হেক্স বাইট হিসাবে একটি স্ট্রিং মুদ্রণ করবেন?


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
দ্রষ্টব্য যে পাইথন 3-তে, strহেক্স হিসাবে মুদ্রণের ধারণাটি আসলেই বোঝায় না; আপনি মুদ্রণ করতে চাইবেন bytes(ধর্মান্তরিত হেক্স হিসাবে বস্তুর strকরার bytesকল করে .encode())।
mic_e

8
প্রকৃতপক্ষে, এটি পাইথন 3: ":".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)(প্রতিস্থাপন 02xসঙ্গে 04xপরিবর্তে শূন্য প্যাড প্রতিটি নম্বরে 4 সংখ্যার হতে করার জন্য)
বরিস

@mic_e কেন এটি? যখন আপনি এম্বেড থাকা দোভাষীতে চেষ্টা করেন তখন স্ক্যাপি এটিকে একটি উল্লেখ করে। WARNING: Calling str(pkt) on Python 3 makes no sense!
শেরেলবিসি

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

3
পাইথন 3 এ এটি কীভাবে করবেন?
এইচ__

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

পাইথন ২.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
এটিও লক্ষ করা উচিত, পরবর্তীতে অজগর 2.x এর সাথেও কাজ করবে এবং এটি অ-
এসিআই

1
তবে আরও মনে রাখবেন যে পরবর্তীকৃত নেতারা জিরোগুলিকে প্যাড করে না: হেক্স (অর্ড ("\ x00")) [2:] হ'ল "0" এবং "\ x00"। এনকোড ("হেক্স") == "00"
উইল ড্যানিয়েলস

3
এই উভয় সমাধানের অন্যান্য ব্যবহারকারীদের দ্বারা প্রস্তাবিত হওয়ার কয়েক মাস পরে, আপনি কেন এটি একটি নতুন উত্তর হিসাবে পোস্ট করার সিদ্ধান্ত নিয়েছিলেন? যদি বিন্দুটি সংস্করণের সামঞ্জস্যতা স্পষ্ট করতে পারে তবে বিদ্যমান উত্তরগুলিতে সম্পাদনাগুলি বোঝাতে এটি আরও অর্থপূর্ণ হয়ে উঠত।
এয়ার

