ネットワーク経由で転送したいバイナリ イメージ ファイルがあるとします。相手がファイルを正しく受信しなかったのには驚きました。ファイルには奇妙な文字が含まれていただけです。
うーん、ファイルを生のビットとバイトで送信しようとしているようですが、使用しているメディアはテキストのストリーミング用に設計されています。
このような問題を回避するための回避策は何ですか? 答えはBase64エンコーディングです。この記事では、Python を使用してバイナリ イメージをエンコードおよびデコードする方法を説明します。このプログラムはスタンドアロンのローカル プログラムとして示されていますが、この概念は、エンコードされた画像をモバイル デバイスからサーバーに送信するなど、さまざまなアプリケーションに適用できます。
Base64とは何ですか?
この記事に入る前に、Base64 の意味を定義しましょう。
Base64 は、8 ビットのバイナリ データを 6 ビットで表現できる形式にエンコードする方法です。 データを表すために使用される文字は、 データ を埋めるために使用される文字 A-Z
、a-z
、0-9
、 、のみです 。たとえば、このエンコードでは、3 オクテットが 4 つの 6 ビット グループに変換されます。+
/
=
Base64 という用語は、HTTP および XML で広く使用されている MultiPurpose Internet Mail Extensions (MIME) 標準から取られており、元々は送信用に電子メールの添付ファイルをエンコードするために開発されました。
なぜBase64を使用するのでしょうか?
Base64 はバイナリ データ表現にとって非常に重要であるため、バイナリ データをプレーン テキストのように見え、動作する方法で表現できるため、データベースへの保存、電子メールでの送信、または他のアプリケーションでの使用の信頼性が高まります。XML などのテキストベースの形式。Base64 は主に、データを ASCII 文字列形式で表すために使用されます。
この記事の冒頭で述べたように、Base64 がないとデータがまったく読み取れない場合があります。
Base64エンコーディング
Base64 エンコードは、バイナリ データを 64 文字の制限された文字セットに変換するプロセスです。最初のセクションで示したように、これらの文字は A-Z
、a-z
、0-9
、 +
および /
(数えてください、合計すると 64 になることに気づきましたか?) です。この文字セットは最も一般的であると考えられており、MIME の Base64 と呼ばれます。 最初の 62 個の値には と 、 最後の 2 つの値にはA-Z
とが a-z
使用 されます 。0-9
+
/
Base64 でエンコードされたデータは、最終的に元のデータよりも長くなるため、前述したように、バイナリ データの 3 バイトごとに、少なくとも 4 バイトの Base64 エンコード データが存在します。これは、データをより小さい文字セットに圧縮するためです。
以下のような、元の電子メール ファイル (未送信の電子メールである可能性が高い) の一部を見たことはありますか? そうであれば、Base64 エンコーディングが実際に動作しているのを見たことになります。(最後に =
等号が埋め込まれているため、これが Base64 エンコードであることがわかります。)
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: base64
2KfZhNiz2YTYp9mFINi52YTZitmD2YUg2YjYsdit2YXYqSDYp9mE2YTZhyDZiNio2LHZg9in2KrZ
h9iMDQoNCtij2YjYryDZgdmC2Lcg2KfZhNin2LPYqtmB2LPYp9ixINi52YYg2KfZhNmF2YLYsdix
2KfYqiDYp9mE2K/Ysdin2LPZitipINin2YTYqtmKINiq2YbYtdit2YjZhiDYqNmH2Kcg2YTZhdmG
INmK2LHZitivINin2YTYqtmI2LPYuSDZgdmKDQrYt9mE2Kgg2KfZhNi52YTZhSDYp9mE2LTYsdi5
2YrYjCDYudmE2YXYpyDYqNij2YbZiiDYutmK2LEg2YXYqtiu2LXYtSDYqNin2YTYudmE2YUg2KfZ
hNi02LHYudmKINmI2KPZgdiq2YLYryDZhNmE2YXZhtmH2Kwg2KfZhNi52YTZhdmKDQrZhNiw2YTZ
gy4NCg0K2KzYstin2YPZhSDYp9mE2YTZhyDYrtmK2LHYpyDYudmE2Ykg2YbYtdit2YPZhSDZgdmK
INmH2LDYpyDYp9mE2LTYo9mGLg0KDQrYudio2K/Yp9mE2LHYrdmF2YYNCg==
--089e0141aa264e929a0514593016
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: base64
Base64 は、次のように複数の手順で実行されます。
- エンコードされるテキストは、それぞれの 10 進数値、つまり対応する ASCII 値 (a:97、b:98 など) に変換されます。これは ASCII テーブルです。
- 上記の手順で取得した 10 進数値を等価な 2 進数値 (97: 01100001) に変換します。
- すべての等価な 2 進数を連結して、多数の 2 進数のセットを取得します。
- 2 進数の大きな山は、それぞれ 6 ビットのみを含む等しい部分に分割されます。
- 等しい 6 ビット グループは、同等の 10 進数に変換されます。
- 最後に、等価な 10 進数が Base64 値 (つまり 4:E) に変換されます。以下は、10 進数値とその Base64 アルファベットです。
Base64デコード
Base64 デコードは、Base64 エンコードの逆です。つまり、前のセクションで説明した手順を逆に行うことで実行されます。
したがって、Base64 デコードの手順は次のように説明できます。
- 文字列内の各文字は、Base64 10 進数値に変更されます。
- 取得した 10 進数値は、同等の 2 進数値に変換されます。
- 取得した各 2 進数から 2 進数の最初の 2 桁を切り捨て、6 ビットのグループを結合して、2 進数の大きな文字列を形成します。
- 前の手順で取得した 2 進数の大きな文字列を 8 ビットのグループに分割します。
- 8 ビットの 2 進数は、同等の 10 進数に変換されます。
- 最後に、取得した 10 進値を対応する ASCII 値に変換します。
文字列のBase64エンコードとデコード
舞台裏で何が起こっているかを理解すると、すべてがどのように機能するかを理解するのが簡単になります。単純な 3 文字の単語 のエンコードとデコードを試してみましょうHey
。
まず単語の各文字を対応する ASCII 文字に変換し、次に対応する ASCII をバイナリに変換します。これにより、次の値が得られます。
手紙 | ASCII インデックス値 | 8ビットのバイナリ値 |
---|---|---|
H | 72 | 01001000 |
e | 101 | 01100101 |
y | 121 | 01111001 |
言い換えれば、次のようにバイナリで書くことができます Hey
。
01001000 01100101 01111001
これは合計 24 ビットで、6 ビットのグループに変換すると、各ビットは 4 つの値を生成します。
010010 000110 010101 111001
Base64 テーブルでは、文字は 0 ~ 25 の値で 表されA
ます 。文字は 26 ~ 51の 値 で 表されます 。数値は 52 ~ 61 の値で 表され ます 。文字の合計は 62 と 63 で 表され ます 。 ビットを 6 つのグループに適切にグループ化できない場合、文字は パディングに使用されます。Z
a
z
0
9
+
/
=
次に、並べ替えたビットを数値に変換し、その数値を表す文字を取得します。
6ビットのバイナリ値 | Base64 インデックス値 | 手紙 |
---|---|---|
010010 | 18 | 小さい |
000110 | 6 | G |
010101 | 21 | V |
111001 | 57 | 5 |
上記の計算によると、Base64 でエンコードすると文字は Hey
になります SGV5
。次のコードを使用して、これが正しいかどうかをテストできます。
from base64 import b64encode
text_binary = b'Hey'
# SGV5
print(b64encode(text_binary))
プロセス全体が逆になり、Base64 デコード後に元のデータが取得されます。
Heyo
ここで、エンコードされた文字列内の出現を考慮した別の単語のエンコードを 簡単に説明します =
。
手紙 | ASCII インデックス値 | 8ビットのバイナリ値 |
---|---|---|
H | 72 | 01001000 |
e | 101 | 01100101 |
y | 121 | 01111001 |
ああ | 111 | 01101111 |
合計32ビットあります。これにより、残りの 2 ビットを含む 5 つの異なる 6 ビット グループが得られます11
。それらをパディング 0000
して 6 ビットのグループを取得します。上記の順列に従って 6 ビットをグループ化すると、次の結果が得られます。
010010 000110 010101 111001 011011 110000
再配置されたビットは、Base64 インデックス値に基づいて次の文字を返します。
6ビットのバイナリ値 | Base64 インデックス値 | 手紙 |
---|---|---|
010010 | 18 | 小さい |
000110 | 6 | G |
010101 | 21 | V |
111001 | 57 | 5 |
011011 | 27 | b |
110000 | 48 | w |
これは、 Heyo
Base64 でエンコードされた の値を 意味しますSGV5bw==
。それぞれは =
ペアを表し 00
、元のビット シーケンスを満たすために追加します。
from base64 import b64encode
text_binary = b'Heyo'
# SGV5bw==
print(b64encode(text_binary))
画像をBase64エンコードする
それでは、この記事の要点を見ていきましょう。このセクションでは、Python を使用して画像を簡単に Base64 エンコードする方法を説明します。
以下のバイナリイメージを使用します。早速ダウンロードして、Python を使い始めましょう! (画像の名前は deer.gifであるとします。)
Python で Base64 を使用するには、最初に Base64 モジュールをインポートする必要があります。
导入base64
画像をエンコードするには、関数を使用するだけです base64.b64encode(s)
。Python では、この関数を次のように説明します。
Base64 を使用してバイトのようなオブジェクト をエンコードし
s
、エンコードされたバイトを返します。
したがって、次のようにして画像を Base64 エンコードできます。
import base64
image = open('deer.gif', 'rb') #open binary file in read mode
image_read = image.read()
image_64_encode = base64.b64encode(image_read)
エンコード プロセスの出力を確認したい場合は、次のように入力します。
打印 image_64_encode
Base64でデコードされた画像
Python を使用して画像をデコードするには、 base64.b64decode(s)
関数を使用するだけです。Python はこの関数について次のように述べています。
Base64 でエンコードされたバイトのようなオブジェクトまたは ASCII 文字列をデコードし、デコードされたバイトを返します。
したがって、前のセクションでエンコードした画像をデコードするには、次の操作を行います。
base64.decode(image_64_encode)
それらを一緒にします
画像をBase64でエンコード・デコードするプログラムを組んでみましょう。これを行うための Python スクリプトは次のようになります。
import base64
image = open('deer.gif', 'rb')
image_read = image.read()
image_64_encode = base64.b64encode(image_read)
image_64_decode = base64.b64decode(image_64_encode)
image_result = open('deer_decode.gif', 'wb') # create a writable image and write the decoding result
image_result.write(image_64_decode)
デスクトップで deer_decode.gifを開くと、手順 1 でエンコードした 元のイメージdeer.gifがあることがわかります。
この記事からわかるように、Python を使用すると、一見複雑なタスクを非常に簡単に実行できます。
URL セーフなエンコードとデコード
このチュートリアルの前半で述べたように、Base64 エンコードでは、通常の英数字の値に加えて、 文字+
と が 使用されます/
。ただし、これらの文字は URL において特別な意味を持ちます。これは、これらの文字を使用した Base64 エンコード値を URL 内で使用すると、予期しない動作が発生する可能性があることを意味します。
この問題に対する 1 つの解決策は、 urlsafe_base64encode()
および urlsafe_base64decode()
関数を使用してデータをエンコードおよびデコードすることです。これらの関数はコーディング 中に に +
置き換えられます 。-
/
_
違いを示す Python の例を次に示します。
import base64
image = open('dot.jpg', 'rb')
image_data = image.read()
unsafe_encode = base64.b64encode(image_data)
safe_encode = base64.urlsafe_b64encode(image_data)
# b'/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNr....
print(unsafe_encode)
# b'_9j_4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP_sABFEdWNr....
print(safe_encode)
Pythonを学ぶ
初心者でも、新しいスキルを習得したいと考えている経験豊富なプログラマーでも、完全な Python チュートリアル ガイドで Python を学習してください。
この記事は Nitish Kumar からの寄稿により更新されました。Nitish は、さまざまなプラットフォームで電子商取引 Web サイトを作成した経験を持つ Web 開発者です。彼は余暇を、日常生活を楽にする個人的なプロジェクトに取り組んだり、友人と夜の散歩をしたりして過ごしています。