পাইথন 3 এ বাইটসকে একটি হেক্স স্ট্রিংয়ে রূপান্তর করার সঠিক উপায় কী?


235

পাইথন 3 এ বাইটসকে একটি হেক্স স্ট্রিংয়ে রূপান্তর করার সঠিক উপায় কী?

আমি কোনও bytes.hexপদ্ধতির দাবী , bytes.decodeকোডেক দেখতে পাচ্ছি এবং কোনও লাভ ছাড়াই কমপক্ষে বিস্মিত হওয়ার সম্ভাব্য অন্যান্য কার্যাদি চেষ্টা করেছি । আমি শুধু আমার বাইটস হেক্স হিসাবে চাই!


"লাভ না করে"? আপনি কোন নির্দিষ্ট সমস্যা বা ত্রুটি পাচ্ছেন? দয়া করে কোড এবং ত্রুটিগুলি দেখান।
এস .লট

উত্তর:


409

পাইথন ৩.৩ হ'ল এটি শেষ পর্যন্ত আর বিশ্রী নয়:

>>> b'\xde\xad\xbe\xef'.hex()
'deadbeef'

এবং বিপরীত:

>>> bytes.fromhex('deadbeef')
b'\xde\xad\xbe\xef'

পরিবর্তনীয় bytearrayধরণের সাথেও কাজ করে ।

তথ্যসূত্র: https://docs.python.org/3/library/stdtypes.html#bytes.hex


5
bytes.fromhex()পাইথন 3.0.০+ এ উপলব্ধ (কেবলমাত্র ৩.৫+ নয়)। bytes.hex()কেবল পাইথন 3.5+ এ।
ফিনিক্স

95

binasciiমডিউলটি ব্যবহার করুন :

>>> import binascii
>>> binascii.hexlify('foo'.encode('utf8'))
b'666f6f'
>>> binascii.unhexlify(_).decode('utf8')
'foo'

এই উত্তরটি দেখুন: হেক্স থেকে পাইথন 3.1.1 স্ট্রিং


8
এটা ভাল. মাইন্ড বগলিং হ'ল আপনি বাইটস.ফ্রোমেক্স (হেক্স_স্ট্রাস্টার) ব্যবহার করে হেক্সকে বাইটে রূপান্তর করতে পারেন, তবে আপনি বাইটসকে টেক্সটেক্স () ব্যবহার করে বেটকে হেক্সে রূপান্তর করতে পারবেন না - এর মধ্যে যুক্তি কী?
নাগাইলিজ

1
আমি অনুমান করি যে বাইটস এবং হেক্সের মধ্যে সম্পর্ক কোনওরই সম্পত্তি নয় (যা কেন হেক্স রয়েছে তা উত্তর দেয় না)। দেখে মনে হচ্ছে এটি কেবল একটি তদারকি নয় বরং এমন কিছু যা নিয়ে তর্ক করা হয়েছিল: bugs.python.org/issue3532#msg70950 । প্রশ্ন: বাইটস অবজেক্টের টোহেক্স পদ্ধতিটিও এই কাজটি সম্পাদন করতে ব্যথা করবে? উত্তর: আইএমও, হ্যাঁ, এটি হবে। এটি কোডটিকে জটিল করে তোলে এবং ডেটা রূপান্তর সম্পর্কিত যথাযথ পদ্ধতির থেকে দৃষ্টি আকর্ষণ করে (যথা, ফাংশন - পদ্ধতি নয়)।
মি মাইন্ড

3
এটি কি সত্যই প্রশ্নের উত্তর দেয়? এটি একটি hex ফেরত না strকিন্তু একটি bytes। আমি জানি যে উত্তরটি দিয়ে ওপি খুশি মনে হয়েছে তবে এই উত্তরটিকে প্রসারিত করে .decode("ascii")এটি একটি "স্ট্রিং" এ রূপান্তর করা আরও ভাল হবে না
রুবেনলগুনা

3
আমি ভাবছিলাম যে অনেকে এই প্রশ্ন / উত্তরে অবতরণ করে একটি প্রিন্ট আউট করার উপায় খুঁজছেন bytes। আপনি যদি print(b'666f6f')আপনি পেতে bআউটে হবে। আপনি যদি .decode("ascii")তারপর না। কীভাবে যাঁরা প্রকৃতপক্ষে bytes(আইটেমগুলির সাথে সত্য বাইনারি> 128, একটি এসকি স্ট্রিং নয়) কীভাবে এটি মুদ্রণ করতে চেয়েছিলেন তা চিন্তা করেই ।
রুবেলগুনা

5
@নাগাইলিজ: .hex()পাইথনে 3.5++ পদ্ধতি রয়েছে
জেএফএস

43

পাইথনের বাইট-টু-বাইটস স্ট্যান্ডার্ড কোডেক রয়েছে যা কোটড-প্রিন্টেবল (7 বেটস এসকিআই-তে ফিট করে), বেস 64 (আলফানিউমারিক্সে ফিট), হেক্স এস্কেটিং, জিজিপ এবং বিজে 2 সংকোচনের মতো সুবিধাজনক রূপান্তর সম্পাদন করে। পাইথন 2 এ আপনি করতে পারেন:

b'foo'.encode('hex')

পাইথন 3 এ, str.encode/ bytes.decodeবাইটস </> স্ট্র রূপান্তরগুলির জন্য কঠোরভাবে হয়। পরিবর্তে, আপনি এটি করতে পারেন যা পাইথন 2 এবং পাইথন 3 জুড়ে কাজ করে ( উল্টোটির জন্য গুলি / এনকোড / ডিকোড / জি ):

