重新认识unicode和utf8编码
直到今天,准确的说是刚才,我才知道UTF-8编码和Unicode编码是不一样的,是有区别的囧
他们之间是有一定的联系的,看看他们的区别:
UTF-8的长度是不一定的,有可能是1、2、3字节
Unicode长度一定,2个字节(USC-2)
UTF-8可以和Unicode互相转换
代码如下:
字符 => UTF-8 => UTF-8二进制=> 去掉固定位置凑够16位的二进制 => 16进制
汉 => E6B189 => 11100110 10110001 10001001 => 01101100 01001001 => 6C49
字 => E5AD97 => 11100101 10101101 10010111 => 01011011 01010111 => 5B57
#下面是在chrome命令行下面运行的结果
'\u6C49'
"汉"
'\u5B57'
"字"
#到这里的话,从UTF-8转换到Unicode已经是一件非常容易的事了,看看转换的伪代码
读取一个字节,11100110
判断该UTF-8字符的格式,属于第三种,3个字节
继续读取2个字节得到 11100101 10101101 10010111
按照格式去掉固定位 1011011 01010111
不够16位,左边补零 01011011 01010111 => 5B57
代码如下:
5B57
获取5B57所在的Unicode范围,0800
获取5B57的二进制编码 101101101010111
用上一步骤的二进制编码从右至左拼接UTF-8编码 11100101 10101101 10010111
说说问题
再说说今天这个问题的起因,从前端输入很多单词,UTF-8格式每个词最多30个字节,因此会在前端和后台分别做验证,javascript用的是Unicode编码,后端程序用的是UTF-8编码,现在的解决办法是这样
前端
function utf8_bytes(str) { var len = 0, unicode; for(var i = 0; i < str.length; i++) { unicode = str.charCodeAt(i); if(unicode < 0x0080) { ++len; } else if(unicode < 0x0800) { len += 2; } else if(unicode <= 0xFFFF) { len += 3; }else { throw "characters must be USC-2!!" } } return len; } #例子 utf8_bytes('asdasdas') 8 utf8_bytes('yrt燕睿涛') 12
后台
#对于GBK字符串 $len = ceil(strlen(bin2hex(iconv('GBK', 'UTF-8', $word)))/2); #对于UTF8字符串 $len = ceil(strlen(bin2hex($word))/2);
以上所述就是本文的全部内容了,希望大家能够喜欢。