文字显示 —— 字符编码

文字显示

计算机可以显示不同的字符,字符又可以选择以不同的字体样式显示

image-20240408192028761 image-20240408192038238

字符编码决定决定显示何种字符

字体文件决定字符以何种形态显示

字符编码

ASCII

由于只定义了128个字符,所以用一个字节来表示一个字符(0~127)

ascii字符编码的最高位永远是0

image-20240408192112171

ANSI

话说计算机是由美国佬搞出来的嘛,他们觉得一个字节(可以表示256个编码)表示英语世界里所有的字母、数字和常用特殊符号已经绰绰有余了(其实ASCII只用了前127个编码)。后来欧洲人不干了,法国人说:我需要在小写字母加上变音符号(如:é),德国人说:我也要加几个字母(Ä ä、Ö ö、Ü ü、ß)。于是,欧洲人就将ASCII没用完的编码(128-255)为自己特有的符号编码(后来称之为“扩展字符集”)。等到我们中国人开始使用计算机的时候,尼玛,256个编码哪够?我泱泱大中华,汉字起码也得N多万吧,就连小学生都得要求掌握两三千字。国标局最后拍板:一个字节不够,那我们就用多个字节来为汉字编码吧,但是,国情那么穷,字节那么贵,三个字节伤不起,那就用俩字节吧,先给常用的几千汉字编个码,等以后国家强盛了人民富裕了,咱再扩展呗—于是GB2312就产生了。台湾同胞一看,尼玛,全是简体字,还让不让我们写繁体字的活了,于是台湾同胞也自己弄了个繁体字编码—大五码(Big-5)。同时,其它国家也在为自己的文字编码。最后,微软苦逼了:顾客就是上帝啊,你们的编码我都得满足啊,这样吧,卖给美国国内的系统默认就用ASCII编码吧,卖给中国人的系统默认就用GBK编码吧,卖给韩国人的系统默认就用EUC-KR编码,…但是为了避免你们误会我卖给你们的系统功能有差异,我就统一把你们的默认编码都显示成ANSI吧。—本故事纯属虚构,但“ANSI编码”确实只存在于Windows系统。

ASNI 是 ASCII 的扩展,向下包含 ASCII。**对于 ASCII 字符仍以一个字节来表示,对于非 ASCII 字符则使用 2 字节来表示(并且这两个字节的首位都为1)。**并没有固定的 ASNI 编码,它跟“本地化”(locale)密切相关。比如在中国大陆地区,ANSI 的默认编码是GB2312;在港澳台地区默认编码是 BIG5。以数值“0xd0d6”为例,对于 GB2312 编码它表示“中”;对于 BIG5 编码它表示“笢”。所以对于 ANSI 编码的 TXT 文件,如果你打开它发现乱码,那么还得再次细分它的具体编码。

对于一个txt文件,里面的编码数值如下

image-20240408192836501

选择不同的编码(或者为字符集)显示的字符是不同的

image-20240408193200510

这仅仅是在中国地区就出现这些不兼容的问题。对于不同国家,它们默认的ANSI 编码各不相同,所以同一个 TXT 文件在不同国家就很有可能出现乱码。

根本的原理在于没有“统一的编码”,那解决方法自然就是使用“统一的编码”:UNICODE。

UNICODE

使用unicode编码就是为了解决ansi编码所遗留的问题(相同的编码值在不同的国家或地区显示不同的字符 eg:数值“0xd6d0”,对于GB2312 编码它表示“中”;对于 BIG5 编码它表示“笢”)

unicode编码:对于地球上任意一个字符,都给它一个唯一的数值。

UNICODE 仍然向下兼容 ASCII,但是对于其他字符会有对应的数值,比如对于“中”、“笢”,它们的数值分别是:0x4e2d、0x7b22

UNICODE的编码实现

所谓的编码实现就是对于一个数值,你怎么去表示它

对于 “中” 而言,直接写入编码值0x4e2d吗?不行,因为0x4e、0x2d在ascii编码中代表着别的字符,如何让计算机知道这是一个整体,是需要一定技巧的,也就是编码实现

1

使用3个字节来表示1个unicode

不行,太浪费了

2

使用两个字节来表示1个unicode

UTF-16 LE

Little endian 表示小字节序,数值中权重低的字节放在前面,比如字符“A 中”在 TXT 文件中的数值如下,其中的“A”使用“0x41 0x00”两字节表示;“中”使用“0x2d 0x4e”两字节表示。文件开头的“0xff 0xfe”表示“UTF-16 LE”。

image-20240408195041326
UTF-16 BE

Big endian 表示大字节序,数值中权重低的字节放在后面,比如字符“ab中”在 TXT 文件中的数值如下,其中的“A”使用“0x00 0x41”两字节表示;“中”使用“0x4e 0x2d”两字节表示。文件开头的“0xfe 0xff”表示“UTF-16 BE”。

image-20240408195132906
3
UTF-8

对于 UTF-16 LE、UTF-16 BE 两种编码实现有明显的缺点

  1. 对于ascii编码的字符仍然有浪费空间的情况
  2. 对于 00 41 4e 2d 而言,只要 41 丢失,后面的所有字符编码都会因为错位而出现错误

使用 UTF8 可以解决上述所有问题。UTF8 是变长的编码方法,有 2 种 UTF8格式的文件:带有头部、不带头部。

41 e4 b8 ad 在UTF-8的文件中代表着 “A中”

image-20240408195723924 image-20240408195738094

对于 ASCII 字符,在 UTF8 文件中直接用其 ASCII 码来表示

对于非 ASCII 字符,使用变长的编码:每一个字节的高位都自带长度信息

image-20240408195911521

上图中,0xe4 的二进制是“11100100”,高位有 3 个 1,表示从当前字节起有 3 字节参与表示 UNICODE;
0xb8 的二进制是“10111000”,高位有 1 个 1,表示从当前字节起有 1 字节参与表示 UNICODE;
0xad 的二进制是“10101101”,高位有 1 个 1,表示从当前字节起有 1 字节参与表示 UNICODE;
除去高位的“1110”、“10”、“10”后,剩下的二进制数组合起来得到“01001110001101”,它就是 0x4e2d,即“中”的 UNICODE 值。
使用 UTF8 编码时,即使 TXT 文件中丢失了某些数据,也只会影响到当前字符的显示,后面的字符不受影响。

0001101”,它就是 0x4e2d,即“中”的 UNICODE 值。
使用 UTF8 编码时,即使 TXT 文件中丢失了某些数据,也只会影响到当前字符的显示,后面的字符不受影响。

  • 15
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值