如何将整数转换为十六进制字符串?

300

我想将一个整数(小于等于255)转换成十六进制字符串表示。

例如:我想传入65并得到'\x41',或者传入255并得到'\xff'

我尝试使用struct.pack('c',65)实现,但是它只接受单个字符字符串,因此无法处理大于9的数字。

15个回答

282

你需要寻找chr函数。

看起来你混淆了整数的十进制表示和十六进制表示,所以不是很清楚你需要什么。根据你提供的描述,我认为以下代码片段中的一个展示了你想要的。

>>> chr(0x65) == '\x65'
True


>>> hex(65)
'0x41'
>>> chr(65) == '\x41'
True

请注意这与包含十六进制整数的字符串是非常不同的。如果您需要这样的话,请使用内置的hex


2
我认为chr将整数转换为ASCII码。在这种情况下,chr(65)= 'A'。这是一个新的添加吗? - diedthreetimes
2
@diedthreetimes,chr并不涉及ASCII——它只是将一个数字转换为一个字节串,其中字节的序数值就是这个数字。当您编写和显示字节串时,ASCII和ASCII兼容编码才会起作用。 - Mike Graham
1
例如,它们通过使'A'成为另一种写法和显示'\x41'的方式进入。所有str真正关心的是这是65。为了使人类能够理解和使用它,它经常变成一个A。@diedthreetimes - Mike Graham

155

这个代码会将一个整数转换为带有0x前缀的两位十六进制字符串:

strHex = "0x%0.2X" % integerVariable

2
我建议在这里编辑代码并更改为:strHex =“0x%0.2X”%integerVariable。(我自己无法进行编辑。) - Samuel

92

关于 hex() 呢?

hex(255)  # 0xff

如果你真的想在前面加上\,可以这样做:

print '\\' + hex(255)[1:]

1
repr(chr(255)) # '\xff' 也可以实现这个功能。 - Glenn 'devalias' Grant

82

有时候你只需要得到单个数字的表示方式,可以使用以下代码(x 可以是小写的 'x' 或者大写的 'X',这会决定输出的字母是大写还是小写):

'{:x}'.format(15)
> f

现在,使用新的f''格式化字符串,您可以执行以下操作:

f'{15:x}'
> f

要添加0填充,可以使用0>n

f'{2034:0>4X}'
> 07F2

注意:在f'{15:x}'中,初始的 'f' 表示格式化字符串


关于这个很棒的功能的参考资料,请查看 PEP 498 -- 字符串字面值插值。 - MFT
3
在我看来,一个更易读的选项是'0x{:X}'.format(15)(注意X是大写)。对于2034,它将打印0x7F2而不是7f2。 - Pavel Sapehin

51

"%#x" % 255 :) - VxJasonxV

31

对于 Python >= 3.6 版本,使用 f-string 格式化:

>>> x = 114514
>>> f'{x:0x}'
'1bf52'
>>> f'{x:#x}'
'0x1bf52'

1
这应该得到更多的赞。f-strings 赢了 :-) - Martin Thoma

13

使用format(),如format-examples所示,我们可以做到:

>>> # format also supports binary numbers
>>> "int: {0:d};  hex: {0:x};  oct: {0:o};  bin: {0:b}".format(42)
'int: 42;  hex: 2a;  oct: 52;  bin: 101010'
>>> # with 0x, 0o, or 0b as prefix:
>>> "int: {0:d};  hex: {0:#x};  oct: {0:#o};  bin: {0:#b}".format(42)
'int: 42;  hex: 0x2a;  oct: 0o52;  bin: 0b101010'

13
如果您想要使用一个小于255的值(一个字节无符号,uint8_t)来填充结构体,并最终得到一个字符长度的字符串,您可能需要使用格式B而不是c。C将字符转换为字符串(本身并不太有用),而B则将整数转换为字符串。
struct.pack('B', 65)

(是的,65是\x41,而不是\x65。)

结构体类还可以方便地处理通信或其他用途的字节序。


我花费的时间去查找struct.pack('B', <integer>)是惊人的。谢谢。 - Sean D.

12

请注意,对于大数值,hex() 仍然有效(某些其他答案则不行):

x = hex(349593196107334030177678842158399357)
print(x)

Python 2:0x4354467b746f6f5f736d616c6c3f7dL
Python 3:0x4354467b746f6f5f736d616c6c3f7d

要解密RSA消息,可以按以下步骤操作:

import binascii

hexadecimals = hex(349593196107334030177678842158399357)

print(binascii.unhexlify(hexadecimals[2:-1])) # python 2
print(binascii.unhexlify(hexadecimals[2:])) # python 3

好吧...不行。我尝试了hex(hash(text)),它产生了一个负整数,导致带有减号的十六进制字符串。谁实现了这个? - JPT
@JPT,我不明白你的问题。如果值为负数,那么十六进制值显然会有一个减号。为什么在写十六进制、二进制、十进制或任何其他数字系统时会有所不同呢?或者你是在寻找内存表示,其中有一个位通过设置或取消来确定符号? - Luc
2
计算机科学家期望负十六进制数以符号标志开头,例如 FFFx xxxx 或 8000 xxxx,而不是实际的符号。我从未见过带有减号的十六进制数。但如果你这么说... ;) - JPT
@JPT,你通常看到的十六进制值只是二进制值的十六进制表示。这是计算机科学中使用的编码方式(二进制补码)。过去也使用了不同的负二进制数表示方法,但是二进制补码具有最大的优势。 - Filip
@Filip 没错,这就是为什么带有负号的十六进制数不是精确表示,而是一种解释。 - JPT

10
(int_variable).to_bytes(bytes_length, byteorder='big'|'little').hex()
例如:
>>> (434).to_bytes(4, byteorder='big').hex()
'000001b2'
>>> (434).to_bytes(4, byteorder='little').hex()
'b2010000'

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