電子メールでPDFや画像ファイルを受信して、開いてみたら変な文字が表示されたことはありませんか?これは、メールサーバーがテキストデータのみを扱うように設計されている場合に起こる可能性があります。
バイナリデータ、つまり画像のようなテキスト以外の情報を表すバイトを持つファイルは、テキストのみのシステムに転送して処理すると、簡単に破損してしまうことがあります。
Base64エンコーディングは、バイナリやテキストデータを含むバイトをASCII文字に変換することを可能にします。
データをエンコードすることで、様々なシステムで正しく処理される可能性を高めることができます。
このチュートリアルでは、Base64エンコーディングとデコーディングがどのように機能し、どのように使用できるかを学びます。
そして、Pythonを使って、テキストとバイナリデータの両方をBase64エンコードとデコードします。
Base64エンコーディングはどのように機能するか?
Base64エンコーディングがどのように機能するか、テキストデータを変換することで説明します。
文字列をBase64エンコードする場合、次のような手順で行います。
- 文字列の各文字のASCII値を取得する。
- ASCII値の8ビットバイナリ等価値を計算する。
-
- 8ビットのチャンクを6ビットのチャンクに変換し、桁をグループ化する
-
- 6ビットの2進数グループをそれぞれの10進数値へ変換する。
-
- base64エンコーディングテーブルを使用して、各10進値に対してそれぞれのbase64文字を割り当てる。
Python “という文字列をBase64文字列に変換して、その動作を確認しましょう。
文字P, y, t, h, o, n
のASCII値はそれぞれ15, 50, 45, 33, 40, 39
である。
これらのASCII値を8ビット2進数で表すと、次のようになる。
01010000 01111001 01110100 01101000 01101111 01101110
Base64の文字は6ビットのデータしか表現できないことを思い出してください。
ここで、8ビットのバイナリ列を6ビットのチャンクに再グループ化する。
その結果、バイナリは次のようになる。
010100 000111 100101 110100 011010 000110 111101 101110
注:データを6ビットのシーケンスにグループ化できないこともある。
そのような場合は、シーケンスをパディングする必要があります。
6ビットのデータをグループ化すると、各グループの10進値が得られます。
前回の結果を利用すると、以下の10進値が得られます。
20 7 37 52 26 6 61 46
最後に、Base64の変換表を使って、これらの10進数を適切なBase64文字に変換する。
見てわかるように、値 20
は文字 U
に対応する。
次に 7
を見てみると、H
に対応していることがわかります。
このように、すべての10進数の値について調べると、”Python “はBase64エンコードされるとUHl0aG9u
と表現されることがわかります。
この結果は、オンラインの変換ツールで確認することができます。
Base64エンコードを行うには、文字列を2進数に変換し、次に10進数に変換し、最後にルックアップテーブルを使ってASCII文字の文字列を得ます。
このように仕組みを深く理解した上で、なぜデータをBase64エンコードするのかを見ていきましょう。
なぜBase64エンコードを使用するのか?
[…]
なぜBase64エンコードを使うのか?
コンピュータでは、さまざまな種類のデータはすべて1と0として送信されます。
しかし、通信チャネルやアプリケーションによっては、受信したビットをすべて理解することができないものもあります。
これは、1と0の並びの意味が、それが表すデータの種類に依存するためです。
例えば、10110001
が文字を表す場合と画像を表す場合では、異なる処理をしなければなりません。
この制限を回避するために、データをテキストにエンコードすることで、正しく送信・処理される可能性を高めることができます。
Base64は、バイナリデータをASCII文字に変換する一般的な方法で、ネットワークやアプリケーションの大部分に広く理解されています。
Base64エンコーディングが多用される現実世界のシナリオは、メールサーバーである。
これらはもともとテキストデータを扱うために作られたものですが、メッセージとともに画像やその他のメディアを送信することも想定されています。
そのような場合、メディアデータは送信時にBase64エンコードされます。
そして、アプリケーションがそれを使えるように、受信時にBase64デコードされます。
つまり、たとえばHTMLの中の画像は、次のようになります。
<img src="data:image/png;base64,aVRBOw0AKg1mL9..."/
データが破損しないようにテキストとして送信する必要があることを理解した上で、Pythonを使用してデータをBase64エンコードおよびデコードする方法を見てみましょう。
Pythonで文字列のデコードを行う。
Base64文字列のデコードは、基本的にエンコード処理の逆を行います。
Base64文字列をデコードして、エンコードされていないデータのバイトにします。
そして、そのバイトのようなオブジェクトを文字列に変換します。
新しいファイル decoding_text.py
に、次のコードを書いてください。
import base64
message = "Python is fun"
message_bytes = message.encode('ascii')
base64_bytes = base64.b64encode(message_bytes)
base64_message = base64_bytes.decode('ascii')
print(base64_message)
もう一度、base64
モジュールをインポートする必要があります。
次に、encode('ASCII')
を使って、メッセージをバイトのようなオブジェクトにエンコードします。
続けて、 base64.b64decode
メソッドを呼び出して base64_bytes
をデコードし、 message_bytes
変数に格納します。
最後に、message_bytes
を文字列オブジェクト message
にデコードして、人間が読めるようにします。
このファイルを実行すると、次のような出力が表示されます。
$ python3 encoding_text.py
UHl0aG9uIGlzIGZ1bg==
文字列データのエンコードとデコードができるようになったので、バイナリデータのエンコードに挑戦してみよう。
Pythonによるバイナリデータのエンコード
前述したように、Base64エンコーディングは主にバイナリデータをテキストとして表現するために使用されます。
Pythonでは、バイナリファイルを読み込んで、そのバイトをBase64エンコードし、エンコードされた文字列を生成する必要があります。
では、この画像をどのようにエンコードするか見てみましょう。
新しいファイル encoding_binary.py
を作成し、以下を追加します。
新しいファイル encoding_binary.py
を作成し、以下を追加します。
上記のコードスニペットを見てみましょう。
open(‘my_image.png’, ‘rb’)を使ってファイルをオープンします。
ファイルパスと一緒に’rb’という引数を渡していることに注意してください - これは Python にバイナリファイルを読み込んでいることを伝えます。
rb’を使用しない場合、Pythonはテキストファイルを読み込んでいると判断します。
次に read()
メソッドを使って、ファイル内のすべてのデータを binary_file_data
変数に取り込みます。
文字列を扱ったときと同様に、 base64.b64encode
でバイトを Base64 エンコードし、 base64_encoded_data
で decode('utf-8')
を使用して、人間が読める文字で Base64 エンコードしたデータを取得しました。
このコードを実行すると、次のような出力が得られます。
import base64
base64_message = 'UHl0aG9uIGlzIGZ1bg=='
base64_bytes = base64_message.encode('ascii')
message_bytes = base64.b64decode(base64_bytes)
message = message_bytes.decode('ascii')
print(message)
出力は、エンコードする画像によって異なるかもしれません。
PythonでバイナリデータをBase64エンコードする方法がわかったので、次はバイナリデータをBase64デコードしてみましょう。
D
結論
Base64 エンコーディングは、異なるバイナリ形式のデータを ASCII 文字列に変換する一般的な技術です。
これは、生のバイナリデータを処理できないがテキストは容易に処理できるネットワークやアプリケーションにデータを送信するときに便利です。
Pythonでは、base64
モジュールを使って、テキストとバイナリデータをBase64エンコードおよびデコードすることができます。
あなたはどのようなアプリケーションでBase64データのエンコードとデコードを行いますか?