Ich habe diese Zeichenfolge: Hello world !!
und ich möchte sie mit Python als drucken 48:65:6c:6c:6f:20:77:6f:72:6c:64:20:21:21
.
hex()
funktioniert nur für ganze Zahlen.
Wie geht das?
Ich habe diese Zeichenfolge: Hello world !!
und ich möchte sie mit Python als drucken 48:65:6c:6c:6f:20:77:6f:72:6c:64:20:21:21
.
hex()
funktioniert nur für ganze Zahlen.
Wie geht das?
Antworten:
Sie können Ihre Zeichenfolge in einen Int-Generator umwandeln, für jedes Element eine Hex-Formatierung anwenden und mit einem Trennzeichen interkalieren:
>>> 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
als Hex nicht wirklich sinnvoll ist. Sie drucken möchten bytes
Objekt als hex (convert str
zu bytes
durch den Aufruf .encode()
).
":".join("{:02x}".format(ord(c)) for c in 'løl')
Renditen '6c:f8:6c'
, während ":".join("{:02x}".format(c) for c in 'løl'.encode())
die Darstellung korrekt utf-8 erzeugt '6c:c3:b8:6c'
.
":".join("{:04x}".format(ord(c)) for c in s)
(Ersetzen 02x
durch 04x
durch Nullstellen jeder Zahl mit 4 Ziffern) verwenden
':'.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))
einfügen ':'
.
LookupError: 'hex' is not a text encoding; use codecs.encode() to handle arbitrary codecs
Für Python 2.x:
':'.join(x.encode('hex') for x in 'Hello World!')
Der obige Code funktioniert nicht mit Python 3.x , für 3.x funktioniert der folgende Code:
':'.join(hex(ord(x))[2:] for x in 'Hello World!')
Eine weitere Antwort in zwei Zeilen, die für manche möglicherweise leichter zu lesen ist und beim Debuggen von Zeilenumbrüchen oder anderen ungeraden Zeichen in einer Zeichenfolge hilfreich ist:
Für Python 2.7
for character in string:
print character, character.encode('hex')
Für Python 3.7 (nicht in allen Versionen von 3 getestet)
for character in string:
print(character, character.encode('utf-8').hex())
codecs.encode(<bytestring>, "hex")
funktioniert aber.
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||
Einige Ergänzungen zu Fedor Gogolev antworten:
Erstens, wenn die Zeichenfolge Zeichen enthält, deren 'ASCII-Code' unter 10 liegt, werden sie nicht wie erforderlich angezeigt. In diesem Fall sollte das richtige Format sein {: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'
^^
Zweitens, wenn Ihre "Zeichenfolge" in Wirklichkeit eine "Byte-Zeichenfolge" ist - und da der Unterschied in Python 3 von Bedeutung ist -, bevorzugen Sie möglicherweise Folgendes:
>>> 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'
Bitte beachten Sie, dass im obigen Code keine Konvertierung erforderlich ist, da ein Byte-Objekt als "unveränderliche Folge von Ganzzahlen im Bereich 0 <= x <256" definiert ist .
Eine Zeichenfolge als Hex-Bytes drucken?
Die akzeptierte Antwort lautet:
s = "Hello world !!"
":".join("{:02x}".format(ord(c)) for c in s)
kehrt zurück:
'48:65:6c:6c:6f:20:77:6f:72:6c:64:20:21:21'
Die akzeptierte Antwort funktioniert nur, solange Sie Bytes (meistens ASCII-Zeichen) verwenden. Wenn Sie jedoch Unicode verwenden, z.
a_string = u"Привет мир!!" # "Prevyet mir", or "Hello World" in Russian.
Sie müssen irgendwie in Bytes konvertieren.
Wenn Ihr Terminal diese Zeichen nicht akzeptiert, können Sie UTF-8 dekodieren oder die Namen verwenden (damit Sie den Code zusammen mit mir einfügen und ausführen können):
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}"
)
Also sehen wir das:
":".join("{:02x}".format(ord(c)) for c in a_string)
kehrt zurück
'41f:440:438:432:435:442:20:43c:438:440:21:21'
Ein schlechtes / unerwartetes Ergebnis - dies sind die Codepunkte , die zusammen die in Unicode angezeigten Grapheme des Unicode-Konsortiums ergeben, die Sprachen auf der ganzen Welt repräsentieren. Dies ist nicht , wie wir diese Informationen tatsächlich gespeichert werden, so dass es durch andere Quellen interpretiert werden kann, though.
Damit eine andere Quelle diese Daten verwenden kann, müssen wir normalerweise in UTF-8-Codierung konvertieren, um diese Zeichenfolge beispielsweise in Byte auf der Festplatte zu speichern oder in HTML zu veröffentlichen. Daher benötigen wir diese Codierung, um die Codepunkte in die Codeeinheiten von UTF-8 zu konvertieren - in Python 3 ord
wird sie nicht benötigt, da bytes
es sich um iterierbare Ganzzahlen handelt:
>>> ":".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'
Oder vielleicht eleganter mit den neuen F-Strings (nur in Python 3 verfügbar):
>>> ":".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, passieren c
zu ord
ersten, das heißt ord(c)
- weitere Beispiele:
>>> ":".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'
Sie können hexdump
's verwenden
import hexdump
hexdump.dump("Hello World", sep=":")
(anhängen, .lower()
wenn Sie Kleinbuchstaben benötigen). Dies funktioniert sowohl für Python 2 als auch für Python.
pip install -U hexdump --proxy http://proxy.address:port
sudo
mit zu verwenden pip
, was durcheinander gebracht hat pacman
...
Mit der Map- und Lambda-Funktion kann eine Liste von Hex-Werten erstellt werden, die gedruckt (oder für andere Zwecke verwendet) werden können.
>>> 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]
Dies kann auf folgende Arten erfolgen:
from __future__ import print_function
str = "Hello World !!"
for char in str:
mm = int(char.encode('hex'), 16)
print(hex(mm), sep=':', end=' ' )
Die Ausgabe erfolgt in hexadezimaler Form wie folgt:
0x48 0x65 0x6c 0x6c 0x6f 0x20 0x57 0x6f 0x72 0x6c 0x64 0x20 0x21 0x21
__future__
steht eine Standardbibliothek in neueren Versionen von Python 2 zur Verfügung, mit der Funktionen normalerweise nur in Python 3 abwärtskompatibel gemacht werden können. In dieser Antwort wird die print(text)
Funktion "Druckfunktion" abgerufen, die die print text
Syntax von Python 2 ersetzt. Weitere Informationen finden Sie in den Python-Dokumenten .
Ein bisschen allgemeiner für diejenigen, die sich nicht für Python3 oder Doppelpunkte interessieren:
from codecs import encode
data = open('/dev/urandom', 'rb').read(20)
print(encode(data, 'hex')) # data
print(encode(b"hello", 'hex')) # string
Verwendung base64.b16encode
in Python2 (integriert)
>>> 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()
?
Nur zur Vereinfachung, sehr einfach.
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'
Für etwas, das mehr Leistung bietet als ''.format()
, können Sie Folgendes verwenden:
>>> ':'.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'
>>>
Entschuldigung, das könnte nicht schöner aussehen. Es
wäre schön, wenn man es einfach tun könnte '%02x'%v
, aber das dauert nur int ...
aber Sie werden mit Byte-Strings b''
ohne die Logik zur Auswahl stecken bleiben ord(v)
.
str
oder Python 3bytestring
), da in 0… 255 keine eindeutige Umwandlung eines Zeichens in eine Ganzzahl erfolgt. Daher erfordern Zeichenketten (Python 2unicode
und Python 3str
) zunächst eine gewisse Codierung, bevor sie in dieses hexadezimale Format konvertiert werden können. Die Antwort von Aaron Hall veranschaulicht dies.