您的位置:首页 > 编程语言 > Lua

Lua与json字符串转换之UTF8

2015-01-22 14:56 281 查看
UTF8编码是一种针对Unicode的可变长度编码,用在网页上可以同一页面显示中文简体繁体以及其他语言(日韩文等)的字形,又称万国码,其编码字节数为1~6个。详情可以参见百度百科

在Lua中读取json字符串时遇到这种字符串需要按照UTF8的规则对其进行转码,将\uXXXX格式的字符转换成相应的字形,其转换规则介绍如下:

1.先将编码中的数据转换为整数,并判断此编码是属于UTF8中的几个字节编码,判断规则如下:

Unicode/UCS-4
bit数 UTF-8
byte数 备注
0000 ~007F
0~7 0XXX XXXX
1
  
0080 ~07FF
8~11 110X XXXX
2
10XX XXXX

0800 ~FFFF
12~16 1110XXXX
3
基本定义范围:0~FFFF
10XX XXXX
10XX XXXX

1 0000 ~1F FFFF
17~21 1111 0XXX
4
Unicode6.1定义范围:0~10 FFFF
10XX XXXX
10XX XXXX
10XX XXXX

20 0000 ~3FF FFFF
22~26 1111 10XX
5
10XX XXXX
10XX XXXX
10XX XXXX
10XX XXXX

400 0000 ~7FFF FFFF
27~31 1111 110X
6
10XX XXXX
10XX XXXX
10XX XXXX
10XX XXXX
10XX XXXX
2.根据整数的值判断落在哪个区间,根据这个区间决定此字形的字节数,并按照规则进行转换:
1).对0x40进行求余,得到的结果加上0x80作为最后一个字节的ascii码,按照string.char(res)转换为字符
2).将值除以0x40取整,得到的值作为新值重复上述过程
3).最后一个值添加上相应的字符头,如六个字节的加上0xfc,五个字节的就加上0xf8,之后按照string.char(res)转换为字符,将这些字符按照先低后高的顺序连接起来就得到了结果,代码如下
function num2char(num,k)                                   -- convert the unicode number into character
local char = string.char
local c,r = ''
for i = 1,k do
r,num = num%0x40, math.floor((num/0x40))
c=table.concat({char(r+0x80),c})
end
return c,num
end

function toUTF8(s)                                         -- convert the json string unicode into character
local char = string.char
local n,c=tonumber(s)
if n<0x80 then                     --1 byte
return char(n)
elseif n<0x800 then                 --2 byte
c,n = num2char(n,1)
return table.concat({char(n+0xc0) , c})
elseif n<0x10000 then               --3 byte
c,n = num2char(n,2)
return table.concat({char(n+0xe0),c})
elseif n<0x200000 then              --4 byte
c,n = num2char(n,3)
return table.concat({char(n+0xf0) , c})
elseif n<0x4000000 then             --5 byte
c,n = num2char(n,4)
return table.concat({char(n+0xf8) , c})
else                                --6 byte
c,n = num2char(n,5)
return table.concat({char(n+0xfc) , c})
end
end


同样,将字形转换为json的\u字符串则是一个反过程,代码如下:
function toUnicode(c,k)                                    -- convert character into unicode code(number)
local byte = string.byte
local n,tmp = 0
if 1 == k then
n = byte(c)
elseif 2 == k then
n = byte(c,1) - 0xc0
for i=2,k do
tmp =byte(c,i) - 0x80
n = n*0x40+tmp
end
elseif 3 == k then
n = byte(c,1) - 0xe0
for i=2,k do
tmp =byte(c,i) - 0x80
n = n*0x40+tmp
end
elseif 4 == k then
n = byte(c,1) - 0xf0
for i=2,k do
tmp =byte(c,i) - 0x80
n = n*0x40+tmp
end
elseif 5 == k then
n = byte(c,1) - 0xf8
for i=2,k do
tmp =byte(c,i) - 0x80
n = n*0x40+tmp
end
elseif 6 == k then
n = byte(c,1) - 0xfc
for i=2,k do
tmp =byte(c,i) - 0x80
n = n*0x40+tmp
end
end
return n
end

function jstr(a)
return string.format("\\u%04x",a)
end
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: