• 重新认识unicode和utf8编码


    重新认识unicode和utf8编码


    直到今天,准确的说是刚才,我才知道UTF-8编码和Unicode编码是不一样的,是有区别的
    他们之间是有一定的联系的,看看他们的区别:

    UTF-8的长度是不一定的,有可能是1、2、3字节
    Unicode长度一定,2个字节(USC-2)
    UTF-8可以和Unicode互相转换
    

    unicode和utf8的关系


    Unicode(16进制) UTF-8(二进制)
    0000 - 007F 0xxxxxxx
    0080 - 07FF 110xxxxx 10xxxxxx
    0800 - FFFF 1110xxxx 10xxxxxx 10xxxxxx

    上面的表格有2个意思,第一个显而易见就是说Unicode和UTF-8字符范围的对应,还有一个可以看出Unicode怎么和UTF-8互相转换:

    先说UTF-8到Unicode的转换

    UTF-8编码的二进制和上面的3种格式进行匹配,匹配到之后去掉固定位(表格中的非x位置),然后从右到左每8位一组,不够8位左边不领,凑够2个字节16 bits,这16 bits所表示的就是UTF-8对应的Unicode编码,看看下面几个例子:

    上面图片中的文字编码格式为UTF-8,可以用WinHex看到其16进制表示

    字符	=> 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
    
    再看看从Unicode到UTF-8的转换
    5B57
    获取5B57所在的Unicode范围,0800 <= 5B57 <= FFFF,得知5B57的UTF-8有三个字节,形式为1110xxxx 10xxxxxx 10xxxxxx
    获取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);
    

    5/21/2015 8:21:53 PM

    本文版权归作者iforever(luluyrt@163.com)所有,未经作者本人同意禁止任何形式的转载,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    常见算法之17---二叉树相等判断以及二叉树的复制
    常见算法之16---二维数组中查找元素
    常见算法之15---求N!末尾有多少个0
    常见算法之14---球放入盒问题
    常见算法之13---跳台阶问题
    常见算法之12---求a^n%p
    DB与java的关联
    重拾python
    Codeforces Round 212 Div 2 报告(以前没写完,现在也没心情补了,先就这样吧)
    交换Ctrl和Caps Lock键
  • 原文地址:https://www.cnblogs.com/iforever/p/4520692.html
Copyright © 2020-2023  润新知