[python] 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 스타일의 문자 배열이 아니므로 바이트 배열이 아니라 고유 한 인코딩이없는 데이터 구조입니다. 해당 문자열을 다양한 방식으로 인코딩하거나 해석 할 수 있습니다. 가장 일반적으로 사용되는 파이썬 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는 단순히 문자열이 아닌 바이트 또는 바이트 배열로 입력을 받고 있음을 의미합니다.


답변