代码之家  ›  专栏  ›  技术社区  ›  JanFi86

Python中的Perl打包和解包

  •  0
  • JanFi86  · 技术社区  · 6 年前

    在Python 3中,将字节转换为十六进制字符串的正确方法是什么?

    我看到有人声称 bytes.hex 方法 bytes.decode 编解码器,并且已经尝试过了 other 最不令人惊讶的可能功能无效。我只希望我的字节是十六进制!

    0 回复  |  直到 14 年前
        1
  •  602
  •   Jean-François Fabre    6 年前

    自从Python 3.5以来,这终于不再尴尬了:

    >>> b'\xde\xad\xbe\xef'.hex()
    'deadbeef'
    

    反过来说:

    >>> bytes.fromhex('deadbeef')
    b'\xde\xad\xbe\xef'
    

    也适用于可变的 bytearray 类型

    参考: https://docs.python.org/3/library/stdtypes.html#bytes.hex

        2
  •  105
  •   Community Mohan Dere    9 年前

    使用 binascii 模块:

    >>> import binascii
    >>> binascii.hexlify('foo'.encode('utf8'))
    b'666f6f'
    >>> binascii.unhexlify(_).decode('utf8')
    'foo'
    

    看看这个答案: Python 3.1.1 string to hex

        3
  •  48
  •   Gabriel    12 年前

    Python有字节到字节的转换 standard codecs 它可以执行方便的转换,比如引号可打印(适合7位ascii)、base64(适合字母数字)、十六进制转义、gzip和bz2压缩。在Python 2中,可以执行以下操作:

    b'foo'.encode('hex')
    

    在Python 3中, str.encode / bytes.decode 严格来说是字节<->str转换。相反,您可以这样做,它可以跨Python 2和Python 3工作( s/编码/解码/g 反之亦然):

    import codecs
    codecs.getencoder('hex')(b'foo')[0]
    

    从Python 3.4开始,有一个不那么尴尬的选项:

    codecs.encode(b'foo', 'hex')
    

    这些misc编解码器也可以在自己的模块(base64、zlib、bz2、uu、quopri、binascii)中访问;API的一致性较差,但对于压缩编解码器,它提供了更多的控制。

        4
  •  15
  •   Peter Mitrano    6 年前

    Python3.8中的新功能是,可以将分隔符参数传递给 hex 函数,如本例所示

    >>> value = b'\xf0\xf1\xf2'
    >>> value.hex('-')
    'f0-f1-f2'
    >>> value.hex('_', 2)
    'f0_f1f2'
    >>> b'UUDDLRLRAB'.hex(' ', -4)
    '55554444 4c524c52 4142'
    

    https://docs.python.org/3/library/stdtypes.html#bytes.hex

        5
  •  11
  •   RubenLaguna    11 年前

    方法 binascii.hexlify() 会转变 bytes 字节 表示ascii十六进制字符串。这意味着输入中的每个字节将被转换为两个ascii字符。如果你想要一个真实的 str 那你就可以出去了 .decode("ascii") 结果呢。

    我附上了一个片段来说明这一点。

    import binascii
    
    with open("addressbook.bin", "rb") as f: # or any binary file like '/bin/ls'
        in_bytes = f.read()
        print(in_bytes) # b'\n\x16\n\x04'
        hex_bytes = binascii.hexlify(in_bytes) 
        print(hex_bytes) # b'0a160a04' which is twice as long as in_bytes
        hex_str = hex_bytes.decode("ascii")
        print(hex_str) # 0a160a04
    

    从十六进制字符串 "0a160a04" 可以回到 字节 具有 binascii.unhexlify("0a160a04") 这会回馈 b'\n\x16\n\x04'

        6
  •  7
  •   Infinite Recursion    11 年前
    import codecs
    codecs.getencoder('hex_codec')(b'foo')[0]
    

    适用于Python3.3(因此使用“hex_codec”而不是“hex”)。

        7
  •  4
  •   Arg0s    7 年前

    它可以用作格式说明符 %x02 该格式并输出十六进制值。例如:

    >>> foo = b"tC\xfc}\x05i\x8d\x86\x05\xa5\xb4\xd3]Vd\x9cZ\x92~'6"
    >>> res = ""
    >>> for b in foo:
    ...     res += "%02x" % b
    ... 
    >>> print(res)
    7443fc7d05698d8605a5b4d35d56649c5a927e2736
    
        8
  •  3
  •   Peter    8 年前

    好的,如果你只关心Python3,那么下面的答案就稍微超出了范围,但是这个问题是谷歌首次提出,即使你没有指定Python版本,所以这里有一种方法可以同时适用于Python2 Python 3。

    我还将这个问题解释为将字节转换为 str 类型:也就是说,在Python2上是bytes-y,在Python3上是Unicode-y。

    鉴于此,我所知道的最佳方法是:

    import six
    
    bytes_to_hex_str = lambda b: ' '.join('%02x' % i for i in six.iterbytes(b))
    

    假设您没有激活 unicode_literals Python 2的未来:

    assert bytes_to_hex_str(b'jkl') == '6a 6b 6c'
    

    (或者你可以使用 ''.join() 省略字节之间的空格等)

        9
  •  1
  •   hao li    9 年前

    如果要将b'\x61'转换为97或“0x61”,可以尝试以下操作:

    [python3.5]
    >>>from struct import *
    >>>temp=unpack('B',b'\x61')[0] ## convert bytes to unsigned int
    97
    >>>hex(temp) ##convert int to string which is hexadecimal expression
    '0x61'
    

    参考: https://docs.python.org/3.5/library/struct.html