हेक्स बाइट्स के रूप में एक स्ट्रिंग प्रिंट करें?


155

मेरे पास यह स्ट्रिंग है: Hello world !!और मैं इसे पायथन का उपयोग करके प्रिंट करना चाहता हूं 48:65:6c:6c:6f:20:77:6f:72:6c:64:20:21:21

hex() केवल पूर्णांकों के लिए काम करता है।

यह कैसे किया जा सकता है?


यदि विचार केवल 2-अंकीय हेक्स मानों को वापस करने के लिए है, तो यह प्रश्न बाइट स्ट्रिंग्स (यानी पायथन 2 strया पायथन 3 bytestring) के उपयोग का तात्पर्य है , क्योंकि 0 में एक पूर्णांक में वर्ण का असमान परिवर्तन नहीं है: 255। इस प्रकार, चरित्र स्ट्रिंग्स (पायथन 2 unicodeऔर पायथन 3 str) को पहले इस हेक्साडेसिमल प्रारूप में परिवर्तनीय होने से पहले कुछ एन्कोडिंग की आवश्यकता होती है। हारून हॉल का जवाब इसका उदाहरण देता है।
एरिक ओ लेबिगॉट

जवाबों:


227

आप अपनी स्ट्रिंग को एक इंटर्न जनरेटर में बदल सकते हैं, प्रत्येक तत्व के लिए हेक्स फॉर्मेटिंग लागू कर सकते हैं और विभाजक के साथ जुड़ सकते हैं:

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

3
ध्यान दें कि python3 में, strहेक्स के रूप में मुद्रण की अवधारणा वास्तव में कोई मतलब नहीं है; आप bytesऑब्जेक्ट को हेक्स के रूप में प्रिंट करना चाहते हैं ( कॉल करके परिवर्तित strकरें )। bytes.encode()
mic_e

8
वास्तव में, यह python3 में अमान्य आउटपुट उत्पन्न करता है: ":".join("{:02x}".format(ord(c)) for c in 'løl')रिटर्न '6c:f8:6c', जबकि ":".join("{:02x}".format(c) for c in 'løl'.encode())सही utf-8 प्रतिनिधित्व का उत्पादन करता है '6c:c3:b8:6c'
mic_e

2
यह प्रश्न और उत्तर की तरह लगता है कि आपके इनपुट में कभी भी गैर-एएससीआईआई अक्षर नहीं हैं। यदि आपके इनपुट में इमोजीस या गैर-लैटिन आधारित लेखन प्रणाली जैसी चीजें शामिल हो सकती हैं, तो आप उपयोग करना चाहते हैं ":".join("{:04x}".format(ord(c)) for c in s)( प्रत्येक संख्या को 4-अंक होने के लिए शून्य-पैड के 02xसाथ बदल सकते हैं 04x)
बोरिस

@mic_e यह क्यों है? जब आप एम्बेडेड दुभाषिया में इसे आज़माते हैं, तो स्केपी इस का संदर्भ देता है। WARNING: Calling str(pkt) on Python 3 makes no sense!
sherrellbc

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

3
Python3 में यह कैसे करें?
h__

6
@ क्यों: इसमें प्रत्येक दो हेक्स अंकों के बाद h = binascii.hexlify(b"Hello world !!") to get hex string. b":".join(h[i:i+2] for i in range(0, len(h), 2))डालने के लिए ':'
jfs

2
पायथन 3 पर काम नहीं करता हैLookupError: 'hex' is not a text encoding; use codecs.encode() to handle arbitrary codecs
बोरिस

55

अजगर के लिए 2.x:

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

उपरोक्त कोड 3.x के लिए पायथन 3.x के साथ काम नहीं करेगा , नीचे दिया गया कोड काम करेगा:

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

1
यह भी ध्यान दिया जाना चाहिए, कि बाद में भी python2.x के साथ ALSO काम करेगा और यह गैर-
अस्की

1
लेकिन यह भी ध्यान दें कि उत्तरार्द्ध अग्रणी शून्य को पैड नहीं करता है: हेक्स (ord ("\ x00")) [2:] "0" और "\ x00" है ।encode ("हेक्स") == "00"
डेनियल।

