read - python string to hex




Imprimir uma string como bytes hexadecimais? (8)

Imprimir uma string como bytes hexadecimais?

A resposta aceita dá:

s = "Hello world !!"
":".join("{:02x}".format(ord(c)) for c in s)

retorna:

'48:65:6c:6c:6f:20:77:6f:72:6c:64:20:21:21'

A resposta aceita funciona apenas desde que você use bytes (principalmente caracteres ascii). Mas se você usar unicode, por exemplo:

a_string = u"Привет мир!!" # "Prevyet mir, or "Hello World" in Russian.

Você precisa converter em bytes de alguma forma.

Se o seu terminal não aceita esses caracteres, você pode decodificar a partir do utf-8 ou usar os nomes (assim você pode colar e executar o código junto comigo):

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}"
)

Então vemos que:

":".join("{:02x}".format(ord(c)) for c in a_string)

devolve

'41f:440:438:432:435:442:20:43c:438:440:21:21'

um resultado ruim / inesperado - estes são os pontos de código que se combinam para tornar os grafemas que vemos em unicode, do consórcio unicode - representando idiomas em todo o mundo. Não é assim que nós realmente armazenamos essa informação para que ela possa ser interpretada por outras fontes, no entanto.

Para permitir que outra fonte use esses dados, normalmente precisaríamos converter a codificação utf-8, por exemplo, para salvar essa string em bytes em disco ou para publicar em html. Portanto, precisamos dessa codificação para converter os pontos de código em unidades de código de utf-8 - no Python 3, ord não é necessário porque os bytes são iteráveis ​​de inteiros:

>>> ":".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'

Ou talvez mais elegantemente, usando as novas strings-f (disponíveis apenas no 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'

Em Python 2, passe c para ord primeiro, ie ord(c) - mais exemplos:

>>> ":".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'

Eu tenho essa string: Hello world !! e quero imprimi-lo usando Python como 48:65:6c:6c:6f:20:77:6f:72:6c:64:20:21:21 .

hex() funciona apenas para números inteiros.

Como pode ser feito?


Alguns complementam a resposta de Fedor Gogolev:

Primeiro, se a string contiver caracteres cujo 'código ASCII' esteja abaixo de 10, eles não serão exibidos conforme necessário. Nesse caso, o formato correto deve 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'
                                           ^^

Segundo, se a sua "string" é na realidade uma "string de bytes" - e como a diferença é importante no Python 3 - você pode preferir o seguinte:

>>> 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'

Observe que não há necessidade de conversão no código acima, pois os objetos de bytes são definidos como "uma sequência imutável de números inteiros no intervalo 0 <= x <256" .


Em Python 3:

":".join(c.encode().hex() for c in "Hello world !!")
# 48:65:6c:6c:6f:20:77:6f:72:6c:64:20:21:21

Isso é semelhante à resposta do @Athhete.


Isso pode ser feito das seguintes maneiras:

from __future__ import print_function
str = "Hello World !!"
for char in str:
    mm = int(char.encode('hex'), 16)
    print(hex(mm), sep=':', end=' ' )

A saída deste será em hexadecimal da seguinte forma:

0x48 0x65 0x6c 0x6c 0x6f 0x20 0x57 0x6f 0x72 0x6c 0x64 0x20 0x21 0x21


Para Python 2.x:

':'.join(x.encode('hex') for x in 'Hello World!')

O código acima não funcionará com o Python 3.x , para 3.x, o código abaixo funcionará:

':'.join(hex(ord(x))[2:] for x in 'Hello World!')

Usando base64.b16encode em python2 (seu built-in)

>>> 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'

Você pode transformar sua string em um gerador int, aplicar formatação hexadecimal para cada elemento e intercalar com o 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

Você pode usar o hexdump 's

import hexdump
hexdump.dump("Hello World", sep=":")

(acrescente .lower() se você precisar de minúsculas). Isso funciona para o Python 2 e 3.





ordinal-indicator