বেস 64 এর সাথে একটি স্ট্রিং এনকোড করতে কেন আমার 'বি' দরকার?


258

এই অজগর উদাহরণ অনুসরণ করে , আমি এর সাথে বেস 64 হিসাবে একটি স্ট্রিং এনকোড করেছি:

>>> import base64
>>> encoded = base64.b64encode(b'data to be encoded')
>>> encoded
b'ZGF0YSB0byBiZSBlbmNvZGVk'

তবে, আমি যদি অগ্রণীটিকে ছেড়ে যাই b:

>>> encoded = base64.b64encode('data to be encoded')

আমি নিম্নলিখিত ত্রুটি পেয়েছি:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python32\lib\base64.py", line 56, in b64encode
   raise TypeError("expected bytes, not %s" % s.__class__.__name__)
   TypeError: expected bytes, not str

কেন?


37
প্রকৃতপক্ষে যে সমস্ত প্রশ্ন "টাইপররার: প্রত্যাশিত বাইটস, স্ট্রিং নয়" ফিরে আসে সেগুলির একই উত্তর রয়েছে।
লেনার্ট রেগেব্রো

উত্তর:


273

করুন Base64- এনকোডিং এটি ব্যবহার করে 8-বিট বাইনারি বাইট ডাটা এবং এনকোড লাগে শুধুমাত্র অক্ষর A-Z, a-z, 0-9, +, /* তাই এটি চ্যানেল যে এই ধরনের ইমেল হিসাবে সমস্ত ডেটা 8-বিট, সংরক্ষিত হয় না বেশি পরিবাহিত হতে পারে।

সুতরাং, এটি 8-বিট বাইটের একটি স্ট্রিং চায়। পাইথন 3 এ আপনি b''সিনট্যাক্স দিয়ে তৈরি করেন ।

আপনি যদি এটি অপসারণ করেন তবে bএটি একটি স্ট্রিং হয়ে যায়। একটি স্ট্রিং ইউনিকোড অক্ষরের একটি ক্রম। বেস 64 এর ইউনিকোড ডেটা দিয়ে কী করবেন তার কোনও ধারণা নেই, এটি 8-বিট নয়। বাস্তবে এটি কোনও বিট নয়। :-)

আপনার দ্বিতীয় উদাহরণে:

>>> encoded = base64.b64encode('data to be encoded')

সমস্ত অক্ষর ASCII অক্ষর সেট মধ্যে ঝরঝরে ফিট করে, এবং বেস 64 এনকোডিং তাই কিছুটা অর্থহীন। পরিবর্তে আপনি এটিকে ascii এ রূপান্তর করতে পারেন with

>>> encoded = 'data to be encoded'.encode('ascii')

বা আরও সহজ:

>>> encoded = b'data to be encoded'

এক্ষেত্রে যা একই জিনিস হবে।


* বেশিরভাগ বেস 64 এর স্বাদগুলি =প্যাডিং হিসাবে শেষে অন্তর্ভুক্ত থাকতে পারে । উপরন্তু, কিছু করুন Base64- রূপগুলো ছাড়া অন্য অক্ষর ব্যবহার করতে পারেন +এবং /। ওভারভিউতে ভেরিয়েন্টের সংক্ষিপ্তসার সারণি দেখুন ।


174

সংক্ষিপ্ত উত্তর

আপনি একটি ধাক্কা প্রয়োজন bytes-likeবস্তু ( bytes, bytearrayকরতে, ইত্যাদি) base64.b64encode()পদ্ধতি। এখানে দুটি উপায় রয়েছে:

>>> data = base64.b64encode(b'data to be encoded')
>>> print(data)
b'ZGF0YSB0byBiZSBlbmNvZGVk'

অথবা একটি পরিবর্তনশীল সহ:

>>> string = 'data to be encoded'
>>> data = base64.b64encode(string.encode())
>>> print(data)
b'ZGF0YSB0byBiZSBlbmNvZGVk'

কেন?

পাইথন 3 সালে strবস্তু সি-শৈলী চরিত্র অ্যারে (তাই তারা নয় না অ্যারে বাইট), কিন্তু এর পরিবর্তে, তারা ডাটা স্ট্রাকচার যে কোনো সহজাত এনকোডিং হবে না হয়। আপনি বিভিন্নভাবে এই স্ট্রিংটিকে (বা এটি ব্যাখ্যা করতে) এনকোড করতে পারেন। সর্বাধিক প্রচলিত (এবং পাইথন 3-এ ডিফল্ট) হল utf-8, বিশেষত যেহেতু এটি ASCII এর সাথে পিছনের দিকে সামঞ্জস্যপূর্ণ (যদিও এটি বহুল ব্যবহৃত-ব্যবহৃত এনকোডিংগুলি রয়েছে)। আপনি যখন এটি গ্রহণ করেন stringএবং সেই .encode()পদ্ধতিটি কল করেন তখন এটিই ঘটে থাকে: পাইথন utf-8 (ডিফল্ট এনকোডিং) এ স্ট্রিংটির ব্যাখ্যা দিচ্ছে এবং আপনাকে এটির সাথে মিলিয়ে বাইটের অ্যারে সরবরাহ করছে।

পাইথন 3 -তে বেস-64৪ এনকোডিং

মূলত প্রশ্ন শিরোনাম বেস -৪ 64 এনকোডিং সম্পর্কে জিজ্ঞাসা করেছিল। বেস-64 stuff স্টাফের জন্য পড়ুন।

base64এনকোডিংয়ে--বিট বাইনারি খণ্ড নেয় এবং এজেড, এজ, ০-৯, '+', '/', এবং '=' অক্ষর ব্যবহার করে তাদের এনকোড করে (কিছু এনকোডিংগুলি '+' এবং '/' এর জায়গায় বিভিন্ন অক্ষর ব্যবহার করে) । এটি একটি চরিত্রের এনকোডিং যা মূলত -৪৪ বা বেস-64৪ নম্বর সিস্টেমের গাণিতিক নির্মাণের ভিত্তিতে নির্মিত তবে সেগুলি খুব আলাদা different গণিতে বেস-64৪ হ'ল বাইনারি বা দশমিকের মতো একটি সংখ্যা সিস্টেম এবং আপনি পুরো সংখ্যাটিতে র‌্যাডিক্সের এই পরিবর্তনটি করেন, বা (যদি আপনি যে রেডিক্সটি রূপান্তর করছেন তবে 64৪ এর চেয়ে কম 2 এর শক্তি) ডান থেকে অংশে পড়ে থাকবে।

ইন base64এনকোডিং, অনুবাদ বাঁ দিক থেকে ডানদিকে সম্পন্ন করা হয়; এই প্রথম 64 টি অক্ষরকে কেন এটি base64 এনকোডিং বলা হয় । Th৫ তম '=' চিহ্নটি প্যাডিংয়ের জন্য ব্যবহৃত হয়, যেহেতু এনকোডিংটি ch-বিট খণ্ডগুলি টান দেয় তবে সাধারণত যে ডেটাটি এনকোড করতে বোঝানো হয় তা হ'ল 8-বিট বাইট হয়, তাই কখনও কখনও শেষ খণ্ডে মাত্র 2 বা 4 বিট থাকে।

উদাহরণ:

>>> data = b'test'
>>> for byte in data:
...     print(format(byte, '08b'), end=" ")
...
01110100 01100101 01110011 01110100
>>>

যদি আপনি সেই বাইনারি ডেটাটিকে একটি একক পূর্ণসংখ্যা হিসাবে ব্যাখ্যা করেন, তবে আপনি এটিই বেস -10 এবং বেস--৪ (বেস-64৪ এর টেবিল ) এ রূপান্তর করবেন :

base-2:  01 110100 011001 010111 001101 110100 (base-64 grouping shown)
base-10:                            1952805748
base-64:  B      0      Z      X      N      0

base64 এনকোডিং যদিও এইভাবে এই ডেটাটিকে পুনরায় গ্রুপ করবে:

base-2:  011101  000110  010101 110011 011101 00(0000) <- pad w/zeros to make a clean 6-bit chunk
base-10:     29       6      21     51     29      0
base-64:      d       G       V      z      d      A

সুতরাং, 'B0ZXN0' হ'ল আমাদের বাইনারি, গাণিতিকভাবে বলার বেস-64 base সংস্করণ। যাইহোক, base64 এনকোডিংকে বিপরীত দিকে এনকোডিং করতে হয় (সুতরাং কাঁচা ডেটাটি 'ডিজিভিজেডএ'তে রূপান্তরিত হয়) এবং শেষদিকে কতটা জায়গা ছেড়ে যায় তা অন্যান্য অ্যাপ্লিকেশনগুলিকে জানানোরও একটি বিধি রয়েছে। এটি '=' চিহ্ন সহ প্রান্ত প্যাডিং দ্বারা সম্পন্ন হয়। সুতরাং, base64এই ডেটাটির এনকোডিংটি 'dGVzdA ==', দুটি '=' চিহ্ন সহ দুটি জোড় বিট নির্দেশ করে যখন এই ডেটাটি মূল ডেটার সাথে মিলে যায় তখন ডিকোড হয়ে যায়।

আসুন আমি পরীক্ষা করে দেখি যে আমি বেonমান হয়ে যাচ্ছি:

>>> encoded = base64.b64encode(data)
>>> print(encoded)
b'dGVzdA=='

base64এনকোডিং কেন ব্যবহার করবেন ?

ধরা যাক এই ডেটার মতো ইমেলের মাধ্যমে আমাকে কারও কাছে কিছু তথ্য প্রেরণ করতে হবে:

>>> data = b'\x04\x6d\x73\x67\x08\x08\x08\x20\x20\x20'
>>> print(data.decode())

>>> print(data)
b'\x04msg\x08\x08\x08   '
>>>

আমি লাগানো দুটি সমস্যা আছে:

  1. যদি আমি ইউনিক্সে সেই ইমেলটি প্রেরণের চেষ্টা করি, \x04চরিত্রটি পড়ার সাথে সাথে ইমেলটি প্রেরণ করা হত , কারণ এটি END-OF-TRANSMISSION(সিটিআরএল-ডি) জন্য ASCII , সুতরাং বাকী ডেটা সংক্রমণের বাইরে থাকবে।
  2. এছাড়াও, যখন পাইথন আমার সমস্ত অশুভ নিয়ন্ত্রণের অক্ষরগুলি থেকে রেহাই পেতে যথেষ্ট স্মার্ট, যখন আমি সরাসরি তথ্য প্রিন্ট করি, যখন সেই স্ট্রিংটি ASCII হিসাবে ডিকোড করা হয়, আপনি দেখতে পাবেন যে 'msg' নেই। কারণ 'আমি ' মুছে ফেলতে আমি তিনটি BACKSPACEঅক্ষর এবং তিনটি SPACEঅক্ষর ব্যবহার করেছি । সুতরাং, আমার EOFসেখানে অক্ষর না থাকলেও শেষ ব্যবহারকারী পর্দার পাঠ্য থেকে আসল, কাঁচা ডেটাতে অনুবাদ করতে পারবেন না।

এটি কেবলমাত্র কাঁচা ডেটা প্রেরণে কতটা শক্ত হতে পারে তা আপনাকে দেখানোর জন্য এটি একটি ডেমো। বেস 6464 ফর্ম্যাটে ডেটা এনকোডিং আপনাকে সঠিক একই তথ্য দেয় তবে এমন ফর্ম্যাটে যা নিশ্চিত করে যে এটি ইমেল হিসাবে ইলেকট্রনিক মিডিয়াতে প্রেরণে নিরাপদ।


6
base64.b64encode(s.encode()).decode()আপনি যে সমস্ত স্ট্রিং থেকে রূপান্তর করতে চান তা হ'ল খুব অজগর নয়। base64.encode(s)কমপক্ষে পাইথন 3 এ যথেষ্ট হওয়া উচিত।
পাইথনে

2
@ মর্টেনবি হ্যাঁ, এটি অদ্ভুত, তবে যতক্ষণ না ইঞ্জিনিয়ার বাইটস এবং স্ট্রিংয়ের অ্যারেগুলির মধ্যে পার্থক্য সম্পর্কে অবগত আছেন ততক্ষণ পর্যন্ত বিষয়টি খুব স্পষ্ট, যেহেতু অন্য ভাষাগুলির মতো তাদের মধ্যে একটিও ম্যাপিং (এনকোডিং) নেই since অনুমান।
গ্রেগ স্মিট

3
@ মর্টেনবি, যাইহোক, base64.encode(s)পাইথন 3 এ কাজ করবে না; আপনি কি বলছেন যে এর মতো কিছু পাওয়া উচিত? আমি মনে করি এটি বিভ্রান্তিকর হওয়ার কারণটি হ'ল, এনকোডিং এবং স্ট্রিংয়ের বিষয়বস্তুর উপর নির্ভর করে sবাইটের অ্যারে হিসাবে 1 টি স্বতন্ত্র উপস্থাপনা নাও থাকতে পারে।
গ্রেগ স্মিট

স্মিট: এটি কতটা সহজ হওয়া উচিত তার উদাহরণ মাত্র was সর্বাধিক সাধারণ ব্যবহারের ক্ষেত্রে এটি হওয়া উচিত।
মর্টেনবি

1
@ মর্টেনবি কিন্তু বি 64 টি কেবল পাঠ্যের জন্য নয়, কোনও বাইনারি সামগ্রী বি 64 এনকোডড (অডিও, চিত্রগুলি ইত্যাদি) হতে পারে। আপনি আমার মতে প্রস্তাব দেওয়ার সাথে সাথে এটি কাজ করে পাঠ্য এবং বাইট অ্যারের মধ্যে পার্থক্যকে আরও বেশি গোপন করে, ডিবাগিংকে আরও শক্ত করে তোলে। এটি কেবল অন্য কোথাও অসুবিধাটি সরিয়ে দেয়।
মাইকেল একোকা

32

যদি এনকোড করা ডেটাতে "বহিরাগত" অক্ষর থাকে তবে আমার মনে হয় আপনাকে "ইউটিএফ -8" এ এনকোড করতে হবে

encoded = base64.b64encode (bytes('data to be encoded', "utf-8"))

24

যদি স্ট্রিংটি ইউনিকোড হয় তবে সবচেয়ে সহজ উপায় হ'ল:

import base64                                                        

a = base64.b64encode(bytes(u'complex string: ñáéíóúÑ', "utf-8"))

# a: b'Y29tcGxleCBzdHJpbmc6IMOxw6HDqcOtw7PDusOR'

b = base64.b64decode(a).decode("utf-8", "ignore")                    

print(b)
# b :complex string: ñáéíóúÑ

সত্যই সহজতম উপায় নয়, তবে সবচেয়ে স্পষ্ট উপায়গুলির মধ্যে একটি, যখন স্ট্রিং সংক্রমণ করার জন্য কোন এনকোডিংটি ব্যবহার করা গুরুত্বপূর্ণ, যা বেস 64 এর মাধ্যমে ডেটা ট্রান্সমিশনের "প্রোটোকলের" অংশ is
xuiqzy

12

আপনার যা যা প্রয়োজন তা রয়েছে:

expected bytes, not str

নেতৃস্থানীয় bআপনার স্ট্রিং বাইনারি করে তোলে।

পাইথনের কোন সংস্করণ আপনি ব্যবহার করেন? 2.x বা 3.x?

সম্পাদনা করুন: পাইথনে স্ট্রিংগুলির ক্ষতিকারক বিশদগুলির জন্য http://docs.python.org/release/3.0.1/whatsnew/3.0.html#text-vs-data-instead-of-unicode-vs-8-bit দেখুন 3.x


ধন্যবাদ আমি ব্যবহার করছি, 3.x। পাইথন কেন এটি স্পষ্ট করে বাইনারি রূপান্তর করতে চায়। রুবিতে একই হবে ...> "বেস64" এবং তারপরে> বেস64.encode64 ('ডেটা এনকোড করতে হবে') দরকার
ডাবলিনটেক

2
@ ডাবলিনটেক কারণ (ইউনিকোড) পাঠ্য কাঁচা ডেটা থেকে পৃথক। আপনি যদি বেস 64 এ কোনও পাঠ্য স্ট্রিংটি এনকোড করতে চেয়েছিলেন তবে প্রথমে আপনাকে অক্ষর এনকোডিং নির্ধারণ করতে হবে (ইউটিএফ -8 এর মতো) এবং তারপরে অক্ষরের পরিবর্তে আপনার বাইটস থাকতে হবে যে আপনি পাঠ্য ascii- নিরাপদ আকারে এনকোড করতে পারবেন।
ফোরট্রান

2
এটি প্রশ্নের উত্তর দেয় না। তিনি জানেন যে এটি কোনও বাইট অবজেক্টের সাথে কাজ করে তবে স্ট্রিং অবজেক্ট নয়। প্রশ্ন কেন ?
লেনার্ট রেগেব্রো

@ ফিফেরান ডিফল্ট পাইথন 3 স্ট্রিং এনকোডিংটি ইউটিএফ, জানেন না কেন এটি স্পষ্টভাবে সেট করতে হবে।
xmedeko

0

খ এর সহজ অর্থ আপনি ইনপুটটি বাইট বা বাইট অ্যারে হিসাবে স্ট্রিং হিসাবে গ্রহণ করছেন না।

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