qbit
  • 149

关于 Python3 的编码(qbit)

Python3 中 str 与 bytes 的转换

bytes

字符与 Unicode 编号之间的转换

  • 字符转 Unicode 编号
>>> ord('A')
65
>>> hex(ord('A'))
'0x41'

>>> ord('你')
20320
>>> hex(ord('你'))
'0x4f60'

>>> '你好'.encode('unicode_escape')
b'\\u4f60\\u597d'
  • Unicode 编号转字符
>>> chr(65)
'A'
>>> chr(0x41)
'A'

>>> chr(20320)
'你'
>>> chr(0x4f60)
'你'

>>> b'\\u4f60\\u597d'.decode(('unicode_escape'))
'你好'
>>> print(b'\\u4f60\\u597d')
b'\\u4f60\\u597d'
>>> print(u'\u4f60\u597d')
你好

汉字与 gbk 十六进制/二进制之间的转换

# 汉字转十六进制
>>> '你好'.encode('gbk')
b'\xc4\xe3\xba\xc3'

# 十六进制转汉字
>>> b'\xc4\xe3\xba\xc3'.decode('gbk')
'你好'

# 汉字转十六进制字符串
>>> ''.join( [ '%02X' % x for x in '你好'.encode('gbk') ] ).strip()
'C4E3BAC3'
>>> ' '.join( [ '%02X' % x for x in '你好'.encode('gbk') ] ).strip()
'C4 E3 BA C3'

# 十六进制字符串转汉字
>>> bytes.fromhex('C4E3BAC3').decode('gbk')
'你好'
>>> bytes.fromhex('C4 E3 BA C3').decode('gbk')
'你好'

数字与十六进制之间的转换

# 数字转十六进制字符串
>>> hex(21)
'0x15'
>>> hex(21)[2:]
'15'

# 十六进制字符串转数字
>>> int('0x15', 16)
21
>>> int('15', 16)
21

数字与八进制之间的转换

# 数字转八进制字符串
>>> oct(21)
'0o25'
>>> oct(21)[2:]
'25'

# 八进制字符串转数字
>>> int('0o25', 8)
21
>>> int('25', 8)
21

数字与二进制之间的转换

# 数字转二进制字符串
>>> bin(5)
'0b101'
>>> bin(5)[2:]
'101'

# 二进制字符串转数字
>>> int('0b101', 2)
5

>>> int('101', 2)
5

bytes 相关

# bytes 对象转十六进制字符串
>>> "%02X" % ord(b'\xff')
'FF'
>>>  ''.join(["%02X" % i for i in b'\xe4\xbd\xa0\xe5\xa5\xbd'])
'E4BDA0E5A5BD'

# 生成 32 byte 的十六进制随机字符串(unpredictable)
>>> ''.join(["%02x" % i for i in os.urandom(32)])
2f15c8cc8852bf3e094bf3fa19fe0a6e1b3ba8d13b8c129f5f29fcf1ac968750

# bytes 转 int
>>> ord(b'\xff')
255

# int 转 bytes
>>> bytes([255])
b'\xff'

bit 相关

# 字符串转 01 串(默认 endian 是大端)
>>> arr = bitarray()
>>> arr.frombytes('你好'.encode('utf8'))
>>> arr.to01()
'111001001011110110100000111001011010010110111101'

# 01 串转字符串
>>> bitarray('111001001011110110100000111001011010010110111101').tobytes().decode('utf8')
'你好'

关于 utf8 的 bom 头

>>> import codecs
>>> codecs.BOM_UTF8
b'\xef\xbb\xbf'
>>> len(b'\xef\xbb\xbf')
3
>>> codecs.BOM_UTF8.decode('utf8')
'\ufeff'
>>> len('\ufeff')
1

Python3 内置编码

>>> from encodings.aliases import aliases
>>> for k in aliases:
    print('%s: %s' % (k, aliases[k]))
  • 验证是不是有效编码
>>> import codecs

>>> codecs.lookup('utf8')    #有效
<codecs.CodecInfo object for encoding utf-8 at 0x13fb4f50828>

>>> codecs.lookup('utf-;8')    #有效
<codecs.CodecInfo object for encoding utf-8 at 0x13fb4f50a08>

>>> codecs.lookup('utf88')    #无效
Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    codecs.lookup('utf88')
LookupError: unknown encoding: utf88
  • 标准化 encoding
>>> import encodings
>>> encodings.normalize_encoding('utf-;8')
'utf_8'

对应 C 代码为:unicodeobject.c 中的 _Py_normalize_encoding 函数。

import sys
import locale
 
# 当前系统所使用的默认字符编码
>>> sys.getdefaultencoding()
'utf-8'
 
# 用于转换 Unicode 文件名至系统文件名所使用的编码
>>> sys.getfilesystemencoding()
'utf-8'
 
# 获取默认的区域设置并返回元组(语言, 编码)
>>> locale.getdefaultlocale()
('zh_CN', 'cp936')
 
# 返回用户设定的文本数据编码
# 文档提到this function only returns a guess
>>> locale.getpreferredencoding()
'cp936'

字符串反转

>>> line = '0123456789'
>>> line[::-1]
'9876543210'
本文出自 qbit snap
阅读 424

推荐阅读
qbit snap
用户专栏

开箱即用,拿走不谢。

206 人关注
106 篇文章
专栏主页