PythonでBase64を使ってエンコード・デコードする

267, 2021-06-10

目次

PythonでBase64を使ってエンコード・デコードをする

Pythonではbase64というモジュールを使うとBase64によるエンコード・デコードを行うことができます。
この記事ではBase64とはなにか? というところから解説し、エンコード、デコード方法を解説します。

結論から言うとBase64のエンコードとデコードは↓のように行います。

from base64 import b64encode, b64decode


encoded = b64encode('本日は晴天なり'.encode())
print(encoded)
# b'5pys5pel44Gv5pm05aSp44Gq44KK'

decoded = b64decode(encoded)
print(decoded.decode())
# 本日は晴天なり

この記事では具体的に↓を見ていきます。

  • Base64とは?

  • エンコードとデコードとは?

  • b64encode()の構造

  • b64encode()でエンコードする

  • b64decode()の構造

  • b64decode()でデコードする

参考
base64 --- Base16, Base32, Base64, Base85 データの符号化 — Python 3.9.4 ドキュメント

Base64とは?

Base64とはエンコード方式のことを言います。
このエンコード方式では、データ(バイナリ)を印字可能な英数字記号のみのバイト列に変換します。
英数字はa-z, A-Z, 0-9の範囲で記号は+, /の2つと余った部分を詰めるパディングとして=が使われます。

  • a-z

  • A-Z

  • 0-9

  • +, /

  • =

Base64は電子メールなどでよく利用されます。
印字出来ないバイナリデータをBase64でエンコードしてメールに添付し、メールを受信した人はそのデータをBase64でデコードして確認します。
こうすることで電子メール上でバイナリデータを扱うことができます。

変換コストとしては元のデータに比べて変換後のデータの容量が増加することが挙げられます。
Base64によるエンコードのデータ量は元のデータに比べて約133%ほどになります(33%増加)。

エンコードとデコードとは?

エンコードとは符号化という意味です。
これは特定のデータにアナログ、あるいはデジタル的な加工を加えます。
また加工後のデータは元に戻せるという特徴があります。
今回の例で言うとBase64のエンコードでバイト列を英数字の羅列に変換することがこれに当たります。

またデコードとはエンコードしたデータを元に戻すことを指します。

エンコード/デコードはセットで使われることが多い概念です。
エンコードで符号化したデータを元に戻すのがデコード、と覚えておくと良さそうです。

今回の場合、Base64のエンコードにはbase64.b64encode()を使います。
またデコードにはbase64.b64decode()を使います。

b64encode()の構造

Base64のエンコードを行うbase64モジュールのb64encode()は↓のような構造をしています。

base64.b64encode(s, altchars=None)

第1引数のsにはバイト列かバイト列に類するオブジェクトを渡します。これがエンコード対象です。

第2引数のaltcharsには最低でも長さが2のバイト列で、+/の代わりになるアルファベットを指定します。
デフォルトではNoneで、Noneの場合はBase64の標準のアルファベットが使われます。
第2引数の存在意義ですが、この代替文字を指定することで、URLやファイルシステムのパスに影響されないバイト列を生成することが出来ます。普通に使うと/がURLやパスに引っかかりますよね。

返り値はエンコードされたバイト列です。

b64encode()でエンコードする

b64encode()でエンコードを行うには↓のようにします。

from base64 import b64encode


s = '本日は晴天なり'
encoded = b64encode(s.encode())

print(encoded)
# b'5pys5pel44Gv5pm05aSp44Gq44KK'

↑の場合、「本日は晴天なり」という文字列が保存された変数sがエンコード対象の文字列です。
これをb64encode()に渡します。このときs.encode()で文字列をバイト列に変換しておきます。
その結果が返り値として返ってきますので、それをprint()で出力しています。

b64decode()の構造

Base64のデコードを行うbase64モジュールのb64decode()は↓のような構造になっています。

base64.b64decode(s, altchars=None, validate=False)

第1引数のsにはバイト列かバイト列に類するオブジェクトを渡します。これがデコード対象です。

第2引数のaltcharsb64encode()の場合と同じです。そちらの解説を参照してください。

第3引数のvalidateTrueの場合、sにBase64のアルファベット以外の文字がある場合に例外binascii.Errorを送出します。
Falseの場合は対応できない文字の場合にスキップします。

b64decode()でデコードする

b64decode()でデコードを行う場合は↓のようにします。

from base64 import b64encode, b64decode


s = '本日は晴天なり'
encoded = b64encode(s.encode())
decoded = b64decode(encoded)

print(decoded)
# b'\xe6\x9c\xac\xe6\x97\xa5\xe3\x81\xaf\xe6\x99\xb4\xe5\xa4\xa9\xe3\x81\xaa\xe3\x82\x8a'

print(decoded.decode())
# 本日は晴天なり

↑の場合、sが入力です。これを最初にb64encode()でエンコードします。その結果がencodedです。
このencodedb64decode()でデコードして、decodedというバイト列にします。
バイト列なので日本語は↑のようなバイトの羅列になっていますが、これはバイト列のメソッドdecode()を使うと認識可能な日本語にすることができます。

おわりに

今回はPythonでBase64のエンコードとデコードを扱ってみました。

64ビットだぜ

それはゲーム機でしょ