简单谈谈php中的unicode和utf8编码


Posted in PHP onJune 10, 2015

重新认识unicode和utf8编码

直到今天,准确的说是刚才,我才知道UTF-8编码和Unicode编码是不一样的,是有区别的??br /> 他们之间是有一定的联系的,看看他们的区别:
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编码,看看下面几个例子:

简单谈谈php中的unicode和utf8编码

上面图片中的文字编码格式为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);

以上所述就是本文的全部内容了,希望大家能够喜欢。

PHP 相关文章推荐
PHP怎样调用MSSQL的存储过程
Oct 09 PHP
Discuz! Passport 通行证整合
Mar 27 PHP
php抽奖小程序的实现代码
Jun 18 PHP
php事务处理实例详解
Jul 11 PHP
php相对当前文件include其它文件的方法
Mar 13 PHP
php获取json数据所有的节点路径
May 17 PHP
深入解析WordPress中加载模板的get_template_part函数
Jan 11 PHP
PHP页面跳转实现延时跳转的方法
Dec 10 PHP
Yii框架表单提交验证功能分析
Jan 07 PHP
利用Laravel生成Gravatar头像地址的优雅方法
Dec 30 PHP
Laravel框架实现的批量删除功能示例
Jan 16 PHP
php+Ajax处理xml与json格式数据的方法示例
Mar 04 PHP
PHP中生成UUID自定义函数分享
Jun 10 #PHP
php使用for语句输出三角形的方法
Jun 09 #PHP
php生成图片验证码
Jun 09 #PHP
php判断用户是否手机访问代码
Jun 08 #PHP
浅谈PHP中Stream(流)
Jun 08 #PHP
php实现有趣的人品测试程序实例
Jun 08 #PHP
老版本PHP转义Json里的特殊字符的函数
Jun 08 #PHP
You might like
php 智能404跳转代码,适合换域名没改变目录的网站
2010/06/04 PHP
CI使用Tank Auth转移数据库导致密码用户错误的解决办法
2014/06/12 PHP
PHP基于文件存储实现缓存的方法
2015/07/20 PHP
PHP微信模板消息操作示例
2017/06/29 PHP
ThinkPHP5 框架引入 Go AOP,PHP AOP编程项目详解
2020/05/12 PHP
JQuery之拖拽插件实现代码
2011/04/14 Javascript
js 输出内容到新窗口具体实现代码
2013/05/31 Javascript
JS实现浏览器状态栏显示时间的方法
2015/10/27 Javascript
WordPress中利用AJAX异步获取评论用户头像的方法
2016/01/08 Javascript
JQuery导航菜单选择特效
2016/04/11 Javascript
JS动态给对象添加事件的简单方法
2016/07/19 Javascript
video.js使用改变ui过程
2017/03/05 Javascript
详解vue2.0的Element UI的表格table列时间戳格式化
2017/06/13 Javascript
js实现从左向右滑动式轮播图效果
2017/07/07 Javascript
详解Vue+axios+Node+express实现文件上传(用户头像上传)
2018/08/10 Javascript
解决Vue2.0 watch对象属性变化监听不到的问题
2018/09/11 Javascript
vue中如何实现后台管理系统的权限控制的方法示例
2018/09/19 Javascript
javascript实现小型区块链功能
2019/04/03 Javascript
Vue移动端右滑屏幕返回上一页附源码下载
2019/06/26 Javascript
Node绑定全局TraceID的实现方法
2019/11/14 Javascript
[02:12]DOTA2英雄基础教程 变体精灵
2013/12/16 DOTA
[01:35:13]DOTA2-DPC中国联赛 正赛 DLG vs PHOENIX BO3 第一场 1月18日
2021/03/11 DOTA
为Python的Tornado框架配置使用Jinja2模板引擎的方法
2016/06/30 Python
Python运维自动化之nginx配置文件对比操作示例
2018/08/29 Python
Python3 chardet模块查看编码格式的例子
2019/08/14 Python
python不使用for计算两组、多个矩形两两间的iou方式
2020/01/18 Python
Python实现曲线拟合的最小二乘法
2021/02/19 Python
英国浴室洗脸盆购物网站:Click Basin
2018/06/08 全球购物
英国最大的在线蜡烛商店:Candles Direct
2019/03/26 全球购物
投标承诺书怎么写
2014/05/24 职场文书
节水标语大全
2014/06/11 职场文书
2014年人事行政工作总结
2014/12/03 职场文书
介绍信格式
2015/01/30 职场文书
家长意见书
2015/06/04 职场文书
创业计划书之熟食店
2019/10/16 职场文书
浅谈golang package中init方法的多处定义及运行顺序问题
2021/05/06 Golang