Tôi có chuỗi này: Hello world !!
và tôi muốn in nó bằng Python 48:65:6c:6c:6f:20:77:6f:72:6c:64:20:21:21
.
hex()
chỉ hoạt động cho số nguyên.
Nó được hoàn thiện bằng cách nào?
Tôi có chuỗi này: Hello world !!
và tôi muốn in nó bằng Python 48:65:6c:6c:6f:20:77:6f:72:6c:64:20:21:21
.
hex()
chỉ hoạt động cho số nguyên.
Nó được hoàn thiện bằng cách nào?
Câu trả lời:
Bạn có thể chuyển đổi chuỗi của mình thành trình tạo int, áp dụng định dạng hex cho từng thành phần và xen kẽ với dấu phân cách:
>>> 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
dưới dạng hex không thực sự có ý nghĩa; bạn sẽ muốn in bytes
đối tượng dưới dạng hex (chuyển đổi str
sang bytes
bằng cách gọi .encode()
).
":".join("{:02x}".format(ord(c)) for c in 'løl')
return '6c:f8:6c'
, trong khi ":".join("{:02x}".format(c) for c in 'løl'.encode())
tạo ra đại diện utf-8 chính xác '6c:c3:b8:6c'
.
":".join("{:04x}".format(ord(c)) for c in s)
(thay thế 02x
bằng 04x
số 0 mỗi số thành 4 chữ số) thay vào đó
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))
để chèn ':'
sau mỗi hai chữ số hex trong đó.
LookupError: 'hex' is not a text encoding; use codecs.encode() to handle arbitrary codecs
Đối với Python 2.x:
':'.join(x.encode('hex') for x in 'Hello World!')
Mã ở trên sẽ không hoạt động với Python 3.x , đối với 3.x, mã bên dưới sẽ hoạt động:
':'.join(hex(ord(x))[2:] for x in 'Hello World!')
Một câu trả lời khác trong hai dòng mà một số người có thể thấy dễ đọc hơn và giúp gỡ lỗi ngắt dòng hoặc các ký tự kỳ lạ khác trong chuỗi:
Đối với Python 2.7
for character in string:
print character, character.encode('hex')
Đối với Python 3.7 (không được thử nghiệm trên tất cả các bản phát hành của 3)
for character in string:
print(character, character.encode('utf-8').hex())
codecs.encode(<bytestring>, "hex")
không hoạt động, mặc dù.
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()+"||")
; (ra)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||
Một số bổ sung cho câu trả lời của Fedor Gogolev:
Đầu tiên, nếu chuỗi chứa các ký tự có 'mã ASCII' dưới 10, chúng sẽ không được hiển thị theo yêu cầu. Trong trường hợp đó, định dạng đúng phải là {: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'
^^
Thứ hai, nếu "chuỗi" của bạn trong thực tế là "chuỗi byte" - và vì sự khác biệt quan trọng trong Python 3 - bạn có thể thích những điều sau:
>>> 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'
Xin lưu ý rằng không cần chuyển đổi trong đoạn mã trên vì các đối tượng byte được định nghĩa là "một chuỗi số nguyên bất biến trong phạm vi 0 <= x <256" .
In một chuỗi dưới dạng byte hex?
Câu trả lời được chấp nhận cho:
s = "Hello world !!"
":".join("{:02x}".format(ord(c)) for c in s)
trả về:
'48:65:6c:6c:6f:20:77:6f:72:6c:64:20:21:21'
Câu trả lời được chấp nhận chỉ hoạt động miễn là bạn sử dụng byte (chủ yếu là ký tự ascii). Nhưng nếu bạn sử dụng unicode, vd:
a_string = u"Привет мир!!" # "Prevyet mir", or "Hello World" in Russian.
Bạn cần phải chuyển đổi sang byte bằng cách nào đó.
Nếu thiết bị đầu cuối của bạn không chấp nhận các ký tự này, bạn có thể giải mã từ UTF-8 hoặc sử dụng tên (để bạn có thể dán và chạy mã cùng với tôi):
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}"
)
Vì vậy, chúng tôi thấy rằng:
":".join("{:02x}".format(ord(c)) for c in a_string)
trả lại
'41f:440:438:432:435:442:20:43c:438:440:21:21'
một kết quả kém / bất ngờ - đây là những điểm mã kết hợp để tạo ra các biểu đồ mà chúng ta thấy trong Unicode, từ Hiệp hội Unicode - đại diện cho các ngôn ngữ trên toàn thế giới. Đây không phải là cách chúng tôi thực sự lưu trữ thông tin này để nó có thể được giải thích bởi các nguồn khác.
Để cho phép một nguồn khác sử dụng dữ liệu này, chúng ta thường cần phải chuyển đổi sang mã hóa UTF-8, ví dụ, để lưu chuỗi này theo byte vào đĩa hoặc xuất bản thành html. Vì vậy, chúng ta cần mã hóa đó để chuyển đổi các điểm mã thành các đơn vị mã của UTF-8 - trong Python 3, ord
không cần thiết bởi vì bytes
có thể lặp lại các số nguyên:
>>> ":".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'
Hoặc có lẽ thanh lịch hơn, sử dụng chuỗi f mới (chỉ có sẵn trong 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'
Trong Python 2, chuyển c
đến ord
đầu tiên, tức là ord(c)
- ví dụ khác:
>>> ":".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'
Bạn có thể sử dụng hexdump
's
import hexdump
hexdump.dump("Hello World", sep=":")
(chắp thêm .lower()
nếu bạn yêu cầu chữ thường). Điều này hoạt động cho cả Python 2 & 3.
pip install -U hexdump --proxy http://proxy.address:port
sudo
với pip
, mà sai lầm pacman
...
Sử dụng chức năng map và lambda có thể tạo ra một danh sách các giá trị hex, có thể được in (hoặc được sử dụng cho các mục đích khác)
>>> 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]
Điều này có thể được thực hiện theo những cách sau:
from __future__ import print_function
str = "Hello World !!"
for char in str:
mm = int(char.encode('hex'), 16)
print(hex(mm), sep=':', end=' ' )
Đầu ra của cái này sẽ ở dạng hex như sau:
0x48 0x65 0x6c 0x6c 0x6f 0x20 0x57 0x6f 0x72 0x6c 0x64 0x20 0x21 0x21
__future__
là một thư viện tiêu chuẩn có sẵn trong các phiên bản gần đây của Python 2 có thể được sử dụng để làm cho các tính năng thường chỉ tương thích với Python 3 tương thích ngược. Trong câu trả lời này, nó được sử dụng để có được print(text)
tính năng "chức năng in", thay thế print text
cú pháp từ Python 2. Xem tài liệu Python .
Nói chung hơn một chút cho những người không quan tâm đến Python3 hoặc dấu hai chấm:
from codecs import encode
data = open('/dev/urandom', 'rb').read(20)
print(encode(data, 'hex')) # data
print(encode(b"hello", 'hex')) # string
Sử dụng base64.b16encode
trong python2 (tích hợp sẵn)
>>> 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()
?
Chỉ để thuận tiện, rất đơn giản.
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'
đối với một cái gì đó cung cấp hiệu suất cao hơn ''.format()
, bạn có thể sử dụng điều này:
>>> ':'.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'
>>>
xin lỗi, điều này không thể đẹp hơn
nếu người ta có thể làm một cách đơn giản '%02x'%v
, nhưng điều đó chỉ mất int ...
nhưng bạn sẽ bị mắc kẹt với chuỗi byte b''
mà không có logic để chọn ord(v)
.
str
hoặc Python 3bytestring
), vì không có sự biến đổi không rõ ràng của một ký tự thành một số nguyên trong 0 0 255. Do đó, các chuỗi ký tự (Python 2unicode
và Python 3str
) trước tiên yêu cầu một số mã hóa trước khi có thể chuyển đổi theo định dạng thập lục phân này. Câu trả lời của Aaron Hall minh họa điều này.