重新认识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)所有,未经作者本人同意禁止任何形式的转载,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。

最新文章

  1. 关于history.js的使用
  2. selenium 3 对我们的影响
  3. adb error: device not found
  4. Unity的物理材质
  5. C#学习笔记(第1周作业)
  6. ansible安装(批量执行命令
  7. JavaScript要点 (六) 函数参数
  8. java新手笔记24 Math/String对象
  9. php 这门语言
  10. iOS 自动布局过程
  11. 解决vue路径中#号
  12. sp_getAppLock使用
  13. 列表&amp;元组的内置方法
  14. java.util.ConcurrentModificationException异常的解决
  15. BZOJ2877 NOI2012魔幻棋盘(二维线段树)
  16. C#通过用户名与密码访问共享目录
  17. istream不是std的成员
  18. nginx try_files 详解
  19. BugPhobia进阶篇章:前端技术/设计文档
  20. 对请求并发数做限制的通用RequestDecorator

热门文章

  1. HTTP04--CDN知识
  2. Hibernate hbm2ddl.auto DDL语句 控制台输出的配置
  3. PHP核心编程知识点
  4. 2016年1月25日 《1024伐木累》-小白篇之开发网站,三天!(中篇-2奇怪的IE)-总章节十一
  5. Bootstrap系列 -- 2. 标题
  6. vNext之旅(1):从概念和基础开始
  7. C 语言学习的第 05 课:了解课程配套的平台
  8. JS模块规范 前端模块管理器
  9. 【CodeVS 2822】爱在心中
  10. JS简单加密