3
इन दोनों समाधानों को अन्य उपयोगकर्ताओं द्वारा पेश किए जाने के महीनों बाद आपने इसे एक नए उत्तर के रूप में पोस्ट करने का निर्णय क्यों लिया? यदि बिंदु संस्करण संगतता को स्पष्ट करने के लिए था, तो यह मौजूदा उत्तरों के लिए संपादन का सुझाव देने के लिए अधिक समझ में आता था।
एयर

2
जैसा कि कहीं और उल्लेख किया गया है, यह उत्तर एक बार भी सही नहीं है क्योंकि एक एससीआई से आगे बढ़ता है और यूनिकोड मानता है। ':'। join (hex (ord) (x)) [2:] in x for 'løl') गलत तरीके से प्रिंट करता है '6c: f8: 6c' जबकि सही आउटपुट '6c: c3: b8: 6c' है।
mcduffee

23

दो पंक्तियों में एक और जवाब जो कुछ पढ़ने में आसान लग सकता है, और एक स्ट्रिंग में डिबगिंग लाइन टूटने या अन्य विषम पात्रों के साथ मदद करता है:

पायथन 2.7 के लिए

for character in string:
    print character, character.encode('hex')

पायथॉन 3.7 के लिए (3 के सभी रिलीज पर परीक्षण नहीं किया गया)

for character in string:
    print(character, character.encode('utf-8').hex())

यह पायथन 3.6.8 (कम से कम) के रूप में काम नहीं करता है: "हेक्स" तार का एक एन्कोडिंग नहीं है। codecs.encode(<bytestring>, "hex")हालांकि काम करता है।
एरिक ओ लेबिगॉट

2
आह, इस जानकारी के लिए अच्छा धन्यवाद ... हाँ, यह निश्चित रूप से पायथन 2.7 के लिए लिखा गया था। मैं पायथन 3.7 के लिए यह करने के लिए कैसे शामिल करने के लिए अपने जवाब को अपडेट करूंगा।
कोपलैंड 3300

सत्यापित, पायथन 3.7.6 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()+"||"); (आउट)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||
बबलडवे ०२५

20

फेडर गोगोलेव के जवाब के लिए कुछ पूरक:

