python编码和解码
Introduction
UCS and CSI
Perl,Python字符串处理: 关于perl, python多字节字符处理方式, 其中:
- UCS(python): 不管读取的是哪一种编码的字节,程序统一设定为某一种特定编码
- CSI(Perl): 读取的字节不需要转换,只是把一个字节串加上一个编码的属性
Five facts of life
关于unicode的5点事实以及3个技巧:
- Fact of life 1:All input and output of your program is bytes
- Fact of life 2:The world needs more than 256 symbols to communicate text
- Fact of life 3:Your program has to deal with both bytes and Unicode
- Fact of life 4:A stream of bytes can’t tell you its encoding.
- Fact of life 5:Encoding specifications can be wrong
Three pro tips:
- Unicode Sandwich: 尽可能确保代码都是unicode, 外层的读写都是bytes
- Know what you have: 了解你当前处理的子串的编码, 而不是一昧的根据 BUG 来修复
- Test: 使用测试用例
其中关于life 1和life 2问题, 提出了unicode来进行处理, 其中每一个code point
都用于表示一个特殊的字符(字体).
对于life3, life4: 则需要利用tip1/tip2来尽可能的确保你所处理的所有中文字符都是
在你的预知范围内.
对于life5的解释, 有时候别人告知你的编码可能不是实际的字符编码, 例如对于某一个
HTML页面, 其告知你编码为 UTF8, 但是可笑的是, 实际为 ISO-8859, 此时就需要进行
编码检查( TEST ).
Code Point
Unicode标准定义了需要将code point
表示字节的方法, 他们被称为编码
.
注意encoding
和encode
的区别.
注意code point
并不等同于byte, 两者的值也是不相等的.
编码说明
目前已知的编码方案:
- ASCII 编码: 范围0x00
0xff, 其中一般使用0x000x80 - GBK编码: 汉字内码扩展规范
- GB2312编码: 汉字编码字符集, 替代 GBK, 长度为 2 字节, 其中: 0xA1A1~0xFEFE 表示汉字信息
- Unicode编码: 万国码,国际码, 统一码. UCS-4, UCS-2等
其中Unicode编码(常见的 UTF8)是对各个国家MBCS
混乱现象的重新编排, 收录各个国家所有文字并
统一.
Encode and Decode
Encode and Decode
- Encode: 唯一目的, 将字符–>字节, 这才是真正的目的, 其他都是耍流氓
- Decode: 唯一目的, 将字节–>字符, 这才是真正的目的, 其他都是混日子
Bytes and Strs
- Bytes: 一串0和1组成
- Character: 抽象的, 特定的符号
Py2 and Py3
- python2: str–实际为字节串, unicode–实际为字符串
- python3: bytes–字节串, str–字符串(python2中的unicode)
其中在python2中, 会隐士进行bytes->unicode的转换, 所以在调用print函数的时候,
一些bytes会默认被转为unicode
并输出. 对于python3, 不支持隐士转换, 在python3
中, 进行bytes和str的合并操作会抛出异常.
Postscript: 因为py2没有搞清楚字节和字串的含义, 所以导致在py2中对str/unicode的编码,
解码处理常常出现问题, 本来字节串对象当且仅当有函数decode, 字符串当且仅当有encode.
Example
python2:
1 | # 首先检测编码类型, 之后才解码 |
python3:
1 | plain = 'Hello world, 碧峰' |
Python2 Example
RSA
Function: 进行SHA256加密, 其中SHA256包的输入数据为: 字节码
Process: 构造原始”字符串”—>将原始”字符串”转为”字节串”—>签名返回签名”字节串”—>对签名”字节串”进行base64, 确保数据能够正常传输.
1 | # 初始化 |
Implicit and Encode
对于隐士转换, 以及相关编码解码进行举例, 建议同下一节一起了解
1 | # bytes -> unicode |
Python3 Example
Rsa
Function: 按照指定的格式(字节流, 将不同的数据填充的不同byte长度的容器中)进行数据的转换与拼接, 将len(plain)放到一个4字节的字节流中, 将plain转换为bytes
Process: 调用struct转换len(plain)—>调用bytes(plain, encoding=’utf8’)来将”字符串”转变为”字节串”—>拼接各个字节串
Encode Code:
1 | # 4字节长度 |
Decode Code
1 | # 在进行解密之后(公私钥), 将字节流-->字符串 |
Encode and Decode
python3不支持隐士转换, 其中编码类似python
1 | # 不支持隐士转换, 并且不能转换 |
Detech Bytes Encoding
Introduction
检测bytes的编码类型, 使用chardet模块来完成.
Example
1 | # 构建字节流 |
Json
utf8
对于包含中文编码的JSON文件, 在进行json->str
转换时, 需要使用ensure_ascii
来进行转换.
1 | import json |
save-to-file
对于json, 如果需要以json格式保存到文件中, 可以直接使用dumps方法
1 | import json |
但是此时, 中文会以Unicode形式存储, 此时需要使用codecs
以utf8格式打开文件
1 | import json |
Base64
Encode
python3中, base64的编码仅仅面向字节字符串或者字节数组, 并且输出结果也总是字节字符串.
如果需要混合字节码和字符串(python3的str就是Unicode), 则需要对原始的str先进行str-->字节码
的操作.
1 | import base64 |
python2中, str实际为字节码, 可以直接进行base64编码
1 | import base64 |