字符编码
- # -*- coding:utf-8 -*-
- ASCII-->扩展ANSI编码-->GB2312-->GBK-->UNICODE-->UTF-8
- 扩展ANSI编码:从128到255的字符集对应拉丁文。
- GB2312编码:GB2312编码范围:A1A1-FEFE,第一字节0xB0-0xF7(对应区号:16-87),第二个字节0xA1-0xFE(对应位号:01-94)。
- GBK编码:GBK 亦采用双字节表示,总体编码范围为 8140-FEFE,首字节在 81-FE 之间,尾字节在 40-FE 之间,剔除 xx7F 一条线。总计 23940 个码位。
- UNICODE和UTF:Unicode是内存编码表示方案(是规范),而UTF是如何保存和传输Unicode的方案(是实现)
- UNICODE涉及到两个步骤,首先是定义一个规范,给所有的字符指定一个唯一对应的数字,这完全是数学问题,可以跟计算机没半毛钱关系。第二步才是怎么把字符对应的数字保存在计算机中,这才涉及到实际在计算机中占多少字节空间。
- UNICODE是用0至65535之间的数字来表示所有字符。其中0至127这128个数字表示的字符仍然跟ASCII完全一样。65536是2的16次方。这是第一步。第二步就是怎么把0至65535这些数字转化成01串保存到计算机中。这肯定就有不同的保存方式了。于是出现了UTF(unicode transformation format),有UTF-8,UTF-16。
- UTF-16比较好理解,就是任何字符对应的数字都用两个字节来保存。我们通常对Unicode的误解就是把Unicode与UTF-16等同了。但是很显然如果都是英文字母这做有点浪费,明明用一个字节能表示一个字符为啥整两个啊。
- 用UTF-8时表示一个字符是可变的,有可能是用一个字节表示一个字符,也可能是两个、三个。当然最多不能超过3个字节了。
- 打开一个文件时我们怎么知道那是用的UTF-8还是UTF-16啊。自然会有点啥标志,在文件的开头几个字节就是标志。EF BB BF 表示UTF-8,FE FF 表示UTF-16。
- 假如用UTF-16表示的话就是01101100 01001001(共16 bit,两个字节)。程序解析的时候知道是UTF-16就把两个字节当成一个单元来解析。这个很简单。
- 用UTF-8就有复杂点。因为此时程序是把一个字节一个字节的来读取,然后再根据字节中开头的bit标志来识别是该把1个还是两个或三个字节做为一个单元来处理。所有一个字节只能表示2的7次方128个字符。两个字节只能表示2的11次方2048个字符。而三个字节能表示2的16次方,65536个字符。
- 0xxxxxxx,如果是这样的01串,也就是以0开头后面是啥就不用管了XX代表任意bit。就表示把一个字节做为一个单元,就跟ASCII完全一样。
- 110xxxxx 10xxxxxx,如果是这样的格式,则把两个字节当一个单元。
- 1110xxxx 10xxxxxx 10xxxxxx 如果是这种格式则是三个字节当一个单元。
- 中文字"汉"对应的unicode是6C49(这是用十六进制表示,用十进制表示是27721)。
-
char data_utf8[] ={0xE6,0xB1,0x89,0xE5,0xAD,0x97} //UTF-8编码
char16_t data_utf16[]={0x6C49,0x5B57} //UTF-16编码
char32_t data_utf32[]={0x00006C49,0x00005B57} //UTF-32编码 -
1 import json 2 3 s='汉' 4 print(type(s)) #<class 'str'> 5 print(s) #汉 6 print(json.dumps(s)) #"\u6c49" 7 8 b=s.encode('utf-8') 9 print(type(b)) # <class 'bytes'> 10 print(b) # b'\xe6\xb1\x89' 11 12 u=b.decode('utf-8') 13 print(type(u)) #<class 'str'> 14 print(u) #汉 15 print(json.dumps(u)) #"\u6c49"
-
b=s.encode('GBK')
print(type(b)) # <class 'bytes'>
print(b) # b'\xba\xba' - https://www.cnblogs.com/fnlingnzb-learner/p/6163205.html