¿Cómo convertir un int en una cadena hexadecimal?

210

Quiero llevar un número entero (que será <= 255) a una representación de cadena hexadecimal

Por ejemplo: quiero pasar 65y salir '\x41', o 255llegar '\xff'.

He intentado hacer esto con el struct.pack('c',65 ), pero eso se ahoga en todo lo anterior 9ya que quiere incluir una sola cadena de caracteres.

pynoob
fuente

Respuestas:

214

Estás buscando la chrfunción.

Parece que está mezclando representaciones decimales de enteros y representaciones hexadecimales de enteros, por lo que no está del todo claro lo que necesita. Según la descripción que proporcionó, creo que uno de estos fragmentos muestra lo que desea.

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


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

Tenga en cuenta que esto es bastante diferente de una cadena que contiene un número entero como hexadecimal . Si eso es lo que quieres, usa el hexincorporado.

Mike Graham
fuente
2
Pensé que chr convirtió enteros a ascii. En cuyo caso chr (65) = 'A'. ¿Es esta una nueva adición?
falleció el
2
@diedthreetimes, chrno involucra ASCII en absoluto: simplemente toma un número y crea una cadena de bytes de un byte donde el valor ordinal del byte es el número. Las codificaciones ASCII y ASCII compatibles entran en juego al escribir y mostrar cadenas de bytes.
Mike Graham
1
@diedthreetimes, por ejemplo, entran haciendo 'A'otra forma de escribir y mostrar '\x41'. Todo lo que strrealmente le importa es el hecho de que son sesenta y cinco. Para hacer que las cosas sean comprensibles y utilizables por los humanos, a menudo se convierte en una A.
Mike Graham
135

Esto convertirá un entero en una cadena hexadecimal de 2 dígitos con el prefijo 0x:

strHex = "0x%0.2X" % 255
Greg Bray
fuente
2
Sugiero editar el código aquí y cambiarlo a esto: strHex = "0x% 0.2X"% integerVariable. (No pude editarme)
Samuel
58

¿Qué hay de hex()?

hex(255)  # 0xff

Si realmente quieres tener \al frente puedes hacer:

print '\\' + hex(255)[1:]
Felix Kling
fuente
repr(chr(255)) # '\xff'también logra esto
Glenn 'devalias'
31

Déjame agregar este, porque a veces solo quieres la representación de un solo dígito:

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

Y ahora con las nuevas f''cadenas de formato que puede hacer:

f'{15:x}'
> f

NOTA: la 'f' inicial f'{15:x}'es para indicar una cadena de formato

Monkut
fuente
Para referencia sobre esta característica ordenada, PEP 498 - Interpolación de cadena literal
MFT
1
En mi humilde opinión, una opción un poco más "legible" puede ser '0x {: X}'. Format (15) (aviso X está en mayúsculas). Para 2034 imprimirá 0x7F2 en lugar de 7f2
Pavel Sapehin
11

Si desea empaquetar una estructura con un valor <255 (un byte sin signo, uint8_t) y terminar con una cadena de un carácter, probablemente esté buscando el formato B en lugar de c . C convierte un carácter en una cadena (no demasiado útil por sí mismo) mientras que B convierte un número entero.

struct.pack('B', 65)

(Y sí, 65 es \ x41, no \ x65.)

La clase struct también manejará convenientemente la resistencia para la comunicación u otros usos.

XTL
fuente
La cantidad de tiempo que me ha llevado encontrar struct.pack ('B', <integer>) es asombrosa. Gracias.
Sean D.
7

Tenga en cuenta que para valores grandes, hex()aún funciona (algunas otras respuestas no):

x = hex(349593196107334030177678842158399357)
print(x)

Python 2: 0x4354467b746f6f5f736d616c6c3f7dL
Python 3:0x4354467b746f6f5f736d616c6c3f7d

Para un mensaje RSA descifrado, se podría hacer lo siguiente:

import binascii

hexadecimals = hex(349593196107334030177678842158399357)

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

Esto funcionó mejor para mí

"0x%02X" % 5  # => 0x05
"0x%02X" % 17 # => 0x11

Cambie el (2) si desea un número con un ancho mayor (2 es para 2 caracteres impresos en hexadecimal), de modo que 3 le dará lo siguiente

"0x%03X" % 5  # => 0x005
"0x%03X" % 17 # => 0x011
shakram02
fuente
3

Quería un entero aleatorio convertido en una cadena hexadecimal de seis dígitos con un # al principio. Para conseguir esto usé

"#%6x" % random.randint(0xFFFFFF)
ncmathsadist
fuente
66
Supongo que te refieres "#%6x" % random.randint(0x0, 0xFFFFFF). (Faltan %antes 6y randinttoma 2 parámetros -más bajos y límites superiores-)
pacha
55
debería ser% 06x si no quieres espacios
Janus Troelsen
3

Con format(), según los ejemplos de formato , podemos hacer:

>>> # 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'
Mapa
fuente
2
(int_variable).to_bytes(bytes_length, byteorder='big'|'little').hex()

Por ejemplo:

>>> (434).to_bytes(4, byteorder='big').hex()
'000001b2'
>>> (434).to_bytes(4, byteorder='little').hex()
'b2010000'
Chengcheng Zhang
fuente
1

También puede convertir cualquier número en cualquier base a hexadecimal. Use este código de línea aquí, es fácil y simple de usar:

hex(int(n,x)).replace("0x","")

Tienes una cadena nque es tu número y x la base de ese número. Primero, cámbielo a entero y luego a hexadecimal, pero hexadecimal tiene 0xal principio, así que con lo replaceeliminamos.

Izak Sensei
fuente
-1

Como una representación alternativa que podría usar

[in] '%s' % hex(15)
[out]'0xf'
Uzumaki
fuente