精简总结字符串编码若干问题
一、编码的产生原因及发展原因
1.最初计算机源于美国,键盘上大家常见的这些字符用一个字节的7个bit来表示就满足了(最高位是符号位不动),这就是ascii码
2.随着计算机的普及发展,各国也需要将自己的文字字符加入进来,发现原有的ascii码已经不够用了,刚开始没想好,觉得用起来一个字节的符号bit位到了2^8的情况,
发现各国交流起来是有问题的,而且还有很多国家字符超级多...........
3.既然一个字节满足不了,我们就多个字节,于是美帝提出用一种标准方案,来展示世界上所有语言中的所有字符,出于这个目的,Unicode诞生了。
二、关于Unicode
1.Unicode 相当于是一本字典,记录着世界上所有字符对应的一个数字。 Unicode 给所有的字符指定了一个数字用来表示该字符。这表大家自行搜索下.
2.Unicode 它的想法很简单,就是为每个字符规定一个用来表示该字符的数字,仅此而已。没有说明这个数字在内存二进制中如何来存储.
这就引申出两个问题:
a.Unicode的编码方案会有多种.
b.数字的二进制在内存中高低端放置问题. BE LE
三、Unicode的各种编码方案的由来及优缺点
UTF-32
为了满足最初最原始的欲望,简单粗暴地将各国的字符放在里面,定长编码,字符统一使用 4 个字节
优点:编码简单快速
缺点:浪费存储空间,不适合网络传输
UTF-16
UTF-32既然太粗暴浪费空间,我们就做一个简单的划分:UTF-16 的编码长度要么是 2 个字节(U+0000 到 U+FFFF),要么是 4 个字节(U+010000 到 U+10FFFF)
具体实现细节,请自行查阅.
优点:一定程度缩减UTF-32的空间占用问题
确定:不利于空间的合理存储
UTF-8
UTF-8 使用变长字节进行字符编码, 使用的字节数可变,这个变化是根据 Unicode 编号的大小有关,使用的字节个数从 1 到 4 个不等。划分方式参考下图
是最流行的编码的方式,原因很简单:在计算机速度突飞猛进的今天,编码解码速度基本上不是问题,所以存储空间是人们更加关心的问题.
UTF-8 的编码规则:
a. ASCII 码中的字符均用一个字节进行表示.
b.n字节的符号(4>=n>2),第一个字节的前 n 位都设为 1,第 n+1 位设为 0,后面字节的前两位一律设为 10,剩下的没有提及的二进制位,全部为这个符号的 Unicode 码 。
举个例子:比如说一个字符的 Unicode 编码是 2049,那么就需要三个字节(n = 3)。
这三个字节的情况如下
第一个字节 | 第二个字节 | 第三个字节 |
1110XXXX | 10XXXXXX | 10XXXXXX |
根据规则,第一个字节的前 3 位都设为 1,第 4 位设为 0,则第一个字节为:110X XXXX,后面两个字节的前两位一律设为 10,格式如:10XX XXXX。
接下来的问题:这些X中需要填写什么东西呢?答案是编码的二进制,即将unicode的二进制从右到左依次放入对应的xxx位置中.
2049的二进制是1000 0000 0001那么填进去,这三个字节的情况就变成了,最后剩余的xxxx用0补上即可
第一个字节 | 第二个字节 | 第三个字节 |
1110XXXX | 10100000 | 10000001 |
四、大端小端
1.概述:为什么会有大端小端的概念
计算机的内存是以字节为单位的,
而CPU的寄存器表示的数据是大于一个字节的,
那么就存在了一个问题,例如0x1234这样的数据如何放到内存中,供CPU寄存器进行读取使用呢?
0x12是高位,0x34是地位,这些数据放在内存的高低,就产生了高低位的说法.
内存地址 | 内存中的数据 |
地址a+1 | 0x34 |
地址a | 0x12 |
(大端存储:高位在低地址内存)
内存地址 | 内存中的数据 |
地址a+1 | 0x12 |
地址a | 0x34 |
(大端存储:高位在高地址内存)
各类CPU厂商大小端方式有差异, 通讯协议是大端的。
2.常见的字节序
常见CPU字节序
Big Endian : PowerPC、IBM、Sun
Little Endian : x86、DEC
ARM既可以工作在大端模式,也可以工作在小端模式。
常见文件字节序
Adobe PS – Big Endian
BMP – Little Endian
DXF(AutoCAD) – Variable
GIF – Little Endian
JPEG – Big Endian
MacPaint – Big Endian
RTF – Little Endian
PS:有人问了解这些有什么用,其实很简单因为你是做IT的,有些东西是基本功,且必知必会.