import codecs
codecs.getencoder('hex')(b'foo')[0]

পাইথন ৩.৪ দিয়ে শুরু করে, একটি কম বিশ্রী বিকল্প রয়েছে:

codecs.encode(b'foo', 'hex')

এই বিবিধ কোডেকগুলি তাদের নিজস্ব মডিউলগুলির মধ্যেও অ্যাক্সেসযোগ্য (বেস 64, জ্লিব, বিজে 2, ইউ, কোপ্রি, বিনাসসি); এপিআই কম সামঞ্জস্যপূর্ণ, তবে সংক্ষেপণ কোডেকগুলির জন্য এটি আরও নিয়ন্ত্রণ সরবরাহ করে।


1
অজগরটি 3.3 ব্যবহার করে:LookupError: unknown encoding: hex
জানুস ট্রয়লসন

@ জানুস ট্রেলসন: 'হেক্স_কোডেক' চেষ্টা করুন । অথবা কেবল binascii.hexlify(b'foo')সরাসরি ব্যবহার করুন
jfs

7
import codecs
codecs.getencoder('hex_codec')(b'foo')[0]

পাইথন ৩.৩ এ কাজ করে (সুতরাং "হেক্স" এর পরিবর্তে "hex_codec")।


সম্ভবত আকর্ষণীয়ভাবে, পাইথন ৩.৪-তে "হেক্স" বা "হেক্স_কোডেক" ভাল কাজ করে।
স্টিফেন পলগার

6

পদ্ধতিটি এসকিআই হেক্স স্ট্রিংকে উপস্থাপন করে একটি binascii.hexlify()রূপান্তর করবে । তার মানে ইনপুটটির প্রতিটি বাইট দুটি এসকিআই অক্ষরে রূপান্তরিত হবে। যদি আপনি একটি সত্য খুঁজে পেতে চান তবে আপনি ফলাফল করতে পারেন ।bytesbytesstr.decode("ascii")

আমি একটি স্নিপেট অন্তর্ভুক্ত করেছি যা এটি চিত্রিত করে।

import binascii

with open("addressbook.bin", "rb") as f: # or any binary file like '/bin/ls'
    in_bytes = f.read()
    print(in_bytes) # b'\n\x16\n\x04'
    hex_bytes = binascii.hexlify(in_bytes) 
    print(hex_bytes) # b'0a160a04' which is twice as long as in_bytes
    hex_str = hex_bytes.decode("ascii")
    print(hex_str) # 0a160a04

হেক্স স্ট্রিং থেকে "0a160a04"ফিরে আসা করতে bytesসঙ্গে binascii.unhexlify("0a160a04")যা ফিরিয়ে দেয়b'\n\x16\n\x04'


3

ঠিক আছে, নীচের উত্তরটি কেবলমাত্র পাইথন 3 সম্পর্কে যত্নশীল হলে অল্প সুযোগের বাইরে, তবে আপনি পাইথন সংস্করণ নির্দিষ্ট না করেও এই প্রশ্নটি প্রথম গুগল হিট, সুতরাং পাইথন 2 এবং পাইথন 3 উভয় ক্ষেত্রেই কাজ করে এমন উপায় এখানে রয়েছে's ।

আমি এই strধরণের বাইটকে রূপান্তরিত করার প্রশ্নটিও ব্যাখ্যা করছি : অর্থাত পাইথন 2 এ বাইট-ওয়াই এবং পাইথন 3 এ ইউনিকোড-ওয়াই।

এটি দেওয়া, আমি জানি সবচেয়ে ভাল পদ্ধতির নাম:

import six

bytes_to_hex_str = lambda b: ' '.join('%02x' % i for i in six.iterbytes(b))

পাইথন 2 বা পাইথন 3 এর জন্য নিম্নলিখিত দাবিটি সত্য হবে, ধরে নিবেন যে আপনি unicode_literalsপাইথন 2 এ ভবিষ্যতটি সক্রিয় করেন নি :

assert bytes_to_hex_str(b'jkl') == '6a 6b 6c'

(অথবা আপনি ''.join()বাইটস ইত্যাদির মধ্যে স্থান বাদ দিতে ব্যবহার করতে পারেন )


3

এটি ফর্ম্যাট নির্দিষ্টকরণকারক ব্যবহার করা যেতে পারে %x02যে ফর্ম্যাট এবং একটি হেক্স মান আউটপুট। উদাহরণ স্বরূপ:

>>> foo = b"tC\xfc}\x05i\x8d\x86\x05\xa5\xb4\xd3]Vd\x9cZ\x92~'6"
>>> res = ""
>>> for b in foo:
...     res += "%02x" % b
... 
>>> print(res)
7443fc7d05698d8605a5b4d35d56649c5a927e2736

আমার মতে এটি সেরা উত্তর কারণ এটি প্রতিটি পাইথন সংস্করণে কাজ করে এবং কোনও আমদানির প্রয়োজন নেই। তবুও, আমি উচ্চতর ক্ষেত্রে হেক্সা স্ট্রিংগুলি আরও ভালভাবে প্রদর্শন করতে পারিres.upper()
ব্রুনো এল।


0

আপনি যদি b '\ x61' কে 97 বা '0x61' তে রূপান্তর করতে চান তবে আপনি এটি চেষ্টা করতে পারেন:

[python3.5]
>>>from struct import *
>>>temp=unpack('B',b'\x61')[0] ## convert bytes to unsigned int
97
>>>hex(temp) ##convert int to string which is hexadecimal expression
'0x61'

তথ্যসূত্র: https://docs.python.org/3.5/library/struct.html


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