Lua与json字符串转换之UTF8

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
10 XX 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




  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值