UTF-8编码问题编码长度问题 博客分类: PHP phputf8
程序员文章站
2024-02-17 08:31:58
...
UTF-8编码问题编码长度问题
UTF-8经常被用于文本文件和网络传输,因为不少这类场合还停留在ANSI时代,需要向纯ASCII兼容。UTF-8是UNICODE的一种变长字符编码 ,长度在1至6字节。这里注意一下,UTF-8曾经是6字节,现在是4字节, 两者都对。 但如果你看到介绍UTF-8的文章说是6字节,基本可以判断这是比较早的文章。在 内容只是ASCII的0X00~0X7F时,UTF-8与ASCII或各种ANSI编码(如GB,JISKSC,ISO-8859-1)的ASCII部分 完全兼容,也是用1字节的低7位表示。这就保证文本编辑器打开的UTF-8格式文档中,即使扩展字符无法显示,但ASCII部分肯定得以顺利解读。这点对 于还需要假定是各种ANSI编码的场合非常有用,比如HTML,前面的纯ASCII部分一直到META标记,然后可以确定随后的编码,而此时UTF-16 则不能正常工作。UTF-8采用如下所示的二进制方式来表示31位UCS-4,X表示有效位:
1字节 0XXXXXXX
2字节 110XXXXX 10XXXXXX
3字节 1110XXXX 10XXXXXX 10XXXXXX
4字节 11110XXX 10XXXXXX 10XXXXXX 10XXXXXX
5字节 111110XX 10XXXXXX 10XXXXXX 10XXXXXX 10XXXXXX
6字节 1111110X 10XXXXXX 10XXXXXX 10XXXXXX 10XXXXXX 10XXXXXX
从上可以看得出,如果处在第一字节的引导字节最高位为0,则是一字节。否则看前导1的个数,来确定是几个字节长。前导1与有效位之间有0相隔,也可以通过首字节的值范围来确定字节数。
1字节 0 ~127
2字节 192~223
3字节 224~239
4字节 240~247
5字节 248~251
6字节 252~253
随后的字节每个都以10为前导位,取值范围则在128~191之间。可以立即得知一个字节是否为后续字节,因为引导字节的引导位不是00、01就是11,不会是10。
截取8个字符:
字符串:stefan²º¹³
字节数:14
字符数:10
01110011
01110100
01100101
01100110
01100001
01101110
11000010
10110010
11000010
10111010
11000010
10111001
11000010
10110011
错误的:
字符串:stefan�0
字节数:10
字符数:8
01110011
01110100
01100101
01100110
01100001
01101110
11101111
10111111
10111101
00110000
正确的:
字符串:stefan²º
字节数:10
字符数:8
01110011
01110100
01100101
01100110
01100001
01101110
11000010
10110010
11000010
10111010
涉及到相关代码:
UTF-8经常被用于文本文件和网络传输,因为不少这类场合还停留在ANSI时代,需要向纯ASCII兼容。UTF-8是UNICODE的一种变长字符编码 ,长度在1至6字节。这里注意一下,UTF-8曾经是6字节,现在是4字节, 两者都对。 但如果你看到介绍UTF-8的文章说是6字节,基本可以判断这是比较早的文章。在 内容只是ASCII的0X00~0X7F时,UTF-8与ASCII或各种ANSI编码(如GB,JISKSC,ISO-8859-1)的ASCII部分 完全兼容,也是用1字节的低7位表示。这就保证文本编辑器打开的UTF-8格式文档中,即使扩展字符无法显示,但ASCII部分肯定得以顺利解读。这点对 于还需要假定是各种ANSI编码的场合非常有用,比如HTML,前面的纯ASCII部分一直到META标记,然后可以确定随后的编码,而此时UTF-16 则不能正常工作。UTF-8采用如下所示的二进制方式来表示31位UCS-4,X表示有效位:
1字节 0XXXXXXX
2字节 110XXXXX 10XXXXXX
3字节 1110XXXX 10XXXXXX 10XXXXXX
4字节 11110XXX 10XXXXXX 10XXXXXX 10XXXXXX
5字节 111110XX 10XXXXXX 10XXXXXX 10XXXXXX 10XXXXXX
6字节 1111110X 10XXXXXX 10XXXXXX 10XXXXXX 10XXXXXX 10XXXXXX
从上可以看得出,如果处在第一字节的引导字节最高位为0,则是一字节。否则看前导1的个数,来确定是几个字节长。前导1与有效位之间有0相隔,也可以通过首字节的值范围来确定字节数。
1字节 0 ~127
2字节 192~223
3字节 224~239
4字节 240~247
5字节 248~251
6字节 252~253
随后的字节每个都以10为前导位,取值范围则在128~191之间。可以立即得知一个字节是否为后续字节,因为引导字节的引导位不是00、01就是11,不会是10。
截取8个字符:
字符串:stefan²º¹³
字节数:14
字符数:10
01110011
01110100
01100101
01100110
01100001
01101110
11000010
10110010
11000010
10111010
11000010
10111001
11000010
10110011
错误的:
字符串:stefan�0
字节数:10
字符数:8
01110011
01110100
01100101
01100110
01100001
01101110
11101111
10111111
10111101
00110000
正确的:
字符串:stefan²º
字节数:10
字符数:8
01110011
01110100
01100101
01100110
01100001
01101110
11000010
10110010
11000010
10111010
涉及到相关代码:
mb_internal_encoding("UTF-8"); $t = "stefan²º¹³"; $t = "绝望的奥特曼绝望的奥特曼"; //$t = "stefan�0"; //$t = mb_substr($t, 0, 8); $t = my_substr($t, 2, 8); echo "字符串:" . $t . "\n"; echo "字节数:" . strlen($t) . "\n"; echo "字符数:" . mb_strlen($t) . "\n"; $len = strlen($t); for($i=0;$i<$len;$i++) { $bin = decbin(ord($t[$i])); for($j=8;$j>strlen($bin);$j--) { echo '0'; } echo $bin . "\n"; } //自定义utf8截取函数 function my_substr($str, $start, $len) { $cur_len = 0; $sub_len = 0; $new_str = ''; $str_len = strlen($str); for($i=0;$i<$str_len;) { $dec = ord($str[$i]); $byte_len = 1; if($dec<=127) { $byte_len = 1; } else if($dec>=192 && $dec<=223) { $byte_len = 2; } else if($dec>=224 && $dec<=239) { $byte_len = 3; } else if($dec>=240 && $dec<=247) { $byte_len = 4; } else if($dec>=248 && $dec<=251) { $byte_len = 5; } else if($dec>=252 && $dec<=253) { $byte_len = 6; } else { // 异常 $i++; continue; } for($j=$byte_len;$j>0;$j--) { if($cur_len>=$start) { $new_str .= $str[$i]; } $i++; } if($cur_len>=$start) { $sub_len++; } $cur_len++; if($sub_len>=$len) { break; } } return $new_str; }
推荐阅读
-
UTF-8编码问题编码长度问题 博客分类: PHP phputf8
-
十步解决PHP使用UTF-8编码问题
-
PHP iconv 解决utf-8和gb2312编码转换问题
-
Get和Post的编码问题 博客分类: Java系统 Java 编码
-
Get和Post的编码问题 博客分类: Java系统 Java 编码
-
源文件与操作系统文件编码冲突导致中文乱码问题 博客分类: 工作 LinuxXMLXPAjaxWindows
-
源文件与操作系统文件编码冲突导致中文乱码问题 博客分类: 工作 LinuxXMLXPAjaxWindows
-
PHP utf-8编码问题,utf8编码,数据库乱码,页面显示输出乱码_PHP教程
-
php页面,mysql数据库转utf-8乱码,utf-8编码问题总结,mysqlutf-8_PHP教程
-
解决PHP生成UTF-8编码的CSV文件用Excel打开乱码的有关问题