この Pythonの例 に従って、文字列を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
どうしてこれなの?
base64エンコーディングは8ビットのバイナリバイトデータを受け取り、A-Z
、a-z
、0-9
、+
、/
*の文字のみを使用してエンコードするので、Eメールなどの8ビットのデータをすべて保存しないチャネルを介して送信できます。
したがって、8ビットバイトの文字列が必要です。あなたはb''
構文でPython 3でそれらを作成します。
b
を削除すると、文字列になります。文字列はUnicode文字のシーケンスです。 base64は、Unicodeデータをどう処理するかわかりません。8ビットではありません。それは実際には少しもそうではありません。 :-)
あなたの2番目の例では:
>>> 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の変種は+
と/
以外の文字を使うかもしれません。概要については、ウィキペディアの バリアント要約表 を参照してください。
bytes-like
オブジェクト(bytes
name__、bytearray
name__など)をbase64.b64encode()
メソッドにプッシュする必要があります。これには2つの方法があります。
>>> 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
name__オブジェクトはCスタイルの文字配列ではありません(つまりnotbyte配列)が、固有のエンコーディングを持たないデータ構造です。 。その文字列をさまざまな方法でエンコード(または解釈)することができます。最も一般的な(そしてPython 3のデフォルト)utf-8は、特にASCIIと後方互換性があるためです(もっとも広く使われているエンコーディングと同様です)。 string
name__を取り、それに.encode()
メソッドを呼び出すとそれが起こります。Pythonはutf-8(デフォルトのエンコーディング)で文字列を解釈し、それに対応するバイト配列を提供します。
もともと質問タイトルはBase-64エンコーディングについて尋ねました。 Base-64について読んでください。
base64
エンコーディングは6ビットのバイナリチャンクを取り、それらをAZ、az、0-9、 '+'、 '/'、および '='の文字を使用してエンコードします(一部のエンコーディングは '+'と '/'の代わりに異なる文字を使用します) )これは、基数64または基数64の数体系の数学的構造に基づいた文字エンコードですが、非常に異なります。数学の基数64は2進数や10進数のような数体系です、そしてあなたは整数の上で基数のこの変更をします、または(あなたが変換している基数が64より小さい2のべき乗である)左。
base64
エンコーディングでは、変換は左から右へ行われます。これらの最初の64文字がbase64
encodingと呼ばれる理由です。エンコーディングは6ビットチャンクを引っ張りますが、通常エンコードするデータは8ビットバイトであるため、最後のチャンクには2または4ビットしかない場合があるため、65番目の '='記号はパディングに使用されます。
例:
>>> data = b'test'
>>> for byte in data:
... print(format(byte, '08b'), end=" ")
...
01110100 01100101 01110011 01110100
>>>
そのバイナリデータを単一の整数として解釈すると、base-64の場合はbase-10および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
encodingは逆方向にエンコードする必要があるため(生データは 'dGVzdA'に変換されます)、他のアプリケーションにいくら分適用するかという規則もあります最後はスペースが残ります。これは、末尾に「=」記号を埋め込むことによって行われます。したがって、このデータのbase64
エンコーディングは 'dGVzdA =='です。2つのビットのペアを表す2つの '='記号は、元のデータと一致させるためにこのデータをデコードするときに末尾から削除する必要があります。
これをテストして、私が不正であるかどうかを確認しましょう。
>>> 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 '
>>>
私が計画した2つの問題があります。
\x04
文字が読み取られるとすぐに送信されます。これは、END-OF-TRANSMISSION
の場合はASCIIなので、残りのデータは除外されるためです。トランスミッション.BACKSPACE
name__文字と3つのSPACE
name__文字を使用したためです。したがって、私がそこにEOF
name__文字を持っていなくても、エンドユーザーは画面上のテキストから実際の生データに変換することができません。これは単に生データを送信するのがどれほど難しいかを示すデモです。データをbase64形式にエンコードすると、まったく同じデータが得られますが、電子メールなどの電子メディアを介して送信しても安全であることが保証される形式になります。
エンコードされるデータに「エキゾチック」な文字が含まれている場合は、「UTF-8」でエンコードする必要があると思います
encoded = base64.b64encode (bytes('data to be encoded', "utf-8"))
必要なものがすべて揃っています。
expected bytes, not str
先頭のb
はあなたの文字列をバイナリにします。
どのバージョンのPythonを使用していますか? 2.xか3.xか
文字列がUnicodeの場合、最も簡単な方法は次のとおりです。
import base64
a = base64.b64encode(bytes(u'complex string: ñáéíóúÑ', "utf-8"))
b = base64.b64decode(a).decode("utf-8", "ignore")
print(b)
これは単に、入力を文字列としてではなくバイトまたはバイト配列として受け取ることを意味します。