1.字符编码
字符
文字+符号
文字:表意文字、表音文字
符号:标点符号、运算符号、货币符号、数字符号、其他符号(音乐符号、化学符号、表情符号等)
一个汉字、一个英文字母、一个数字、一个emoji表情都是一个字符
字符集
多个字符整合在一起就是字符集
例如:数字字符集:0123456789;大写字母字符集:A-Z;ASCII、GB2312、GBK、GB18030、Unicode字符集
字符编号
按照一定的规则给字符集里面的字符进行编号
编号规则:
一般使用连续的自然数来进行编号,例如:0,1,2,3
特别的编号方式,例如:GB2312的区位码
字符集的字符编号不是必须的,不会影响字符在计算机中的存储格式,例如GBK,GB18030
特点:唯一性
字符编码
让字符能在计算机中存储和识别
假设字符集TEST中有3个字符△、○、●,字符编号是0、1、2,那么字符编码就是
字符 | △○● |
---|---|
字符集 | TEST |
字符编号 | 0 1 2 |
字符编码 | (单字节编码)00000000 00000001 00000010 |
例如:
字符 | 字符集 | 字符编号 | 字符编码 |
---|---|---|---|
A | ASCII | 65 | 01000001 |
2.进制转换
3种进制
十进制
0 1 2 3 4 5 6 7 8 9
逢十进一
直接表示 例如1000
decimal dec
二进制
0 1
逢二进一
0b前缀 例如0b1000
binary bin b
十六进制
0 1 2 3 4 5 6 7 8 9 a b c d e f
逢十六进一
0x前缀 例如0x1000
hexdecimal hex x
进制的转换
十进制转其他进制(以二进制为例)
主要有两种办法
1.除2取余法,倒序排列法 例如 8=0b1000
2.8421法 例如十进制的15=0b1111=8+4+2+1,十进制的9=8+1 =0b1001
其他进制转十进制(以二进制为例)
乘以2的次幂依次相加例如0b1001=1x23+0x22+0x21+1x20=8+0+0+1=9
二进制转十六进制
从后往前 每4位二进制转1位十六进制,例如0b10011000=0x98
为什么可以这样转呢?因为2^4=16,二进制4位等于十六进制的1位
十六进制转二进制
从后往前 每1位十六进制转4位二进制,例如0x98=0b10011000
3.ASCII
Windows的换行符是回车+换行 CR+LF 0x0d 0x0a \r\n
Linux的换行符是LF也就是0x0a \n
Mac的换行符是CR也就是0x0d \n
字符
整合了128个字符
33个控制字符 例如回车符
10个数字字符 0 1 2 3 4 5 6 7 8 9
26个大写字母字符A-Z
26个小写字母字符a-z
33个其他字符 例如运算符号 标点符号
字符集
ASCII American Standard Code for Information Interchange 美国信息交换标准代码
字符编号
0-127给字符编号
例如数字0是48大写A是65小写a是97
字符编码
单字节编码 8位 256个字符
128只需要用到7位
剩下的1位固定0 例如0b01111111
单字节共8位,有价值的共7位,剩下的1位固定为0
问答:
问:1.ASCII中为什么大写字母在前,小写字母在后?
答:因为拉丁字母最开始只有大写字母,后衍生出小写字母(个人所想,帮助记忆)。
问:2.ASCII中有33个控制字符,为什么32个控制字符在前,1个控制字符在最后?
答:
穿孔纸带是早期计算机的储存介质,它将程序和数据转换二进制数码:带孔为1,无孔为0,经过光电输入机将数据输入计算机。
作为计算机周边设备而言,较更早期的穿孔卡有很大进步。被更先进的磁带(1951年起作为计算机存储设备)所替代。
因为纸带已经打孔很难补孔,所以干脆将那7位全部打孔表示删除,故DEL 0b01111111放在最后。
问:3.单字节码8位,第一位是0,如果第一位改1了会怎么样?
答:不是标准ASCII码的正确的字符编码,会显示乱码。
4.GB2312
字符
共7573个字符
1.有128个ASCII字符,例如换行符、回车符、数字0-9、大小写字母。
2.有682个非ASCII非汉字图形字符,例如全角标点符号、全角数字、全角大小写字母、希腊字母、日文平假名和片假字母、俄语的西里尔字母。
3.6763个简体汉字字符,一级汉字3755个,二级汉字3008个。
128+682+6763=7573个字符。
字符集
GB2312字符集。
GB是国标的意思,GuoBiao的缩写,国标是中华人民共和国国家标准的缩写。
2312没有特别含义,国家标准的一个编号。
1980年发布,所以也叫做GB2312-80或GB2312-1980。
字符编号
两种编号方式。
1.128个ASCII码字符的编号方式0~127。
2.区位码的方式:
- 682个非ASCII码非汉字图形字符和6763个汉字字符的编号方式,7445个字符。
- 共94个区 每个区94位
- 94*94 = 8836个字符 1381个空余的区位
- 94个区,从1开始计数,1到94,例如第1区、第2区、第94区
- 94个位,从1开始计算,1到94,例如第1位、第2位、第94位
- 第1~8区,特殊符号,例如全角标点符号、全角数字
- 第9区,造表符号
- 第10~15区,没有编码,空余出来的区位
- 第16~55区,一级汉字,拼音排序,3755个
- 第56~87区,二级汉字,按部首笔画排序,3008个
- 第88~94区,没有编码,空余出来的区位
字符编码
两种编码方式。
1.128个ASCII字符的字符编码,单字节编码,8位,最前面那位固定位0,例如:大写A,编号65,编码0b010001001
2.682个非ASCII非汉字图形字符和6763个汉字字符共7445个字符的字符编码,双字节编码,区号+0xa0,位号+0xa0,区位各占一个字节,共两个字节
汉字字符“啊” | 第16区 | 第1位 |
---|---|---|
区位二进制 | 0b00010000 | 0b00000001 |
0xa0 | 0b10100000 | 0b10100000 |
两个字节 | 0b10110000 | 0b10100001 |
0xb0 | 0xa1 |
汉字字符“周” | 第54区 | 第60位 |
---|---|---|
区位二进制 | 0b00110110 | 0b00111100 |
0xa0 | 0b10100000 | 0b10100000 |
两个字节 | 0b11010110 | 0b11011100 |
0xd6 | 0xdc |
问答
问:1.GB2312兼容ASCII码吗?
答:兼容。128个ASCII字符,单字节编码,最前面那位固定0;非ASCII字符区位+0xa0,两个字节的最前面都是固定为1。
问:为什么使用区位码,这样用有什么好处?
答:隐藏技术细节,例如设计字符的人员,不用考虑字符在计算机中如何存储。
问:不符合编码规则的数据会怎么显示?
答:乱码。
5.GBK
字符
22014个字符。
1.有128个ASCII字符,例如回车符、换行符、数字、大写字母、小写字母
2.有21003个汉字字符,包括简体汉字、繁体汉字、汉字部首、汉字构建,例如简体汉字中的“中”
3.有883个非ASCII非汉字图形符号字符,例如全角标点符号、全角数字、全角大小写字母
字符集
1980年发布GB2312简体汉字字符集,无法处理繁体汉字和罕用字。
1983年12月中国台湾信息产业策进会发布Big5繁体汉字字符集,港澳台地区比较常用。
1995年全国信息技术标准化技术委员会发布GBK。
完全保留GB2312的所有字符字符顺序和字符编码方式。
单字节存128个ASCII字符,其他字符使用双字节存,空余的可编码位置放置Big5的13060个繁体字。
GBK就是利用GB2312空余的编码位,把繁体汉字补充进去,然后再补充其他汉字和其他图形符号。
GB2312的双字节编码是区位号各加0xa0,区位各占一个字节,共两个字节。
0xa0 0b10100000前面还会有很多空余可编码的位置。
94个区中也有没有编码的区,也会有很多空余的可编码的位置。
GBK是GB2312扩展的意思,GB国标GuoBiao K扩展的扩Kuo的缩写。
字符编号
字符编号有两种:
1.128个ASCII码字符的字符编号0~127,例如数字0是48,大写字母A是65,小写字母a是97。
2.21886个非ASCII码字符的字符编号,没有具体的编号规则,例如0x8140 0xa1a1。
字符编码
单字节和双字节两种编码方式。
1.128个ASCII字符的字符编码,单字节编码,8位,最前面那位固定为0,例如大写字母A,编号65=0x41=0b01000001。
2.21003个汉字字符和883个非ASCII非汉字的图形符号字符,共21886个字符,双字节编码,双字节编码范围是0x8140-0xfefe,并且去掉第二个字节的0x7f,第一个字节0x81-0xfe,第二个字节0x40~0xfe,去掉0x7f,共23940个编码位。
问答
问:1.为什么第二个字节要去掉0x7f?
答:各种非ASCII码字符编码,一般都要避开ASCII的33个控制字符0~31和127,控制字符一般会有特殊的控制效果,例如0x7f del 可以把光标后一个字符给删掉,0x08 BS baskspace退格符,光标的前一个字符给删掉。
问:2.为什么去掉了0xff?
答:0xff通常文件开头做一些特殊的文件标记,例如UTF16的大端小端的标记。
问:3.第二个字节会不会和ASCII码单字节混淆?
答:不会,双字节编码的第一个字节来实现不会混淆,第一个字节0x81开始编码0b10000001,最开始那位固定为1。
问:4.不符合GBK编码规则的数据会怎样?
答:会显示为乱码。
6.GB18030
字符
共76556个字符。
1.128个ASCII码字符。
2.70244个汉字字符,GBK是21003个汉字字符,新增的汉字主要是古汉字、生僻字和少数民族文字,例如藏文、维吾尔文、蒙古文。
3.6184个图形字符,GBK是883个图形字符,新增的图形字符主要是少数民族的图形字符。
字符集
GBK它不是强制性国家标准,而是指导性的技术规范。
2000年发布GB18030,也叫做GB18030-2000。
2005年发布GB18030-2005。
GB18030基本兼容GBK,完全兼容GB2312。
GB18030除了有82个字符的Unicode映射关系和GBK不一样外,完全兼容GBK的字符和字符编码。
字符编号
没有明确的编号规则。
字符编码
字符编码方式有三种:
编码方式 | 编码范围 | 可编码位数 | 实际编码字符数 |
---|---|---|---|
单字节 | 0x00~0x7f | 128 | 128 |
双字节 | 第一个字节0x81~0xfe | 23940 | 21897 |
第二个字节0x40~0xfe 去掉0x7f | |||
四字节 | 第一个字节0x81~0xfe | 1587600 | 54531 |
第二个字节0x30~0x39 | |||
第三个字节0x81~0xfe | |||
第四个字节0x30~0x39 |
7.Unicode字符集
字符
共收集143859个字符。
字符集
1988年Apple、Xerox等软件公司组成了一个机构——Unicode联盟,Unicode Consortium容纳全世界所有字符,每个字符分配唯一的编号,字符进行统一的编码。
1991年Unicode1.0双字节给字符编号0x0000~0xffff 6万多个字符。
2001年Unicode3.1四字节给字符编号0x0000~0x10ffff,分为17个平面,每个平面有65536个可编号位。
2022年,Unicode15.0。
字符编号
非常直观,非常简单,连续自然数给字符进行编号。
Unicode一般使用十进制的十六进制来表示一个字符编号,在前面加前缀U,例如:0 U0000,127 U007F,65535 UFFFF。
Unicode1.0双字节给字符编号0x0000~0xffff。
Unicode3.1四字节分为17个平面,每个平面65536个可编号位
- 平面0 0x0000~0xffff共65536个可编号位
- 平面1 0x10000~0x1ffff共65536个可编号位
- 平面2 0x20000~0x2ffff共65536个可编号位
- …
- 平面15 0xf0000~0xfffff共65536个可编号位
- 平面16 0x100000~0x10ffff共65536个可编号位
字符编码
Unicode字符编码有三种:UTF-8、UTF-16和UTF-32
计算机处理整数数据时,通常使用8-bit、16-bit或者32-bit作为代码单元去处理整数数据,代码单元code unit 码元。
计算机处理器一次执行能同时处理8-bit、16-bit、32-bit、64-bit码元的数据。
例如:假设int是四字节整数类型,变量test=0x12345678 内存地址是0x8001 0x8002 0x8003 0x8004
test(0x8001) | 0x12(高位字节) | 34 | 56 | 78(低位字节) |
---|---|---|---|---|
内存地址 | 0x8001(低位地址) | 0x8002 | 0x8003 | 0x8004(高位地址) |
大端字节序bit-endian BE | 0x12 | 34 | 56 | 78 |
小端字节序little-endian LE | 0x78 | 56 | 34 | 12 |
计算机使用32-bit码元去处理test变量的数据。
字节序byte order字节的顺序,内存地址的分配一定是先分配低位地址再分配高位地址,人类书写、阅读字节数据的习惯一定是高位字节在左,低字节在右
- 大端字节序,这种字节序符合人类的思维方式,高位字节存放在内存低位地址,低位字节存放在内存高位地址。
- 小端字节序,这种字节序符合机器的思维方式,低位字节存放在内存低位地址,高位字节存放在内存高位地址。
另外16-bit、32-bit码元的数据才要考虑字节序问题,8-bit码元的数据只有一个字节,没有字节序的问题
UTF-8字节序列 | 有效编码位 | Unicode编号范围 |
---|---|---|
单字节 0xxxxxxx | 7 | 0x00~0x7f |
双字节 110xxxxx 10xxxxxx | 11 | 0x80~0x7ff |
三字节 1110xxxx 10xxxxxx 10xxxxxx | 16 | 0x800~0xffff |
四字节 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx | 21 | 0x10000~0x10ffff |
首字节一定是以0 110 1110 11110开头,后续字节一定是以10开头。
非0开头的首字节有一个特点,多少个1就表示这个字符有多少个字节。
UTF-8编码算法(三步):
- 1.确定Unicode字符编号或者叫码点code point,例如汉字的“汉”,编号是0x6c49。
- 2.根据UTF-8的Unicode码点范围确定UTF-8字节序列,例如“汉”码点是0x6c49,是三字节序列。
- 3.把Unicode字符的编号,转成二进制,将二进制数据填充到UTF-8字节序列有效编码位中,如果没填充满,则高位补0,例如“汉”编号是0x6c49,二进制是0b01101100 01001001,填充至1110xxxx 10xxxxxx 10xxxxxx,得11100110 10110001 10001001