2
অন্য কোথাও উল্লিখিত হিসাবে, একবার উত্তর একবার অ্যাস্কির বাইরে চলে গেলে এবং ইউনিকোড বিবেচনা করে। ':'। join (হেক্স (অর্ড (এক্স)) [2:] এক্স এর জন্য '' লালের ') ভুলভাবে' 6c: f8: 6c 'মুদ্রণ করা হয় যখন সঠিক আউটপুট' 6c: c3: b8: 6c 'হয়।
এমসিডুফি

23

দুটি লাইনে আরেকটি উত্তর যা কারও কারও পক্ষে পড়া সহজতর হতে পারে এবং ডিবাগিং লাইন ব্রেক বা স্ট্রিংয়ের অন্যান্য বিজোড় অক্ষরগুলির সাথে সহায়তা করে:

পাইথন ২.7 এর জন্য

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

পাইথন ৩.7 এর জন্য (3 টির সমস্ত রিলিজ পরীক্ষা করা হয়নি)

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

এটি পাইথন 3.6.8 (কমপক্ষে) হিসাবে কাজ করে না: "হেক্স" স্ট্রিংগুলির এনকোডিং নয়। codecs.encode(<bytestring>, "hex")কাজ করে, যদিও।
এরিক হে লেবিগোট

2
আহ, তথ্যের জন্য দুর্দান্ত ধন্যবাদ ... হ্যাঁ এটি অবশ্যই পাইথন ২.7 এর জন্য লেখা হয়েছিল। পাইথন ৩.7-এ এটি কীভাবে করা যায় তা অন্তর্ভুক্ত করার জন্য আমি আমার উত্তর আপডেট করব।
copeland3300

যাচাইকৃত, পাইথন 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||
বুবল্ডেভে025

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 <= x <256 পরিসরে পূর্ণসংখ্যার একটি পরিবর্তনীয় ক্রম " হিসাবে সংজ্ঞায়িত করা হয়েছে ।


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.

আপনাকে কোনওভাবে বাইটে রূপান্তর করতে হবে।

যদি আপনার টার্মিনাল এই অক্ষরগুলি গ্রহণ করে না, আপনি ইউটিএফ -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'

একটি দুর্বল / অপ্রত্যাশিত ফলাফল - এই ইউনিকোড কনসোর্টিয়াম থেকে আমরা ইউনিকোডে দেখি গ্রাফেমগুলি তৈরি করার জন্য কোড পয়েন্টগুলি রয়েছে - সারা বিশ্ব জুড়ে ভাষার প্রতিনিধিত্ব করে। আমরা আসলে এই তথ্যটি কীভাবে সংরক্ষণ করি তা নয় তাই এটি অন্যান্য উত্স দ্বারা ব্যাখ্যা করা যায়।

অন্য কোনও উত্সকে এই ডেটা ব্যবহার করার অনুমতি দেওয়ার জন্য, আমাদের সাধারণত ইউটিএফ -8 এনকোডিংয়ে রূপান্তর করতে হবে, উদাহরণস্বরূপ, এই স্ট্রিংটি বাইটে ডিস্কে সংরক্ষণ করতে বা এইচটিএমএল এ প্রকাশ করতে হবে। সুতরাং পাইথন 3-তে ইউটিএফ -8 এর কোড ইউনিটগুলিতে কোড পয়েন্টগুলিতে রূপান্তর করতে আমাদের এনকোডিং দরকার - 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'

অথবা আরও মার্জিতভাবে, নতুন এফ-স্ট্রিংগুলি ব্যবহার করে (কেবল পাইথন 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-র জন্য লিখেছিলাম এবং আমার উত্তরটি কিউ করার জন্য ধন্যবাদ!
অ্যারন হল

হ্যাঁ, এটা এটা করেছে। ধন্যবাদ!
not2qubit

8

আপনি ব্যবহার করতে পারেন hexdump'র

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

( .lower()আপনার যদি ছোট-কেসের প্রয়োজন হয় তবে সংযোজন করুন )। এটি পাইথন 2 এবং 3 উভয়ের জন্যই কাজ করে।


এছাড়াও একটি সমস্যা আমি গাড়ীতে আঘাত, আপনি যদি hexdump বা অন্য কোন প্যাকেজ ইনস্টল সমস্যা এটা usualy প্রক্সি সেটিংস চেষ্টা প্রক্সি বিকল্প পিপ চালানোর জন্যই pip install -U hexdump --proxy http://proxy.address:port
এডুয়ার্ড Florinescu

আসলে আমি এর sudoসাথে ব্যবহার করার ভুল করেছিলাম pip, যা pacman
গোলমেলে

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


আমি কোথায় ভবিষ্যতের সন্ধান করব
তোফুটিম

ভবিষ্যতের রেফারেন্সের জন্য, __future__পাইথন 2 এর সাম্প্রতিক সংস্করণগুলিতে একটি স্ট্যান্ডার্ড লাইব্রেরি পাওয়া যায় যা কেবলমাত্র পাইথন 3 পিছনের দিকে সামঞ্জস্যপূর্ণ বৈশিষ্ট্যগুলি তৈরি করতে ব্যবহার করা যেতে পারে। এই উত্তরে এটি print(text)"মুদ্রণ ফাংশন" বৈশিষ্ট্যটি পেতে ব্যবহৃত হয় যা print textপাইথন ২ থেকে বাক্য গঠনটি প্রতিস্থাপন করে । পাইথন ডক্স দেখুন
এরিক রিড

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

পাইথন 2 এ ব্যবহার base64.b16encodeকরা (এটি অন্তর্নির্মিত)

>>> 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()করবেন না ?
not2qubit

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ইনট লাগে ...
তবে আপনি b''নির্বাচন না করে যুক্তি ছাড়াই বাইট স্ট্রিং দিয়ে আটকে যাবেন ord(v)

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.