重新认识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)所有,未经作者本人同意禁止任何形式的转载,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
重新认识unicode和utf8编码的更多相关文章
- (转载):ASCII,Unicode和UTF-8 编码
UTF-8是Unicode的一种实现方式,也就是它的字节结构有特殊要求,所以我们说一个汉字的范围是0X4E00到0x9FA5,是指unicode值,至于放在utf-8的编码里去就是由三个字节来组织,所 ...
- ASCLL、Unicode和UTF-8编码的理解
我们已经讲过了,字符串也是一种数据类型,但是,字符串比较特殊的是还有一个编码问题. 因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理.最早的计算机在设计时采用8个比特(bit) ...
- ASCII、Unicode和UTF-8编码的区别
归纳: 编码 大小 支持语言 ASCII 1个字节 英文 Unicode 2个字节(生僻字4个) 所有语言 UTF-8 1-6个字节,英文字母1个字节,汉字3个字节,生僻字4-6个字节 所有语言 具体 ...
- ASCII、Unicode和UTF-8编码的区别;中英文混合截取
ASCII编码是128个字符 中国把汉字编入GB2312,Shift_JIS/Euc-kr各国标准..... Unicode是为了解决各国乱码的,但浪费存储空间 UTF-8编码把一个Unicode字符 ...
- 字符编码的来源,ascii、unicode和utf-8编码的关系
字符编码 我们已经讲过了,字符串也是一种数据类型,但是,字符串比较特殊的是还有一个编码问题. 因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理.最早的计算机在设计时采用8个比特 ...
- Ascii码 unicode码 utf-8编码 gbk编码的区别
ASCII码: 只包含英文,数字,特殊符号的编码,一个字符用8位(bit)1字节(byte)表示 Unicode码: 又称万国码,包含全世界所有的文字,符号,一个字符用32位(bit)4字节(byte ...
- ASCII、Unicode、UTF-8编码关系
由于计算机是美国人发明的,因此,最早只有127个字符被编码到计算机里,也就是大小写英文字母.数字和一些符号,这个编码表被称为ASCII编码,比如大写字母A的编码是65,小写字母z的编码是122.但是要 ...
- ASCII、Unicode、UTF8编码类型的理解
一.ASCII码 在计算机内部,所有的信息最终都表示为一个二进制的字符串.每一个二进制位(bit)有0和1两种状态,因此八个二进制位就可以组合出256种状态,这被称为一个字节(byte) ...
- ANSI、ASCII、Unicode和UTF-8编码
来自:http://blog.163.com/yang_jianli/blog/static/161990006201371451851274/ --------------------------- ...
随机推荐
- Map集合 总结
(本人第一次写博客,部分内容有参照李刚老师的疯狂java系列图书,如有遗漏错误,请多指教,谢谢.) Java的集合类可分为Set.List.Map.Queue,其中Set.List.Queue都有共同 ...
- mac 10.9.4下配置apache
mac 10.9.x已经自带了apache,可按如下步骤开启: 1.启动 sudo apachectl start 启动后,访问 http://localhost/ 应该能看到"It wor ...
- 纯html的table打印注意事项
1. 在firefox下,每页均会打印重复thead(表头),tfoot(表尾)的内容:IE8下无效(其它IE版本未测试) 2. 分页的处理 @media print { .page-brea ...
- 你真的理解 new 了吗?
开篇先提几个问吧,如果你对这些问题都清楚了,那说明对于 new 这个关键字已经掌握得很好了,也不再需要花时间来阅读本文了, 1 new 一个class 与 new 一个Struct有什么 ...
- ffmpeg在shell循环中只执行一次问题
最近写了一个shell脚本,发现 ffmpeg 命令只执行了一次就停了,最后找到原因: ffmpeg有时会读取标准输入流,导致命令出错,解决办法是在ffmpeg命令之后添加 #xxx ffmpeg x ...
- ASP.NET 系列:单元测试之Log4Net
使用Log组件时,我们通常自定义ILogger接口,使用Log4Net等组件进行适配来定义不同的实现类.使用Log4Net日志组件时,为了即方便单元测试又能使用配置文件,我们通过Log4Net的ILo ...
- How to remove a batch of VMs and related Disks
Foreword Need to remove a batch of VMs, which named with same prefix or belong to same Cloud Service ...
- Eclipse自动补全功能管理
#这种方法只适用于Eclipse Classic版本(这个版本带有插件的源码) 在使用Eclispe的过程,感觉自动补全做的不好,没有VS的强大.下面说两个增强自动补全的方法: 1.增加Eclipse ...
- C语言strcat()函数:连接字符串
头文件:#include <string.h> strcat() 函数用来连接字符串,其原型为: char *strcat(char *dest, const char *src); ...
- Go--避免SQL注入
避免SQL注入 什么是SQL注入 SQL注入攻击(SQL Injection),简称注入攻击,是Web开发中最常见的一种安全漏洞.可以用它来从数据库获取敏感信息,或者利用数据库的特性执行添加用户,导出 ...