4

这是将 Python 数字转换为十六进制字符串的最佳方法吗?

number = 123456789
hex(number)[2:-1].decode('hex')

有时它不起作用并在您执行 1234567890 时抱怨奇怪长度的字符串。

澄清:

我要从 int 到 hex。

另外,我需要它被逃脱。

IE: 1234567890 -> '\x49\x96\x02\xd2' 不是 '499602D2'

此外,它需要能够接受任何 Python 整数。IE。比 Int 更大的东西。

编辑:

这是迄今为止我从 Paolo 和 Devin 的帖子中拼凑起来的最佳解决方案。

def hexify(num):
    num = "%x" % num

    if len(num) % 2:
        num = '0'+num

    return num.decode('hex')
4

7 回答 7

6

您可以使用字符串格式

>>> number = 123456789
>>> hex = "%X" % number
>>> hex
'75BCD15'
于 2009-03-30T22:28:52.447 回答
5

我不确定你到底想要什么,但你看过这个struct模块吗?

给定

>>> hex(123456789)
'0x75bcd15'

你可以做:

>>> struct.pack('i', 123456789)
'\x15\xcd[\x07'

请注意'\x5b' == '['.

此外,您可以反转字节顺序:

>>> struct.pack('>i', 123456789)
'\x07[\xcd\x15'

编辑:我不确定您所说的“大于长”是什么意思,因为 python 中的 AFAIK 长是无界的(内存除外)。但是,您可以通过除法和连接来处理更大的整数。例如给定:

>>> n = 123456789012345678901234567890

目标是:

>>> hex(n)
'0x18ee90ff6c373e0ee4e3f0ad2L'

所以:

>>> s = ''
>>> while n >= 2**32:
...  n, r = divmod(n, 2**32)
...  s = struct.pack('>l', r) + s
... 
>>> s = struct.pack('>l', n) + s

看到与上面s的结果相匹配hex(n)

>>> s
'\x00\x00\x00\x01\x8e\xe9\x0f\xf6\xc3s\xe0\xeeN?\n\xd2'
于 2009-03-30T22:47:49.170 回答
1
'{0:b}'.format( number )

参考http://docs.python.org/library/string.html

于 2011-06-03T02:05:45.927 回答
1

有时它不起作用并在您执行 1234567890 时抱怨奇怪长度的字符串。

因为没有意义。您如何在需要 2 位或 4 位数字的空间中放置“AAB”?每个字节是两个十六进制字符。当您有奇数个十六进制字符时,所需的结果是不明确的。您希望它相当于 0AAB 还是 AAB0?如果您知道您希望它等同于哪一个,只需在解码之前将该字符添加到正确的位置即可。

(('0' + foo) if len(foo) % 2 else foo).decode('hex')其中 foo 是由返回的形式的字符串%x.

于 2009-03-30T22:31:03.563 回答
0

正如 Paolo 提到的,字符串格式化是要走的路。请注意,您可以在小写和大写字母之间进行选择:

>>> hex = lambda n: '%X' % n
>>> hex(42)
'2A'
>>> hex = lambda n: '%x' % n
>>> hex(42)
'2a'
>>> def escaped(n):
...     s = hex(n)
...     if len(s) & 1:
...          s = '0' + s
...     return ''.join(chr(int(s[i:i + 2], 16)) for i in range(0, len(s), 2))
...
>>> escaped(123)
'{'
>>> escaped(1234)
'\x04\xd2'
>>> escaped(12348767655764764654764445473245874398787989879879873)
'!\x01^\xa4\xdf\xdd(l\x9c\x00\\\xfa*\xf3\xb4\xc4\x94\x98\xa9\x03x\xc1'

请注意,如果十六进制数字为奇数,则转义会添加前导零。此解决方案适用于任何长度的字符串。

于 2009-03-30T22:33:40.080 回答
0

如果您知道输出字符串应该有多长,那么字符串格式将起作用。例如,要获取四个字符的字符串,您需要格式化长度为 8:

>>> "{0:08x}".format(123456789).decode("hex")
'\x07[\xcd\x15'
>>> "{0:08x}".format(1234567890).decode("hex")
'I\x96\x02\xd2'

如果您的号码没有“填满”字符串,这将在前面添加零。例如,对于六个字符的字符串:

>>> "{0:012x}".format(123456789).decode("hex")
'\x00\x00\x07[\xcd\x15'
>>> "{0:012x}".format(1234567890).decode("hex")
'\x00\x00I\x96\x02\xd2'

编辑:

要“检测”目标字符串的长度,您可以使用以下math.log函数:

>>> def int2str(n):
        l = int(math.ceil(math.log(n, 256) / 2) * 4)
        return ("{0:0{1}x}").format(n, l).decode("hex")

>>> int2str(123456789)
'\x07[\xcd\x15'
>>> int2str(1234567890)
'I\x96\x02\xd2'
于 2009-03-30T22:47:32.993 回答
0

对于任意数字,最可靠的方法之一是像这样使用“数组”模块:

from array import array
binArr = array('B')

while(data):
    d = data & 0xFF
    binArr.append(d)
    data >>= 8

hexStr = binArr.tostring()
于 2010-06-29T10:23:44.447 回答