简单谈谈php中的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);

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

(0)

相关推荐

  • php实现utf-8转unicode函数分享

    代码很简单,功能却很实用,推荐给大家. 奉上代码先: 复制代码 代码如下: public function utf8_unicode($str) {     $unicode = array();     $values = array();     $lookingFor = 1;     for ($i = 0; $i < strlen( $str ); $i++ ) {         $thisValue = ord( $str[ $i ] );         if ( $thisVa

  • php utf-8转unicode的函数第1/2页

    UTF编码 UTF-8就是以8位为单元对UCS进行编码.从UCS-2到UTF-8的编码方式如下: UCS-2编码(16进制) UTF-8 字节流(二进制) 0000 - 007F 0xxxxxxx 0080 - 07FF 110xxxxx 10xxxxxx 0800 - FFFF 1110xxxx 10xxxxxx 10xxxxxx 例如"汉"字的Unicode编码是6C49.6C49在0800-FFFF之间,所以肯定要用3字节模板了:1110xxxx 10xxxxxx 10xxxxx

  • 浅析PHP中的UNICODE 编码与解码

    方法一: 复制代码 代码如下: <?phpfunction unicode_encode($name){    $name = iconv('UTF-8', 'UCS-2', $name);    $len = strlen($name);    $str = '';    for ($i = 0; $i < $len - 1; $i = $i + 2)    {        $c = $name[$i];        $c2 = $name[$i + 1];        if (ord

  • 用php实现gb2312和unicode间的编码转换

    gb2312 和 unicode 间的编码转换 下面的例子是将 gb2312 转换为 "全"这种形式 php4.3.1以后的iconv函数很好用的,只是需要自己写一个uft8到unicode的转换函数 查表(gb2312.txt)也行 复制代码 代码如下: <? $text = "我们"; preg_match_all("/[\x80-\xff]?./",$text,$ar); foreach($ar[0] as $v) echo &quo

  • PHP解密Unicode及Escape加密字符串

    本文给大家分享一个PHP解密Unicode及Escape加密字符串函数 <?php function uni_decode($s) { preg_match_all('/\&\#([0-9]{2,5})\;/', $s, $html_uni); preg_match_all('/[\\\%]u([0-9a-f]{4})/ie', $s, $js_uni); $source = array_merge($html_uni[0], $js_uni[0]); $js = array(); for(

  • PHP实现Unicode编码相互转换的方法示例

    本文实例讲述了PHP实现Unicode编码相互转换的方法.分享给大家供大家参考,具体如下: <?php /** * $str 原始中文字符串 * $encoding 原始字符串的编码,默认utf-8 * $prefix 编码后的前缀,默认"&#" * $postfix 编码后的后缀,默认";" */ function unicode_encode($str, $encoding = 'utf-8', $prefix = '&#', $postf

  • PHP如何实现Unicode和Utf-8编码相互转换

    最近恰好要用到unicode编码的转换,就去查了一下php的库函数,居然没找到一个函数可以对字符串进行Unicode的编码和解码!也罢,找不到的话就自己实现一下了... Unicode和Utf-8编码的区别 Unicode是一个字符集,而UTF-8是Unicode的其中一种,Unicode是定长的都为双字节,而UTF-8是可变的,对于汉字来说Unicode占有的字节比UTF-8占用的字节少1个字节.Unicode为双字节,而UTF-8中汉字占三个字节. UTF-8编码字符理论上可以最多到6个字节

  • PHP解码unicode编码的中文字符代码分享

    问题背景: 晚上在抓取某网站数据,结果在数据包中发现了这么一串编码的数据:"......\u65b0\u6d6a\u5fae\u535a......", 这其实是中文被unicode编码后了的数据,我现在就是想解码出中文来,上度娘搞了半天,试了很多的姿(方)势(法),终于搞定了. 解决方案: 呵呵,老外就是给力啊, 猛戳这里看老外给的解决方案 方案A(稳定版+推荐): function replace_unicode_escape_sequence($match) { return m

  • php制作unicode解码工具(unicode编码转换器)代码分享

    复制代码 代码如下: <?phpfunction unicode_encode($name){    $name = iconv('UTF-8', 'UCS-2', $name);    $len = strlen($name);    $str = '';    for ($i = 0; $i < $len - 1; $i = $i + 2)    {        $c = $name[$i];        $c2 = $name[$i + 1];        if (ord($c)

  • php UTF-8、Unicode和BOM问题

    一.介绍 UTF-8 是一种在web应用中经常使用的一种 Unicode 字符的编码方式,使用 UTF-8 的好处在于它是一种变长的编码方式,对于 ANSII 码编码长度为1个字节,这样的话在传输大量 ASCII 字符集的网页时,可以大量节约网络带宽. UTF-8签名(UTF-8 signature)也叫做BOM(Byte Order Mark),是UTF编码方案里用于标识编码的标准标记.BOM,是UTF编码方案里用于标识编码的标准标记,在UTF-16里本来是FF FE,变成UTF-8就成了EF

  • PHP中正则表达式对UNICODE字符码的匹配方法

    网友ainiaa的问题是 PHP代码如下 复制代码 代码如下: $words = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSRUVWXYZ!@#$%^&*()_+-=[]\\,./{}|<>?'\"你好啊我们"; $otherStr=preg_replace("/[chr(128)-chr(256)]+/is"," ",$words); echo

随机推荐