पहला, यदि स्ट्रिंग में ऐसे अक्षर हैं जिनका 'ASCII कोड' 10 से नीचे है, तो उन्हें आवश्यकतानुसार प्रदर्शित नहीं किया जाएगा। उस स्थिति में, सही प्रारूप होना चाहिए {: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'
                                           ^^

दूसरा, यदि आपका "स्ट्रिंग" वास्तव में "बाइट स्ट्रिंग" है - और चूंकि पायथन 3 में अंतर मायने रखता है - आप निम्नलिखित को पसंद कर सकते हैं:

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

कृपया ध्यान दें कि उपरोक्त कोड में रूपांतरण की कोई आवश्यकता नहीं है क्योंकि बाइट्स ऑब्जेक्ट को "रेंज 0 में पूर्णांक का अपरिवर्तनीय अनुक्रम" के रूप में परिभाषित किया गया है ।


11

हेक्स बाइट्स के रूप में एक स्ट्रिंग प्रिंट करें?

स्वीकृत उत्तर देता है:

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'

स्वीकृत उत्तर केवल इतने लंबे समय तक काम करता है जब तक आप बाइट्स (ज्यादातर एस्की अक्षर) का उपयोग करते हैं। लेकिन अगर आप यूनिकोड का उपयोग करते हैं, जैसे:

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

आपको किसी तरह बाइट में बदलने की आवश्यकता है।

यदि आपका टर्मिनल इन पात्रों को स्वीकार नहीं करता है, तो आप UTF-8 से डीकोड कर सकते हैं या नामों का उपयोग कर सकते हैं (ताकि आप मेरे साथ कोड पेस्ट और चला सकें):

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

तो हम देखते हैं कि:

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

रिटर्न

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

एक खराब / अप्रत्याशित परिणाम - ये कोड बिंदु हैं जो कि यूनिकोड में हमारे द्वारा देखे गए अंगूर बनाने के लिए यूनिकोड कंसोर्टियम से - दुनिया भर की भाषाओं का प्रतिनिधित्व करते हैं। यह नहीं है कि हम वास्तव में इस जानकारी को कैसे संग्रहीत करते हैं, इसलिए इसकी व्याख्या अन्य स्रोतों से की जा सकती है, हालांकि।

इस डेटा का उपयोग करने के लिए किसी अन्य स्रोत की अनुमति देने के लिए, हमें आमतौर पर UTF-8 एन्कोडिंग में बदलने की आवश्यकता होगी, उदाहरण के लिए, इस स्ट्रिंग को बाइट्स में डिस्क पर सहेजने के लिए या html में प्रकाशित करने के लिए। इसलिए हमें कोड अंक को यूटीएफ -8 की कोड इकाइयों में परिवर्तित करने की आवश्यकता है - पायथन 3 में, पूर्णांक के पुनरावृत्तियों की ordआवश्यकता नहीं है bytes:

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

या शायद अधिक शान से, नए f- स्ट्रिंग्स का उपयोग करके (केवल पायथन 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'

पायथन 2 में, पहले पास cकरें ord, अर्थात ord(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'

1
@ not2qubit कृपया इन उदाहरणों को फिर से आज़माएं - मैंने पायथन 2 और 3 के बीच के अंतरों को दूर करने के लिए थोड़ा समय लिया, और जाहिर है मैंने मूल रूप से केवल पायथन 2 के लिए ये लिखा था। और QA'ing के लिए धन्यवाद मेरा जवाब!
हारून हॉल

हाँ, यह किया है। धन्यवाद!
नॉटआउट २२

8

आप उपयोग कर सकते हैं hexdumpकी

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

( .lower()अगर आपको लोअर-केस की आवश्यकता हो तो अपीयर करें )। यह पायथन 2 और 3 दोनों के लिए काम करता है।


इसके अलावा एक समस्या मैं भाग गया, अगर आपको हेक्सडम्प या किसी अन्य पैकेज को स्थापित करने में समस्या है, तो यह सामान्य है क्योंकि प्रॉक्सी सेटिंग्स प्रॉक्सी विकल्प के साथ पाइप चलाने की कोशिश करती हैं pip install -U hexdump --proxy http://proxy.address:port
एडुआर्ड फ्लोरिंसक्यू

वास्तव में मैं के sudoसाथ प्रयोग करने की गलती की है pip, जो गड़बड़ कर दी pacman...
Tobias Kienzler

6

मानचित्र और लैम्ब्डा फ़ंक्शन का उपयोग करके हेक्स मानों की एक सूची तैयार की जा सकती है, जिसे मुद्रित किया जा सकता है (या अन्य प्रयोजनों के लिए उपयोग किया जाता है)

>>> 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]
बोरिस

2

यह निम्नलिखित तरीकों से किया जा सकता है:

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

इसका उत्पादन निम्नानुसार हेक्स में होगा:

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


मुझे भविष्य
tofutim

भविष्य के संदर्भ के लिए, __future__पायथन 2 के हाल के संस्करणों में उपलब्ध एक मानक पुस्तकालय है जिसका उपयोग केवल पायथन 3 के पीछे-संगत में सामान्य रूप से सुविधाएँ बनाने के लिए किया जा सकता है। इस उत्तर में, इसका उपयोग print(text)"प्रिंट फ़ंक्शन" सुविधा प्राप्त करने के लिए किया जाता है , जो कि print textपायथन से वाक्यविन्यास को बदलता है 2. पायथन डॉक्स देखें ।
एरिक रीड

2

उन लोगों के लिए थोड़ा और सामान्य है जो पायथन 3 या कॉलोनों की परवाह नहीं करते हैं:

from codecs import encode

data = open('/dev/urandom', 'rb').read(20)
print(encode(data, 'hex'))      # data

print(encode(b"hello", 'hex'))  # string

0

का प्रयोग base64.b16encodeमें को Python2 (अपने में निर्मित)

>>> 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()?
14

0

बस सुविधा के लिए, बहुत सरल।

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'

0

किसी ऐसी चीज़ के लिए, जो इससे अधिक प्रदर्शन प्रदान करती है ''.format(), आप इसका उपयोग कर सकते हैं:

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

खेद है कि यह अच्छा नहीं लग
सकता है यदि कोई व्यक्ति बस कर सकता है '%02x'%v, लेकिन यह केवल int लेता है ...
लेकिन आप b''बिना तर्क के बाइट-स्ट्रिंग्स के साथ चयन करने के लिए फंस जाएंगे ord(v)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.