Saya memiliki string ini: Hello world !!
dan saya ingin mencetaknya menggunakan Python as 48:65:6c:6c:6f:20:77:6f:72:6c:64:20:21:21
.
hex()
hanya berfungsi untuk bilangan bulat.
Bagaimana itu bisa dilakukan?
Saya memiliki string ini: Hello world !!
dan saya ingin mencetaknya menggunakan Python as 48:65:6c:6c:6f:20:77:6f:72:6c:64:20:21:21
.
hex()
hanya berfungsi untuk bilangan bulat.
Bagaimana itu bisa dilakukan?
Jawaban:
Anda dapat mengubah string Anda menjadi generator int, menerapkan pemformatan hex untuk setiap elemen dan bersinggungan dengan pemisah:
>>> 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
sebagai hex tidak benar-benar masuk akal; Anda ingin mencetak bytes
objek sebagai hex (konversikan str
ke bytes
dengan menelepon .encode()
).
":".join("{:02x}".format(ord(c)) for c in 'løl')
return '6c:f8:6c'
, sementara ":".join("{:02x}".format(c) for c in 'løl'.encode())
menghasilkan representasi utf-8 yang benar '6c:c3:b8:6c'
.
":".join("{:04x}".format(ord(c)) for c in s)
(ganti 02x
dengan 04x
ke-pad nol setiap angka menjadi 4 digit) sebagai gantinya
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))
untuk memasukkan ':'
setelah setiap dua digit hex di dalamnya.
LookupError: 'hex' is not a text encoding; use codecs.encode() to handle arbitrary codecs
Untuk Python 2.x:
':'.join(x.encode('hex') for x in 'Hello World!')
Kode di atas tidak akan berfungsi dengan Python 3.x , untuk 3.x, kode di bawah ini akan berfungsi:
':'.join(hex(ord(x))[2:] for x in 'Hello World!')
Jawaban lain dalam dua baris yang sebagian mungkin lebih mudah dibaca, dan membantu dengan men-debug jeda baris atau karakter aneh lainnya dalam sebuah string:
Untuk Python 2.7
for character in string:
print character, character.encode('hex')
Untuk Python 3.7 (tidak diuji pada semua rilis 3)
for character in string:
print(character, character.encode('utf-8').hex())
codecs.encode(<bytestring>, "hex")
tidak bekerja.
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()+"||")
; (keluar)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||
Beberapa pelengkap jawaban Fedor Gogolev:
Pertama, jika string berisi karakter yang 'kode ASCII' di bawah 10, mereka tidak akan ditampilkan seperti yang diperlukan. Dalam hal itu, format yang benar adalah {: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'
^^
Kedua, jika "string" Anda sebenarnya adalah "byte string" - dan karena perbedaannya penting dalam Python 3 - Anda mungkin lebih suka yang berikut ini:
>>> 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'
Harap perhatikan bahwa tidak perlu konversi dalam kode di atas karena objek byte didefinisikan sebagai "urutan bilangan bulat yang tidak dapat diubah dalam kisaran 0 <= x <256" .
Cetak string sebagai hex byte?
Jawaban yang diterima memberi:
s = "Hello world !!"
":".join("{:02x}".format(ord(c)) for c in s)
pengembalian:
'48:65:6c:6c:6f:20:77:6f:72:6c:64:20:21:21'
Jawaban yang diterima hanya berfungsi selama Anda menggunakan byte (kebanyakan karakter ascii). Tetapi jika Anda menggunakan unicode, misal:
a_string = u"Привет мир!!" # "Prevyet mir", or "Hello World" in Russian.
Anda perlu mengonversi ke byte entah bagaimana.
Jika terminal Anda tidak menerima karakter ini, Anda dapat mendekode dari UTF-8 atau menggunakan nama (sehingga Anda dapat menempel dan menjalankan kode bersama dengan saya):
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}"
)
Jadi kita melihat bahwa:
":".join("{:02x}".format(ord(c)) for c in a_string)
kembali
'41f:440:438:432:435:442:20:43c:438:440:21:21'
hasil yang buruk / tidak terduga - ini adalah poin kode yang bergabung untuk membuat grafik yang kita lihat di Unicode, dari Konsorsium Unicode - mewakili bahasa di seluruh dunia. Namun, ini bukan cara kami menyimpan informasi ini sehingga dapat ditafsirkan oleh sumber lain.
Untuk mengizinkan sumber lain menggunakan data ini, kita biasanya perlu mengonversi ke pengkodean UTF-8, misalnya, untuk menyimpan string ini dalam byte ke disk atau untuk mempublikasikan ke html. Jadi kita memerlukan pengkodean untuk mengonversi titik kode ke unit kode UTF-8 - dengan Python 3, ord
tidak diperlukan karena bytes
iterables bilangan bulat:
>>> ":".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'
Atau mungkin lebih elegan, menggunakan f-string baru (hanya tersedia di 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'
Dalam Python 2, beralih c
ke yang ord
pertama, yaitu ord(c)
- lebih banyak contoh:
>>> ":".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'
Anda dapat menggunakan hexdump
's
import hexdump
hexdump.dump("Hello World", sep=":")
(tambahkan .lower()
jika Anda membutuhkan huruf kecil). Ini berfungsi baik untuk Python 2 & 3.
pip install -U hexdump --proxy http://proxy.address:port
sudo
dengan menggunakan pip
, yang mengacaukan pacman
...
Menggunakan fungsi peta dan lambda dapat menghasilkan daftar nilai hex, yang dapat dicetak (atau digunakan untuk tujuan lain)
>>> 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]
Ini dapat dilakukan dengan cara-cara berikut:
from __future__ import print_function
str = "Hello World !!"
for char in str:
mm = int(char.encode('hex'), 16)
print(hex(mm), sep=':', end=' ' )
Output dari ini adalah dalam hex sebagai berikut:
0x48 0x65 0x6c 0x6c 0x6f 0x20 0x57 0x6f 0x72 0x6c 0x64 0x20 0x21 0x21
__future__
adalah pustaka standar yang tersedia dalam versi terbaru dari Python 2 yang dapat digunakan untuk membuat fitur-fitur yang biasanya hanya di Python 3 kompatibel dengan mundur. Dalam jawaban ini, ini digunakan untuk mendapatkan fitur print(text)
"fungsi cetak", yang menggantikan print text
sintaks dari Python 2. Lihat dokumen Python .
Sedikit lebih umum bagi mereka yang tidak peduli tentang Python3 atau titik dua:
from codecs import encode
data = open('/dev/urandom', 'rb').read(20)
print(encode(data, 'hex')) # data
print(encode(b"hello", 'hex')) # string
Menggunakan base64.b16encode
di python2 ( bawaannya )
>>> 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()
?
Hanya untuk kenyamanan, sangat sederhana.
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'
untuk sesuatu yang menawarkan lebih banyak kinerja daripada ''.format()
, Anda dapat menggunakan ini:
>>> ':'.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'
>>>
maaf ini tidak bisa terlihat lebih bagus
akan lebih baik jika seseorang bisa melakukannya '%02x'%v
, tetapi itu hanya membutuhkan int ...
tetapi Anda akan terjebak dengan byte-string b''
tanpa logika untuk memilih ord(v)
.
str
atau Python 3bytestring
), karena tidak ada transformasi tegas karakter ke dalam integer di 0 ... 255. Dengan demikian, karakter string (Python 2unicode
dan Python 3str
) pertama-tama memerlukan beberapa pengkodean sebelum dapat dikonversi dalam format heksadesimal ini. Jawaban Aaron Hall mencontohkan ini.