本文参考:
字符编码笔记:ASCII,Unicode 和 UTF-8
这个问题的来源于最近 Python
语言的学习中。在 Python3 中,使用 Unicode
对字符串进行编码,这使 Python3
成为一个多语言的语言。同样的,在 Python 中,支持 ord(), chr()
这样的函数对字符串和字符串的 ASCII
十进制值。
在实际的运用过程中,PHP
也包含类似的函数,但是对相同的中文字符,两个函数输出的结果却不同,于是有了对 Unicode
和 UTF-8
的疑问和探索
字符编码的由来
在计算机内部只能识别 二进制
的数据,为了让每个英文单词在计算机内部能够被表示出来,美国制定了一套字符编码,表示 英文字符与二进制位
之间的关系,也就是说,每一个 英文字符
都对应了一个 二进制的编码
,这相当于有一个 集合
而制定这个 “表”
必须要有一定的规则,所以美国制定了 ASCII 码
,规定用 一个字节(8bit)
来表示 128
个英文字符。比如 A
就是 65,二进制为 0100 0001
。这 128 个字符只能占 7 个位,最前面的一个位默认都为 0
ASCII 码的扩展
128 个字符对于英文编码来说够用了,但是对于世界上其他国家的很多语言来说是远远不够的。在计算机慢慢普及的过程中,欧洲一些国家渐渐的字符渐渐被编入 ASCII 码中,利用原 ASCII 编码的最高位,越来越多的国家渐渐扩展出了自己的编码,这样就带来了新的问题
当 256 个字符被占完,也就是 8 个 bit 位被用完的时候,相同的十进制编码在不同的国家中可能会存在冲突,被编码成不同的字符。对于亚洲国家来说,256 个字符就更不够用了
Unicode 产生
随着编码方式越来越多,同一个十进制或二进制会被编译成不同的符号。为了解决这个问题,人们意识到,要用一个新的编码,将世界上所有的字符全部编入其中
,这样,全世界统一使用这个编码,就不会产生冲突和乱码了
这个 集合
就是 Unicode
,它将世界上所有的字符都拿出其中并给出对应的二进制,十进制,十六进制值
注意,Unicode, ASCII
都只是一种编码标准,它规定的是 某某字符应该是用 XXX 值表示
这种标准,而没有指定一种具体的行为去实现从 某某字符转换到二进制编码
这样一种过程
比如,A 用两个字节来存储 Unicode 编码的二进制表示,B 用三个字节来存储 Unicode 编码的二进制表示,在计算机中,就需要去根据不同的 规则
来对内容进行翻译和解释
UTF-8
随着互联网的兴起,计算机与网络,计算机与计算机之间的通讯急需一种统一的 编码方式
来编译和解释 Unicode
编码
这种 编码方式
就是我们现在使用最广泛的 UTF-8
,
所以,UTF-8 是 Unicode 编码的一种具体实现,它规定了字符转换到二进制编码的一系列规则
UTF-8 最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度
UTF-8 的编码规则有两个:
-
对于单字节的符号,字节的第一位设为 0,后面 7 位为这个符号的 Unicode 码
-
对于 n 字节的符号(n > 1),第一个字节的前 n 位都设为1,第 n + 1 位设为 0,后面字节的前两位一律设为 10。剩下的没有提及的二进制位,全部为这个符号的 Unicode 码
PHP 中的 ord() 和 Python 中的 ord() 区别
php 中的 ord 函数,转换字符串第一个字节为 0-255 之间的值
,也就是说,php 的 ord 函数在作用于中文字符串的时候,并不会把所有的字符串都转化为十进制的 ASCII
值,只会转换第一个字节的字符为 ASCII
python 中的 ord 函数,给定一个 Unicode 编码的字符串,返回一个十进制整数
,所以 python 中的 ord 函数如果处理的字符串是 Unicode 编码的,那么将返回完整的十进制数