Python3 中 str 与 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'
    >>> binascii.b2a_hex('你好'.encode('gbk')).upper().decode('gbk')
    'C4E3BAC3'
    >>> '你好'.encode('gbk').hex(' ').upper()
    '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'
    >>> b'\xff'.hex().upper()
    'FF'
    
    >>>  ''.join(["%02X" % i for i in b'\xe4\xbd\xa0\xe5\xa5\xbd'])
    'E4BDA0E5A5BD'
    >>> b'\xe4\xbd\xa0\xe5\xa5\xbd'.hex().upper()
    '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 相关

  • 需使用第三方包 bitarray

    # 字符串转 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 内置编码

  • Python3 有哪些编码: Standard EncodingsPython Specific Encodings 。
  • 打印编码及别名: Get a list of all the encodings Python can encode to

    >>> 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 函数。

  • sys/locale 模块中与编码相关的方法。(Python字符编码详解

    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

qbit
268 声望279 粉丝