【问题标题】:Pythonic way to convert an integer into a hex-escaped string将整数转换为十六进制转义字符串的 Pythonic 方法
【发布时间】:2015-07-28 22:23:58
【问题描述】:

将整数转换为十六进制转义字符串的最 Pythonic 方式是什么?

0 -> '\x00'

15 -> '\x0f'

0xdeadbeef -> '\xde\xad\xbe\xef'

【问题讨论】:

  • @Lix:这绝对不是那个问题的重复,它专门询问值

标签: python


【解决方案1】:

没有办法直接做你想做的事,但做自己并不难。

例如,您可以将整个 int 转换为 hex,然后在每对字符之前插入一个 \x 字符:

n = 0xdeadbeef
x = format(n, 'x')
s = re.sub('(..)', r'\\x\1', x)
# or s = ''.join(r'\x{}{}'.format(*b) for b in pairwise(x))
# or s = ''.join(r'\x' + x[i:i+2] for i in range(0, len(x), 2))

或者您可以一次提取一个字节并自行格式化:

x = []
while n:
    x.append(n % 256)
    n //= 256
s = ''.join(r'\x{:02x}'.format(b) for b in reversed(x))

其中哪一个是最 Pythonic 的?我认为它们都很简单,如果你将它们包装在一个具有适当名称的函数中,没有人会抱怨,但它们都足够复杂,如果你只是将它们内联到你的代码中,它就不会很pythonic。 (我个人会使用pairwise 版本,只是因为我总是首先想到itertools,但这只是我。)

【讨论】:

    【解决方案2】:

    您想要 1 字节字符串 '\x0f' 还是 6 字节字符串 "'\\x0f'"(即打印时看起来像 '\x0f' 的字符串)有点模棱两可。如果您指的是前者,这里有一种方法:

    s = '%x' % 0xdeadbeef
    binascii.unhexlify('0' + s if len(s) % 2 else s)
    

    【讨论】:

      【解决方案3】:

      不确定“pythonic”如何,但这里有一个使用递归函数的解决方案:

      def uint_tuple_to_bytes(t):
              if t[0] < 0x100:
                      return t
              else:
                      return uint_tuple_to_bytes(divmod(t[0], 0x100) + t[1:])
      
      def uint_to_bytes(i):
              return uint_tuple_to_bytes((i,))
      
      def uint_to_binary_string(i):
              return ''.join(chr(byte) for byte in uint_to_bytes(i))
      

      (受abarnert's answer 的第二部分(“一次拉出一个字节”)和msvalkon's answer'How to split 16-bit unsigned integer into array of bytes in python?' 的启发。)

      【讨论】:

        猜你喜欢
        • 2015-11-29
        • 2014-12-15
        • 2013-12-07
        • 2017-08-12
        相关资源
        最近更新 更多