Tengo esta cadena: Hello world !!
y quiero imprimirla usando Python como 48:65:6c:6c:6f:20:77:6f:72:6c:64:20:21:21
.
hex()
funciona solo para enteros.
¿Cómo puede hacerse esto?
Tengo esta cadena: Hello world !!
y quiero imprimirla usando Python como 48:65:6c:6c:6f:20:77:6f:72:6c:64:20:21:21
.
hex()
funciona solo para enteros.
¿Cómo puede hacerse esto?
Respuestas:
Puede transformar su cadena en un generador int, aplicar formato hexadecimal para cada elemento e intercalar con separador:
>>> s = "Hello world !!"
>>> ":".join("{:02x}".format(ord(c)) for c in s)
'48:65:6c:6c:6f:20:77:6f:72:6c:64:20:21:21
str
como hexadecimal realmente no tiene sentido; querrá imprimir el bytes
objeto como hexadecimal (convertir str
a bytes
llamando .encode()
).
":".join("{:02x}".format(ord(c)) for c in 'løl')
devuelve '6c:f8:6c'
, mientras que ":".join("{:02x}".format(c) for c in 'løl'.encode())
produce la representación utf-8 correcta '6c:c3:b8:6c'
.
":".join("{:04x}".format(ord(c)) for c in s)
(reemplazando 02x
con 04x
cero cada número para que tenga 4 dígitos)
WARNING: Calling str(pkt) on Python 3 makes no sense!
':'.join(x.encode('hex') for x in 'Hello World!')
h = binascii.hexlify(b"Hello world !!") to get hex string. b":".join(h[i:i+2] for i in range(0, len(h), 2))
para insertar ':'
después de cada dos dígitos hexadecimales.
LookupError: 'hex' is not a text encoding; use codecs.encode() to handle arbitrary codecs
Para Python 2.x:
':'.join(x.encode('hex') for x in 'Hello World!')
El código anterior no funcionará con Python 3.x , para 3.x, el código siguiente funcionará:
':'.join(hex(ord(x))[2:] for x in 'Hello World!')
Otra respuesta en dos líneas que algunos pueden encontrar más fácil de leer y ayuda a depurar saltos de línea u otros caracteres extraños en una cadena:
Para Python 2.7
for character in string:
print character, character.encode('hex')
Para Python 3.7 (no probado en todas las versiones de 3)
for character in string:
print(character, character.encode('utf-8').hex())
codecs.encode(<bytestring>, "hex")
funciona, sin embargo.
import sys
; s="Déjà vu Besançon,Lupiñén,Šiauliai,Großräschen,Łódź,Аша,广东省,LA"
; for c in s:
; w=sys.stdout.write(c+":"+c.encode('utf-8').hex()+"||")
; (out)D:44||é:c3a9||j:6a||à:c3a0|| :20||v:76||u:75|| :20||B:42||e:65||s:73||a:61||n:6e||ç:c3a7||o:6f||n:6e||,:2c||L:4c||u:75||p:70||i:69||ñ:c3b1||é:c3a9||n:6e||,:2c||Š:c5a0||i:69||a:61||u:75||l:6c||i:69||a:61||i:69||,:2c||G:47||r:72||o:6f||ß:c39f||r:72||ä:c3a4||s:73||c:63||h:68||e:65||n:6e||,:2c||Ł:c581||ó:c3b3||d:64||ź:c5ba||,:2c||А:d090||ш:d188||а:d0b0||,:2c||广:e5b9bf||东:e4b89c||省:e79c81||,:2c||L:4c||A:41||
Algunos complementos a la respuesta de Fedor Gogolev:
Primero, si la cadena contiene caracteres cuyo 'código ASCII' es inferior a 10, no se mostrarán según sea necesario. En ese caso, el formato correcto debería ser {:02x}
:
>>> s = "Hello unicode \u0005 !!"
>>> ":".join("{0:x}".format(ord(c)) for c in s)
'48:65:6c:6c:6f:20:75:6e:69:63:6f:64:65:20:5:20:21:21'
^
>>> ":".join("{:02x}".format(ord(c)) for c in s)
'48:65:6c:6c:6f:20:75:6e:69:63:6f:64:65:20:05:20:21:21'
^^
En segundo lugar, si su "cadena" es en realidad una "cadena de bytes", y dado que la diferencia es importante en Python 3, puede preferir lo siguiente:
>>> s = b"Hello bytes \x05 !!"
>>> ":".join("{:02x}".format(c) for c in s)
'48:65:6c:6c:6f:20:62:79:74:65:73:20:05:20:21:21'
Tenga en cuenta que no hay necesidad de conversión en el código anterior ya que los objetos de bytes se definen como "una secuencia inmutable de enteros en el rango 0 <= x <256" .
Imprimir una cadena como bytes hexadecimales?
La respuesta aceptada da:
s = "Hello world !!"
":".join("{:02x}".format(ord(c)) for c in s)
devoluciones:
'48:65:6c:6c:6f:20:77:6f:72:6c:64:20:21:21'
La respuesta aceptada solo funciona mientras use bytes (principalmente caracteres ascii). Pero si usa unicode, por ejemplo:
a_string = u"Привет мир!!" # "Prevyet mir", or "Hello World" in Russian.
Necesita convertir a bytes de alguna manera.
Si su terminal no acepta estos caracteres, puede decodificar desde UTF-8 o usar los nombres (para que pueda pegar y ejecutar el código junto conmigo):
a_string = (
"\N{CYRILLIC CAPITAL LETTER PE}"
"\N{CYRILLIC SMALL LETTER ER}"
"\N{CYRILLIC SMALL LETTER I}"
"\N{CYRILLIC SMALL LETTER VE}"
"\N{CYRILLIC SMALL LETTER IE}"
"\N{CYRILLIC SMALL LETTER TE}"
"\N{SPACE}"
"\N{CYRILLIC SMALL LETTER EM}"
"\N{CYRILLIC SMALL LETTER I}"
"\N{CYRILLIC SMALL LETTER ER}"
"\N{EXCLAMATION MARK}"
"\N{EXCLAMATION MARK}"
)
Entonces vemos que:
":".join("{:02x}".format(ord(c)) for c in a_string)
devoluciones
'41f:440:438:432:435:442:20:43c:438:440:21:21'
un resultado pobre / inesperado: estos son los puntos de código que se combinan para hacer que los grafemas que vemos en Unicode, del Consorcio Unicode, representen idiomas en todo el mundo. Sin embargo, no es así como almacenamos esta información para que otras fuentes puedan interpretarla.
Para permitir que otra fuente use estos datos, generalmente deberíamos convertir a la codificación UTF-8, por ejemplo, para guardar esta cadena en bytes en el disco o para publicar en html. Por lo tanto, necesitamos esa codificación para convertir los puntos de código en las unidades de código de UTF-8; en Python 3, ord
no es necesaria porque bytes
son iterables de enteros:
>>> ":".join("{:02x}".format(c) for c in a_string.encode('utf-8'))
'd0:9f:d1:80:d0:b8:d0:b2:d0:b5:d1:82:20:d0:bc:d0:b8:d1:80:21:21'
O quizás de manera más elegante, utilizando las nuevas cadenas f (solo disponibles en Python 3):
>>> ":".join(f'{c:02x}' for c in a_string.encode('utf-8'))
'd0:9f:d1:80:d0:b8:d0:b2:d0:b5:d1:82:20:d0:bc:d0:b8:d1:80:21:21'
En Python 2, pase c
al ord
primero, es decir ord(c)
, más ejemplos:
>>> ":".join("{:02x}".format(ord(c)) for c in a_string.encode('utf-8'))
'd0:9f:d1:80:d0:b8:d0:b2:d0:b5:d1:82:20:d0:bc:d0:b8:d1:80:21:21'
>>> ":".join(format(ord(c), '02x') for c in a_string.encode('utf-8'))
'd0:9f:d1:80:d0:b8:d0:b2:d0:b5:d1:82:20:d0:bc:d0:b8:d1:80:21:21'
Puedes usar hexdump
's
import hexdump
hexdump.dump("Hello World", sep=":")
(agregue .lower()
si necesita minúsculas). Esto funciona tanto para Python 2 como para 3.
pip install -U hexdump --proxy http://proxy.address:port
sudo
con pip
, que en mal estado pacman
...
El uso de la función map y lambda puede producir una lista de valores hexadecimales, que pueden imprimirse (o usarse para otros fines)
>>> s = 'Hello 1 2 3 \x01\x02\x03 :)'
>>> map(lambda c: hex(ord(c)), s)
['0x48', '0x65', '0x6c', '0x6c', '0x6f', '0x20', '0x31', '0x20', '0x32', '0x20', '0x33', '0x20', '0x1', '0x2', '0x3', '0x20', '0x3a', '0x29']
[hex(ord(c)) for c in s]
Esto se puede hacer de las siguientes maneras:
from __future__ import print_function
str = "Hello World !!"
for char in str:
mm = int(char.encode('hex'), 16)
print(hex(mm), sep=':', end=' ' )
La salida de esto estará en hexadecimal de la siguiente manera:
0x48 0x65 0x6c 0x6c 0x6f 0x20 0x57 0x6f 0x72 0x6c 0x64 0x20 0x21 0x21
__future__
es una biblioteca estándar disponible en versiones recientes de Python 2 que se puede usar para hacer que las características normalmente solo sean compatibles con Python 3. En esta respuesta, se utiliza para obtener la print(text)
función "función de impresión", que reemplaza la print text
sintaxis de Python 2. Consulte los documentos de Python .
Un poco más general para aquellos que no se preocupan por Python3 o dos puntos:
from codecs import encode
data = open('/dev/urandom', 'rb').read(20)
print(encode(data, 'hex')) # data
print(encode(b"hello", 'hex')) # string
Utilizando base64.b16encode
en python2 (su incorporado)
>>> s = 'Hello world !!'
>>> h = base64.b16encode(s)
>>> ':'.join([h[i:i+2] for i in xrange(0, len(h), 2)]
'48:65:6C:6C:6F:20:77:6F:72:6C:64:20:21:21'
.decode()
?
Solo por conveniencia, muy simple.
def hexlify_byteString(byteString, delim="%"):
''' very simple way to hexlify a bytestring using delimiters '''
retval = ""
for intval in byteString:
retval += ( '0123456789ABCDEF'[int(intval / 16)])
retval += ( '0123456789ABCDEF'[int(intval % 16)])
retval += delim
return( retval[:-1])
hexlify_byteString(b'Hello World!', ":")
# Out[439]: '48:65:6C:6C:6F:20:57:6F:72:6C:64:21'
para algo que ofrece más rendimiento que ''.format()
, puede usar esto:
>>> ':'.join( '%02x'%(v if type(v) is int else ord(v)) for v in 'Hello World !!' )
'48:65:6C:6C:6F:20:77:6F:72:6C:64:20:21:21'
>>>
>>> ':'.join( '%02x'%(v if type(v) is int else ord(v)) for v in b'Hello World !!' )
'48:65:6C:6C:6F:20:77:6F:72:6C:64:20:21:21'
>>>
lo siento, esto no podría verse mejor
sería bueno si uno simplemente pudiera hacerlo '%02x'%v
, pero eso solo requiere int ...
pero estará atrapado con cadenas de bytes b''
sin la lógica para seleccionar ord(v)
.
str
o Python 3bytestring
), ya que no hay transformación inequívoca de un personaje en un entero en 0 ... 255. Por lo tanto, las cadenas de caracteres (Python 2unicode
y Python 3str
) primero requieren algo de codificación antes de ser convertibles en este formato hexadecimal. La respuesta de Aaron Hall ejemplifica esto.