参考 廖雪峰-字符串和编码
https://blog.csdn.net/weixin_41789688/article/details/116787795
首先计算机内部只能识别数字,在底层就是0,1编码。比如:不论是数字100,还是字符 今天,在底层都是1010 1000 1010 这种形式的二进制代码
二进制:
二进制只有0,1两种状态,所以只需要一个二进制位(也就是一个比特位)就可以表示二进制数。
八进制:
八进制有八种状态:0,1,2,3,4,5,6,7
八种状态需要三个比特位才能表示 000–111
所以一个八进制数占了三个比特,比如 7 表示出来就是三个比特位111才能表示
十六进制:
十六进制有16种状态: 0-9,A-F
十六中状态可以用四个比特位表示 0000-1111。
所以一个十六进制数,对应着4个比特位。
假设汉字一共只有16种,我们让每一个汉字对应着一个数字(0-15),用十六进制表示就是
这些十六进制数,在计算机内可以用比特位来表示出来,所以这样中文的文本就可以在计算机中表示了。
所以 天气真好 在计算机中就表示成了 1111 1010 0100 0010
基于这种想法,由于计算机是美国人发明的,所以他们也想让计算机可以表示出他们的语言。对于英语来说,26个大写字母,26个小写字母,10个数字,加上其他的一些符号,他们一共就127个字符,所以他们建立了一个对应关系:
这就是ascii码表,一共128个字符,使用一个字节(xxxx xxxx)就可以完全表示这些字符。一个字节能表示的最大的整数就是255(二进制11111111=十进制255),就是255种状态,表示128种状态肯定是够了。
汉语中有那么多个汉字,算上各种繁体字,大概几万个吧,这些字符仅仅使用一个字节是不够的。比如两个字节可以表示的最大整数是65535。
但是现在这么多国家都在使用计算机,不同国家字符不同,所以不同的国家又自己制定了自己需要的一张表。
假如说现在用两个字节(最大整数65535)来表示这些字符。除去一些通用的字符(数字,符号之类的),然后不同的国家需要不同的字符对应关系,比如:
在汉语中, 21234 —> 编
日语中,21234 —> xx(反正是其他的字符)
那么同样的一段编码,在不同的计算机中,解码出的语言就完全不一样了,这样肯定是不行的。
因此,Unicode字符集应运而生。Unicode把所有语言都统一到一套编码里,这样就不会再有乱码问题了。
可以简单理解为Unicode字符集是一个非常大的表,包括了全世界的字符,它给出了一个统一的规定,比如,哪个字符用哪个数表示,全球统一,这样就不存在乱码了。
Unicode为世界上所有字符都分配了一个唯一的数字编号,这个编号范围从 0x000000 到 0x10FFFF(十六进制),有110多万,每个字符都有一个唯一的Unicode编号,这个编号一般写成16进制,在前面加上U+。例如:“马”的Unicode是U+9A6C。
它是一种规定,Unicode本身只规定了每个字符的数字编号是多少,并没有规定这个编号如何存储。
既然是十六进制,编号范围从 0x000000 到 0x10FFFF(十六进制),那么直接用这些编号对应的二进制存储也是可以的。
但是问题就是,这里有6个十六进制位,也就是24个比特位(3个字节),编码方式是比较简单,但是浪费空间啊,比如有个字符:
实际上a对应的十六进制0x000061对应的二进制完全不需要那么多位来表示
110 0001 就可以表示了,前面那么多字节就浪费了。
然后就有了变长编码:
针对不同范围的码点, 使用不同长度的字节序列来表示 utf-8就是一种变长编码。
UTF-8使用1~4字节为每个字符编码:
- 一个US-ASCIl字符只需1字节编码(Unicode范围由U+0000~U+007F)。
- 带有变音符号的拉丁文、希腊文、西里尔字母、亚美尼亚语、希伯来文、阿拉伯文、叙利亚文等字母则需要2字节编码(Unicode范围由U+0080~U+07FF)。
- 其他语言的字符(包括中日韩文字、东南亚文字、中东文字等)包含了大部分常用字,使用3字节编码。
- 其他极少使用的语言字符使用4字节编码。
还有很多细节没有看,先简单了解一下。
Unicode字符集可以简写为UCS(Unicode Character Set)。就是一个字符集,一个大表格,有一个对应关系。
UTF是“UCS Transformation Format”的缩写,可以翻译成Unicode字符集转换格式,即怎样将Unicode定义的数字转换成程序数据。就是怎么把这些字符对应的十六进制编码,按照哪种格式编码。



