Programing

Base64로 문자열을 인코딩하려면 왜 'b'가 필요합니까?

lottogame 2020. 4. 24. 08:03
반응형

Base64로 문자열을 인코딩하려면 왜 'b'가 필요합니까?


파이썬 예제에 따라 문자열을 Base64로 인코딩합니다.

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

왜 이런거야?


베이스 64 인코딩이 사용하는 8 비트 이진 바이트 데이터 인코딩 소요 자만 A-Z, a-z, 0-9, +, /*가 이메일과 같은 모든 데이터를 8 비트를 보존하지 않는 채널을 통해 전송 될 수 있도록.

따라서 8 비트 바이트의 문자열을 원합니다. b''구문을 사용하여 Python 3에서 생성 합니다.

를 제거하면 b문자열이됩니다. 문자열은 일련의 유니 코드 문자입니다. base64는 유니 코드 데이터로 무엇을해야할지 전혀 모르며 8 비트가 아닙니다. 실제로 실제로는 조금도 아닙니다. :-)

두 번째 예에서 :

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

모든 문자는 ASCII 문자 세트에 깔끔하게 들어 맞으므로 base64 인코딩은 실제로 약간 의미가 없습니다. 대신에 ascii로 변환 할 수 있습니다.

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

또는 더 간단합니다.

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

이 경우에도 같은 것입니다.


* 대부분의 base64 맛은 또한 =끝에 패딩으로 포함 할 수 있습니다 . 또한 일부 base64 변형은 +이외의 문자를 사용할 수 있습니다 /. 개요는 Wikipedia 변형 요약 표참조하십시오 .


짧은 답변

당신은 추진해야 할 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'

왜?

Python 3에서 str객체는 C 스타일의 문자 배열이 아니므로 바이트 배열이 아니라 고유 한 인코딩이없는 데이터 구조입니다. 해당 문자열을 다양한 방식으로 인코딩하거나 해석 할 수 있습니다. 가장 일반적인 (Python 3의 기본값)은 utf-8이며, 특히 ASCII와 호환됩니다 (가장 널리 사용되는 인코딩 임에도 불구하고). 즉 당신이 걸릴 때 무슨 일이 일어나고있는 것입니다 string과 전화 .encode()파이썬은 UTF-8 문자열 (기본 인코딩)을 해석하고 당신이에 해당 바이트의 배열을 제공 : 거기에 방법을.

Python 3의 Base-64 인코딩

원래 제목은 Base-64 인코딩에 관한 질문이었습니다. Base-64에 대해 읽어보십시오.

base64인코딩은 6 비트 이진 청크를 사용하고 AZ, az, 0-9, '+', '/'및 '='문자를 사용하여 인코딩합니다 (일부 인코딩은 '+'및 '/'대신 다른 문자를 사용함) . 이것은 radix-64 또는 base-64 숫자 시스템의 수학 구조를 기반으로하는 문자 인코딩이지만 매우 다릅니다. 수학의 Base-64는 이진수 또는 십진수와 같은 숫자 시스템이며 정수에서 또는 (변환하는 기수가 64보다 작은 2의 거듭 제곱 인 경우) 오른쪽에서 왼쪽.

에서 base64인코딩, 번역은 왼쪽에서 오른쪽으로 이루어집니다; 첫 64자인 이유는 base64 인코딩 이라고 합니다. 인코딩은 6 비트 청크를 가져 오지만 일반적으로 인코딩하려는 데이터는 8 비트 바이트이므로 마지막 청크에는 2 또는 4 비트 만 있기 때문에 65 번째 '='기호는 패딩에 사용됩니다.

예:

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

이진 데이터를 단일 정수로 해석하면 base-10 및 base-64 (base-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 그러나 encoding 은이 데이터를 다음과 같이 다시 그룹화합니다.

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'은 수학적으로 말하는 바이너리의 base-64 버전입니다. 그러나 base64 인코딩 은 반대 방향으로 인코딩을 수행해야하므로 (원시 데이터는 'dGVzdA'로 변환 됨) 다른 응용 프로그램에 마지막에 얼마나 많은 공간이 남아 있는지 알려주는 규칙이 있습니다. '='기호로 끝을 채우면됩니다. 따라서이 base64데이터 인코딩은 'dGVzdA =='이며, 두 개의 '='기호를 나타내는 두 개의 '='기호는이 데이터가 원래 데이터와 일치하도록 디코딩 될 때 끝에서 제거되어야합니다.

내가 부정직한지 알아보기 위해 이것을 시험해 보자.

>>> 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. 해당 이메일을 Unix로 보내려고하면 \x04문자가 읽히자 마자 이메일이 전송됩니다. 문자는 END-OF-TRANSMISSION(Ctrl-D)의 ASCII 이므로 나머지 데이터는 전송에서 제외됩니다.
  2. 또한 파이썬은 데이터를 직접 인쇄 할 때 모든 사악한 제어 문자를 피할 수있을만큼 똑똑하지만 해당 문자열이 ASCII로 디코딩되면 'msg'가 없다는 것을 알 수 있습니다. 3 개의 BACKSPACE문자와 3 개의 SPACE문자를 사용하여 'msg'를 지우기 때문입니다. 따라서 EOF문자가 없더라도 최종 사용자는 화면의 텍스트를 실제 원시 데이터로 번역 할 수 없습니다.

이것은 단순히 원시 데이터를 보내는 것이 얼마나 어려운지를 보여주는 데모 일뿐입니다. 데이터를 base64 형식으로 인코딩하면 정확한 데이터가 제공되지만 전자 메일과 같은 전자 매체를 통해 안전하게 전송할 수있는 형식으로 제공됩니다.


인코딩 할 데이터에 "이국적인"문자가 포함되어 있으면 "UTF-8"로 인코딩해야한다고 생각합니다

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

문자열이 유니 코드 인 경우 가장 쉬운 방법은 다음과 같습니다.

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: ñáéíóúÑ

필요한 모든 것이 있습니다 :

expected bytes, not str

행간 b은 문자열을 이진으로 만듭니다.

어떤 버전의 Python을 사용하십니까? 2.x 또는 3.x?

편집 : Python에서 문자열에 대한 자세한 내용은 http://docs.python.org/release/3.0.1/whatsnew/3.0.html#text-vs-data-instead-of-unicode-vs-8-bit참조 하십시오 . 3.x


b는 단순히 문자열이 아닌 바이트 또는 바이트 배열로 입력을 받고 있음을 의미합니다.

참고 URL : https://stackoverflow.com/questions/8908287/why-do-i-need-b-to-encode-a-string-with-base64

반응형