短い答え
あなたはプッシュする必要があるbytes-like
オブジェクト(bytes
、bytearray
に、等)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
オブジェクトはCスタイルの文字配列ではないため(バイト配列ではありません)、固有のエンコーディングを持たないデータ構造です。その文字列は、さまざまな方法でエンコード(または解釈)できます。最も一般的(そしてPython 3のデフォルト)はutf-8です。これは、ASCIIと下位互換性があるためです(ただし、最も広く使用されているエンコーディングと同様)。これは、a string
を受け取ってその.encode()
メソッドを呼び出すと発生します。Pythonは文字列をutf-8(デフォルトのエンコーディング)で解釈し、それに対応するバイトの配列を提供します。
Python 3のBase-64エンコーディング
元々、質問のタイトルはBase-64エンコーディングについて尋ねていました。Base-64について読んでください。
base64
エンコーディングは6ビットのバイナリチャンクを受け取り、AZ、az、0-9、「+」、「/」、および「=」の文字を使用してエンコードします(一部のエンコーディングは「+」と「/」の代わりに異なる文字を使用します)。 。これは、基数64または基数64の数体系の数学的構造に基づいた文字エンコードですが、非常に異なります。数学のBase-64は、2進数や10進数のような数体系であり、基数のこの変更は整数全体で行うか、または(変換元の基数が64未満の2の累乗の場合)右から左。
ではbase64
エンコーディング、翻訳は左から右に行われます。これらの最初の64文字が、base64
エンコーディングと呼ばれる理由です。65番目の「=」記号はパディングに使用されます。これは、エンコーディングが6ビットのチャンクをプルするためですが、通常、エンコードするデータは8ビットバイトであるため、最後のチャンクに2ビットまたは4ビットしかない場合があります。
例:
>>> 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 ==」であり、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つの問題があります:
- そのメールをUnixで送信しようとすると、
\x04
文字が読み取られるとすぐにメールが送信されます。これは、END-OF-TRANSMISSION
(Ctrl-D)のASCII であるため、残りのデータは送信されません。
- また、Pythonはデータを直接出力するときに邪悪な制御文字をすべてエスケープするのに十分スマートですが、その文字列がASCIIとしてデコードされると、「msg」がそこにないことがわかります。これは、「msg」を消去するために3
BACKSPACE
文字と3 SPACE
文字を使用したためです。したがって、EOF
そこに文字がなかったとしても、エンドユーザーは画面上のテキストから実際の生データに翻訳することができません。
これは単に生データを送信するのがどれほど難しいかを示すデモにすぎません。データをbase64形式にエンコードすると、まったく同じデータが得られますが、電子メールなどの電子メディアを介して安全に送信できる形式になります。