Ho questa stringa: Hello world !!
e voglio stamparla usando Python come 48:65:6c:6c:6f:20:77:6f:72:6c:64:20:21:21
.
hex()
funziona solo per numeri interi.
Come si può fare?
Ho questa stringa: Hello world !!
e voglio stamparla usando Python come 48:65:6c:6c:6f:20:77:6f:72:6c:64:20:21:21
.
hex()
funziona solo per numeri interi.
Come si può fare?
Risposte:
Puoi trasformare la tua stringa in un generatore int, applicare la formattazione esadecimale per ciascun elemento e intercalare con il separatore:
>>> 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
as hex non ha davvero senso; ti consigliamo di stampare l' bytes
oggetto come esadecimale (converti str
in bytes
chiamando .encode()
).
":".join("{:02x}".format(ord(c)) for c in 'løl')
rendimenti '6c:f8:6c'
, mentre ":".join("{:02x}".format(c) for c in 'løl'.encode())
produce la corretta rappresentazione utf-8 '6c:c3:b8:6c'
.
":".join("{:04x}".format(ord(c)) for c in s)
(sostituendo 02x
con 04x
zero-pad ogni numero per essere composto da 4 cifre)
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))
da inserire ':'
dopo ogni due cifre esadecimali.
LookupError: 'hex' is not a text encoding; use codecs.encode() to handle arbitrary codecs
Per Python 2.x:
':'.join(x.encode('hex') for x in 'Hello World!')
Il codice sopra non funzionerà con Python 3.x , per 3.x, il codice qui sotto funzionerà:
':'.join(hex(ord(x))[2:] for x in 'Hello World!')
Un'altra risposta in due righe che alcuni potrebbero trovare più facili da leggere e aiuta con il debug delle interruzioni di riga o di altri caratteri dispari in una stringa:
Per Python 2.7
for character in string:
print character, character.encode('hex')
Per Python 3.7 (non testato su tutte le versioni di 3)
for character in string:
print(character, character.encode('utf-8').hex())
codecs.encode(<bytestring>, "hex")
funziona, però.
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()+"||")
; (fuori)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||
Alcuni complementi di Fedor Gogolev rispondono:
Innanzitutto, se la stringa contiene caratteri il cui "codice ASCII" è inferiore a 10, non verranno visualizzati come richiesto. In tal caso, il formato corretto dovrebbe essere {: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'
^^
In secondo luogo, se la tua "stringa" è in realtà una "stringa di byte" - e poiché la differenza è importante in Python 3 - potresti preferire quanto segue:
>>> 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'
Si noti che non è necessario eseguire la conversione nel codice sopra poiché oggetti byte sono definiti come "una sequenza immutabile di numeri interi nell'intervallo 0 <= x <256" .
Stampa una stringa come byte esadecimali?
La risposta accettata dà:
s = "Hello world !!"
":".join("{:02x}".format(ord(c)) for c in s)
ritorna:
'48:65:6c:6c:6f:20:77:6f:72:6c:64:20:21:21'
La risposta accettata funziona solo finché si utilizzano byte (principalmente caratteri ASCII). Ma se usi unicode, ad esempio:
a_string = u"Привет мир!!" # "Prevyet mir", or "Hello World" in Russian.
È necessario convertire in byte in qualche modo.
Se il tuo terminale non accetta questi caratteri, puoi decodificare da UTF-8 o usare i nomi (così puoi incollare ed eseguire il codice insieme a me):
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}"
)
Quindi vediamo che:
":".join("{:02x}".format(ord(c)) for c in a_string)
ritorna
'41f:440:438:432:435:442:20:43c:438:440:21:21'
un risultato scarso / imprevisto: questi sono i punti di codice che si combinano per creare i grafemi che vediamo in Unicode, dal consorzio Unicode, che rappresentano le lingue di tutto il mondo. Questo non lo è il modo in cui effettivamente memorizzare queste informazioni in modo che possa essere interpretato da altre fonti, però.
Per consentire a un'altra fonte di utilizzare questi dati, di solito dovremmo convertire in codifica UTF-8, ad esempio, per salvare questa stringa in byte su disco o per pubblicare in html. Quindi abbiamo bisogno che la codifica per convertire i punti di codice nelle unità di codice di UTF-8 - in Python 3, ord
non sia necessaria perché bytes
sono iterabili di numeri interi:
>>> ":".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 forse più elegantemente, usando le nuove stringhe f (disponibili solo in 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'
In Python 2, passa c
al ord
primo, ovvero ord(c)
- altri esempi:
>>> ":".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'
Puoi usare hexdump
's
import hexdump
hexdump.dump("Hello World", sep=":")
(aggiungi .lower()
se hai bisogno di lettere minuscole). Funziona con Python 2 e 3.
pip install -U hexdump --proxy http://proxy.address:port
sudo
con pip
, che ha incasinato pacman
...
L'uso della funzione map e lambda può produrre un elenco di valori esadecimali, che possono essere stampati (o utilizzati per altri scopi)
>>> 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]
Questo può essere fatto nei seguenti modi:
from __future__ import print_function
str = "Hello World !!"
for char in str:
mm = int(char.encode('hex'), 16)
print(hex(mm), sep=':', end=' ' )
L'output di questo sarà in esadecimale come segue:
0x48 0x65 0x6c 0x6c 0x6f 0x20 0x57 0x6f 0x72 0x6c 0x64 0x20 0x21 0x21
__future__
è disponibile una libreria standard nelle ultime versioni di Python 2 che può essere utilizzata per rendere le funzionalità normalmente compatibili solo con Python 3. In questa risposta, viene utilizzato per ottenere la print(text)
funzione "funzione di stampa", che sostituisce la print text
sintassi di Python 2. Vedi i documenti di Python .
Un po 'più generale per coloro a cui non interessa Python3 o due punti:
from codecs import encode
data = open('/dev/urandom', 'rb').read(20)
print(encode(data, 'hex')) # data
print(encode(b"hello", 'hex')) # string
Usando base64.b16encode
in python2 (il suo 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'
.decode()
?
Solo per comodità, molto semplice.
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'
per qualcosa che offre più prestazioni di ''.format()
, puoi usare questo:
>>> ':'.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'
>>>
mi dispiace che questo non possa apparire più bello
sarebbe bello se si potesse semplicemente fare '%02x'%v
, ma ci vuole solo int ...
ma rimarrai bloccato con stringhe di byte b''
senza la logica da selezionare ord(v)
.
str
o Python 3bytestring
), poiché non esiste una trasformazione inequivocabile di un carattere in un numero intero in 0 ... 255. Pertanto, le stringhe di caratteri (Python 2unicode
e Python 3str
) richiedono prima un po 'di codifica prima di essere convertibili in questo formato esadecimale. La risposta di Aaron Hall ne è un esempio.