2023-04-01 10:00:13 +08:00

168 lines
3.7 KiB
Lua

local utf8togsm = {}
function hasbit(x, p)
return x % (p + p) >= p
end
function bitand(x, y)
local p = 1; local z = 0; local limit = x > y and x or y
while p <= limit do
if hasbit(x, p) and hasbit(y, p) then
z = z + p
end
p = p + p
end
return z
end
function bitor(x, y)
local p = 1; local z = 0; local limit = x > y and x or y
while p <= limit do
if hasbit(x, p) or hasbit(y, p) then
z = z + p
end
p = p + p
end
return z
end
function bitleft(x, y)
return x * 2 ^ y
end
function bitright(x, y)
return math.floor(x / 2 ^ y)
end
function utf8togsm.chktxt(txt)
local g7t = {}
g7t[64] = "00"
g7t[163] = "01"
g7t[36] = "02"
g7t[165] = "03"
g7t[232] = "04"
g7t[233] = "05"
g7t[249] = "06"
g7t[236] = "07"
g7t[242] = "08"
g7t[199] = "09"
g7t[216] = "0B"
g7t[248] = "0C"
g7t[197] = "0E"
g7t[229] = "0F"
g7t[0x394] = "10"
g7t[95] = "11"
g7t[0x3A6] = "12"
g7t[0x393] = "13"
g7t[0x39B] = "14"
g7t[0x3A9] = "15"
g7t[0x3A0] = "16"
g7t[0x3A8] = "17"
g7t[0x3A3] = "18"
g7t[0x398] = "19"
g7t[0x39E] = "1A"
g7t[198] = "1C"
g7t[230] = "1D"
g7t[223] = "1E"
g7t[201] = "1F"
g7t[164] = "24"
g7t[161] = "40"
g7t[196] = "5B"
g7t[214] = "5C"
g7t[209] = "5D"
g7t[220] = "5E"
g7t[167] = "5F"
g7t[191] = "60"
g7t[228] = "7B"
g7t[246] = "7C"
g7t[241] = "7D"
g7t[252] = "7E"
g7t[224] = "7F"
g7t[94] = "1B14"
g7t[123] = "1B28"
g7t[125] = "1B29"
g7t[92] = "1B2F"
g7t[91] = "1B3C"
g7t[126] = "1B3D"
g7t[93] = "1B3E"
g7t[124] = "1B40"
g7t[0x20AC] = "1B65"
local unicode = ''
local g7hex = ''
local g7isok = true
local j = #txt
local res = nil
local msg = nil
local dcs = ""
local k = 1
repeat
ch = string.byte(txt, k, k)
if ch >= 0xF0 then
ch = bitleft(bitand(ch, 7), 18)
ch = bitor(bitleft(bitand(string.byte(txt, k + 1, k + 1), 0x3F), 12), ch)
ch = bitor(bitleft(bitand(string.byte(txt, k + 2, k + 2), 0x3F), 6), ch)
ch = bitor(bitand(string.byte(txt, k + 3, k + 3), 0x3F), ch) - 0x10000
local w1 = bitor(0xD800, bitright(bitand(ch, 0xFFC00), 10))
local w2 = bitor(0xDC00, bitand(ch, 0x3FF))
unicode = unicode .. string.format("%04X", w1) .. string.format("%04X", w2)
g7isok = false
k = k + 3
elseif ch >= 0xE0 then
ch = bitleft(bitand(ch, 0xF), 12)
ch = bitor(bitleft(bitand(string.byte(txt, k + 1, k + 1), 0x3F), 6), ch)
ch = bitor(bitand(string.byte(txt, k + 2, k + 2), 0x3F), ch)
res = g7t[ch]
if res == nil then
g7isok = false
else
g7hex = g7hex .. res
end
unicode = unicode .. string.format("%04X", ch)
k = k + 2
elseif ch >= 0xC0 then
ch = bitleft(bitand(ch, 0x3F), 6)
ch = bitor(bitand(string.byte(txt, k + 1, k + 1), 0x3F), ch)
res = g7t[ch]
if res == nil then
g7isok = false
else
g7hex = g7hex .. res
end
unicode = unicode .. string.format("%04X", ch)
k = k + 1
elseif ch == 0x60 then
unicode = unicode .. '0060'
g7isok = false
elseif ch <= 0x7F then
res = g7t[ch]
if res == nil then
g7hex = g7hex .. string.format("%02X", ch)
else
g7hex = g7hex .. res
end
unicode = unicode .. string.format("%04X", ch)
else
g7hex = g7hex .. '3F'
unicode = unicode .. '003F'
end
k = k + 1
until k > j
if g7isok and #g7hex <= 320 then
dcs = "00"
txt = g7hex
elseif g7isok then
msg = 'Processed text length = ' .. math.floor(#g7hex / 2) .. ' 7-bit characters.\n'
msg = msg .. 'Currently ROOter supports 160 maximum per message.'
elseif #unicode <= 280 then
dcs = "08"
txt = unicode
else
msg = 'Processed text length = ' .. math.floor(#unicode / 4) .. ' 16-bit Unicode characters.\n'
msg = msg .. 'Currently ROOter supports 70 maximum per message.'
end
utf8togsm["msg"] = msg
utf8togsm["dcs"] = dcs
utf8togsm["txt"] = txt
end
return utf8togsm