程序的编码问题
# 编码问题
- 为什么需要编码问题
- 本质上计算机只能识别01代码
- 如何用一长串01代码表示复杂的信息
- 编码简史
- 二进制
- bit:一个0或者1的二进制数字
- byte:八个01代码,字节
- 第一阶段:ASCII
- 第二阶段:百花齐放,GB2312,GBK,BIG5,Latin1,JIS,
- Latin1:兼容欧洲大多数语言
- 韩国台湾:BIG5
- 日本:JIS
- ANSI-MBCS(Multi-bytes character set, 多字节字符集)
- 第三阶段:Unicode(ISO)
# 编码表示方法
- ASCII-american standard code for information interchange
- 所有控制字符(包括回车,删除等)编码在0-31范围以及127
- 所有标点符号,英文大小写放在32-126之间
- 预留128-255之间位置
- 0xxx xxxx 是它的编码形式
- Latin1
- 0-127的所有位置不动,那么可以兼容ASCII,二进制位0XXX XXXX
- 128-255位置全部用完,二进制位1XXX XXXX
- 128-159之间为控制字符,
- 160-255位文字符号,
- 其中包括了西欧语言、希腊语、泰语、阿拉伯语、希伯来语
- 欧元符号
-GBxxxxxxxxxx
- GB2312
- 如果一个字符中第一位为0,那么这就是一个ASCII字符。
- 如果一个字节中第一位为1,那么这个是汉字,认定需要2个字节才表示一个编码的文
- 这个码表中包含汉字6763个和非汉字图形字符682个。
- 还有很多的空间没有用到,索性全部预留了吧。
- 0xxxxxxxx:表示为ASCII字符
- 1xxxxxxx 1xxxxxxx:表示为汉字
----------------------------------------------------------------
- GBK
- 在GB2312基础上添加汉字
- 兼任GB2312和ASCII
- 0xxxxxxxx:表示ASCII字符
- 1xxxxxxxx xxxxxxxx:表示为汉字
- GB18030
- 2/4位混编
--------------------------------------------------------------------
# Unicode编码
- 只是一个码表,具体实现没有规定
- 0-0x10FFFF来映射这些字符,最多可以容纳1114112个字符
- 中文的编码范围为4E00-9FCF,其中9FC4-9FCF之间的区间没有使用
- 上述区间全都是汉字,不包含全角字符,不包含特殊文字
- UTF=UnicodeTransformationFormat
- UTF-8
---------------------------------------------------------------------------------------
Unicode/UCS-4
|
bit数
|
UTF-8
|
byte数
|
备注
|
0000 ~
007F
|
0~7
|
0XXX XXXX
|
1
|
|
0080 ~
07FF
|
8~11
|
110X XXXX
10XX XXXX
|
2
|
|
0800 ~
FFFF
|
12~16
|
1110XXXX
10XX XXXX
10XX XXXX
|
3
|
基本定义范围:0~FFFF
|
1 0000 ~
1F FFFF
|
17~21
|
1111 0XXX
10XX XXXX
10XX XXXX
10XX XXXX
|
4
|
Unicode6.1定义范围:0~10 FFFF
|
20 0000 ~
3FF FFFF
|
22~26
|
1111 10XX
10XX XXXX
10XX XXXX
10XX XXXX
10XX XXXX
|
5
|
说明:此非unicode编码范围,属于UCS-4 编码
早期的规范UTF-8可以到达6字节序列,可以覆盖到31位元(通用字符集原来的极限)。尽管如此,2003年11月UTF-8 被 RFC 3629 重新规范,只能使用原来Unicode定义的区域, U+0000到U+10FFFF。根据规范,这些字节值将无法出现在合法 UTF-8序列中
|
400 0000 ~
7FFF FFFF
|
27~31
|
1111 110X
10XX XXXX
10XX XXXX
10XX XXXX
10XX XXXX
10XX XXXX
|
6
|
-------------------------------------------------------------------------------------------------
- UTF-16, UTF-32
- UTF-16 早期 Uncode历史遗留问题
- UTF-32 浪费空间
- UCS-4
- 第一个字节:表示组(group),最高位为0,则有128个。
- 第二个字节:表示平面(plane),256个。
- 第三个字节:表示行(row),256个。
- 第四个字节:表示码位(cell),256个。
- 如果UCS-4前两个字节为0,则就是CUS-2
# 常用概念
- 编码/解码:由人类可直接读取信息转换成bytes格式的,叫编码,
- 大尾(BigEndian)和小尾(LittleEndian)
- “汉” -> 6C49
- 6C49 -> BigEndian
- 496C -> LittleEndian
- BOM
- UTF-8没有字节顺序问题
- UTF-16会出现问题
- “奎“ -> 594E
- "乙" -> 4E59
- BOM-ByteOrderMark
- "ZERO WIDTH NO-BERAK SPACE" -> FEFE, 在UCS中不存在
- FEFE->BigEndian
- FFFE->LittleEndian
- UTF-8 用来表示编码,FEFF的UTF-8编码是EF BB BF, 用来表示此后编码是UTF-8编码
# Python编码问题
- str
- bytes
- bytearray
-------------------------------------------------
- python文件默认utf-8编码,如果特殊需要,需要声明
- 放在第一行,或者第二行
- ···# -*- coding: windows-1252 -*-···
- code point方式比较字符串,可能会带来问题
- 重音符号的表示
- 使用 unicodedata, normalize 函数
- Python源码中出现了解码错误,那么会产生SyntaxError异常
- 其他情况下,如果发现编码解码错误,那么会产生UnicodeEncodeError,UnicodeDecodeError异常
-----------------------------------------------------------------