1. 编码与字体
对于同一个字符,在文件中保存的是他的编码值,这些文字什么形态,是由字符文件决定的。编码值和字体是两个不一样的东西,例如B的编码值是0x42,但是在屏幕上显示出来时,可以有不同形状,如繁体字与简体中文的区别。
什么叫编码?就是一个字符用什么数字来表示。在计算机里一切都是用数字来表示,比如字符 A,用 0x41表示,当我们打开文件,发现里面含有数值0x41,你就知道了这是一个字符A。
一个字符用哪个数值来表示,有很多标准,常用的有三个ASCII、ANSI、UNICODE。
A. ASCII(American Standard Code for Information Interchange)
ASCII是由西方发明的,表示常用字符,字母区分大小写,加上标点符号不超过127个,每个字符用一个字节表示足够了。一个字节的7位就可以表示128个字符,所以在ASCII码中最高位永远是0。具体字符与数值的对应关系可以参考ASCII_百度百科。
B. ANSI
ASNI 是 ASCII 的扩展,向下包含 ASCII。对于 ASCII 字符仍以一个字节来表示,对于非 ASCII 字符则使用 2 字节来表示。并没有固定的 ASNI 编码,它跟“本地化”(locale)密切相关。比如在中国大陆地区, ANSI 的默认编码是 GB2312;在港澳台地区默认编码是 BIG5。对于不同国家,它们默认的ANSI 编码各不相同,所以同一个 TXT 文件在不同国家就很有可能出现乱码。根本的原理在于没有“统一的编码”,那解决方法自然就是使用“统一的编码”: UNICODE。
C. UNICODE
对于英文来讲,ASCII码就足以编码所有字符,但对于中文,则必须使用两个字节来代表一个汉字,这种表示汉字的方式习惯上称为双字节。虽然双字节可以解决中英文字符混合使用的情况,但对于不同字符系统而言,就要经过字符码转换,非常麻烦,如中英、中日、日韩混合的情况。为解决这一问题,很多公司联合起来制定了一套可以适用于全世界所有国家的字符码,不管是东方文字还是西方文字,一律用两个字节来表示,这就是UNICODE。
2 . UNICODE 编码实现
编码实现就是如何将字符准确表示出来,比如“中”在UNICODE中对应的是0x4e2d,如果直接使用0x4e2d是不行的,但是如果使用两字节”0x4e 0x2d“表示又对应上了ASCII中的字符“-N”。所以,用数值表示字符需要定一套技巧。
在ASCII和ANSI编码中,表示字符非常简单,ASCII中使用一个字节来表示一个字符;ANSI中对于ASCII中存在的仍然使用一个字节表示,非ASCII字符的使用两个字节表示。对于UNICODE的表示就有点复杂了,如果与ASCII和ANSI一样直接表示,这样会太浪费了。UNICODE 编码的实现主要有三种形式,分别是 UTF-8、UTF-16 和 UTF-32。这三种编码方式各有特点,适用于不同的场景。
(1)UTF-16
适用场景:在一些操作系统和编程语言中广泛使用,如Java和Windows系统中的内部字符串处理。
UTF-16又分为两种,一种是UTF-16 LE,另一种是UTF-16 BE。对于BMP(基本多文种平面)内的字符,他们都用两个字符表示,但是又存在不同。
a. UTF-16 LE
UTF-16 LE又称UCS-2 Little endian,Little endian 表示小字节序,数值中权重低的字节放在前面,比如字符“K 华”在 TXT 文件中的数值如下,其中的“ K”使用“0x4B 0x00”两字节表示;“华”使用“0x4e 0x53”两字节表示。文件开头的“ 0xff 0xfe”表示“UTF-16 LE”。
b. UTF-16 BE
UTF-16 BE又称UCS-2 Big endian,Big endian 表示大字节序,数值中权重低的字节放在后面,比如字符“ K华”在 TXT 文件中的数值如下,其中的“ K”使用“ 0x00 0x4b”两字节表示;“华”使用“ 0x53 0x4e”两字节表示。文件开头的“ 0xfe 0xff”表示“UTF-16 BE”,此处小编不知道怎么使用Ultra Edit打开带BOM的UTF-16 BE,所以图片没有显示“ 0xfe 0xff”,有知道方法的评论区指导一下。
(2)UTF-8
适用场景:因其高效性和广泛的兼容性,UTF-8 成为了互联网上最常用的文本编码方式。
UTF-16 LE/UTF-16 BE缺点:
- 表示的字符数量有限
- 对于 ASCII 字符有空间浪费
- 如果文件中有某个字节丢失,这会使得后面所有字符都因为错位而无法显示
使用 UTF8 可以解决上述所有问题。 UTF8 是变长的编码方法,有 2 种 UTF8格式的文件:带有头部、不带头部。带头部的会多出三个字节“0xef 0xbb 0xbf”。小编展示的是不带头部的。
对于其中的 ASCII 字符,在 UTF8 文件中直接用其 ASCII 码来表示,比如上图中的“ 0x4b”表示字符“K”。上图中的 3 个字节“ 0xe5 0x8D 0x8E”表示的数值是0x53 0x4e,对应“中”的UNICODE 码。
上图中, 0xe5 的二进制是“ 11100101”,高位有 3 个 1,表示从当前字节起有 3 字节参与表示 UNICODE;
0x8d 的二进制是“101001101”,高位有 1 个 1,表示从当前字节起有 1 字节参与表示 UNICODE;
0x8e 的二进制是“10001110”,高位有 1 个 1,表示从当前字节起有 1 字节参与表示 UNICODE;
除去高位的“ 1110”、“ 10”、“ 10”后,剩下的二进制数组合起来得到“0101 0011 0100 1110”,它就是 0x53 0x4e,即“华”的 UNICODE 值。
使用 UTF8 编码时,即使 TXT 文件中丢失了某些数据,也只会影响到当前字符的显示,后面的字符不受影响。
(3)UTF-32
适用场景:主要用于内存中的字符串处理,尤其是在需要快速访问单个字符的场合。
每个字符固定使用4个字节来表示。虽然简单直接,但由于每个字符占用的空间较大,因此在存储效率上不如UTF-8和UTF-16。
标签:文字,字符,UTF,字节,16,表示,编码方式,ASCII From: https://blog.csdn.net/2203_75769742/article/details/142411635