将整数转换为具有特定格式的十六进制字符串

9

我是一名新手,正在学习Python,遇到了以下问题:我需要将一个整数转换为6个字节的十六进制字符串。

例如: 281473900746245 --> "\xFF\xFF\xBF\xDE\x16\x05"

十六进制字符串的格式很重要。整数值的长度是可变的。

格式'0xffffbf949309L'对我不起作用。(使用hex(int-value)可以得到这个结果)


我的最终解决方案(经过一些“试验”)是:

def _tohex(self, int_value):
    data_ = format(int_value, 'x')

    result = data_.rjust(12, '0')
    hexed = unhexlify(result)

    return hexed

感谢您所提供的所有帮助!

1
你想要Python字符串字面值“\xFF\xFF\xBF\xDE\x16\x05”定义的长度为6的字符串,还是由“\xFF\xFF\xBF\xDE\x16\x05”给出的长度为24的字符串? - Sven Marnach
术语“十六进制字符串”和“格式”是误导性的,你真正想要的是将任意大小的整数形成一个字节串,并按大端序排列。 - Ferdinand Beyer
1
请原谅我的英语 - 我只是从我的第一语言翻译了这些术语 - 感谢您的翻译。 - Oxymoron
3个回答

13

也许有更好的解决方案,但你可以这样做:

x = 281473900746245
decoded_x = hex(x)[2:].decode('hex') # value: '\xff\xff\xbf\xde\x16\x05'

分解:

hex(x)                     # value: '0xffffbfde1605'
hex(x)[2:]                 # value: 'ffffbfde1605'
hex(x)[2:].decode('hex')   # value: '\xff\xff\xbf\xde\x16\x05'

更新:

根据 @multipleinstances 和 @Sven 的评论,由于您可能处理的是较长的值,因此您可能需要稍微调整十六进制输出:

format(x, 'x')     # value: 'ffffbfde1605'
有时,使用hex的输出可能是奇数长度,这会导致解码出错,因此最好创建一个函数来解决这个问题:
def convert(int_value):
   encoded = format(int_value, 'x')

   length = len(encoded)
   encoded = encoded.zfill(length+length%2)

   return encoded.decode('hex')

1
在我的系统上,hex(x)[2:] 生成了 ffffbfde1605L,这会导致解码中出现 TypeError。也许使用 hex(x)[2:-1] 会更好一些。 - multipleinterfaces
2
@multipleinterfaces:无条件地剥离最后一个字节是一个不好的想法。hex(x)[2:].rstrip("L")应该可以完成任务。 - Sven Marnach
@multiple 实际上,这对于 L 值不起作用,因为十六进制输出可能是奇数长度(出于某种原因)。 - Manny D
@Manny:你的解决方案对于由奇数个十六进制字符组成的任何数字都不起作用。例如,27480xABC,而str.decode('hex')需要0abc而不是abc - Ferdinand Beyer
2
为了避免使用0x前缀和L后缀的麻烦,建议使用format(number, 'x')代替hex() - Ferdinand Beyer

4
在Python 3.2或更高版本中,您可以使用整数的 to_bytes() 方法进行操作。
>>> i = 281473900746245       
>>> i.to_bytes((i.bit_length() + 7) // 8, "big")
b'\xff\xff\xbf\xde\x16\x05'

1
值得一提的是,您需要预先计算所需长度(使用math.logint.bit_length),并且可能希望指定byteorder ='big' - Ferdinand Beyer
@Ferdinand:谢谢,我扩展了我的答案。 - Sven Marnach

1

如果您没有使用Python 3.2(我很确定您没有),请考虑下一种方法:

>>> i = 281473900746245
>>> hex_repr = []
>>> while i:
...     hex_repr.append(struct.pack('B', i & 255))
...     i >>= 8
...
>>> ''.join(reversed(hex_repr))
'\xff\xff\xbf\xde\x16\x05'

我测试了这种方法...只有当int值不太短时才有效。例如,当i=2时,我得到'\x02\x1d\x08\xff\xff\xbf\xde\x16\x05'... - Oxymoron

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接