base64 – バイナリデータを ASCII 文字へエンコードする

目的:base64 モジュールは、プレーンテキストプロトコルによる通信に適した ASCII 文字のサブセットへバイナリデータを変換する機能を持ちます。
利用できるバージョン:1.4 以上

base64, base32 と base16 エンコーディングは、例えば SMTP のような、プレーンな ASCII 文字を必要とするプロトコルの通信で ASCII 文字としてエンコードされるように非 ASCII 文字を許容して、8ビットのバイト値を1バイト毎に扱い易い 6, 5 又は 4ビットに変換します。 基数 となる値は各々のエンコーディングで使用されるアルファベットの長さに対応します。また、少し違う結果を使用するオリジナルエンコーディングの URL セーフな変形もあります。

Base64 エンコーディング

基本的なテキストのエンコーディング例は次のようになります:

import base64

# このソースファイルを読み込んでヘッダを取り除きます
initial_data = open(__file__, 'rt').read().split('#end_pymotw_header')[1]

encoded_data = base64.b64encode(initial_data)

num_initial = len(initial_data)
padding = { 0:0, 1:2, 2:1 }[num_initial % 3]

print '%d bytes before encoding' % num_initial
print 'Expect %d padding bytes' % padding
print '%d bytes after encoding' % len(encoded_data)
print
# encoded_data を表示する
for i in xrange((len(encoded_data)/40)+1):
    print encoded_data[i*40:(i+1)*40]

その出力はオリジナルソースが558バイトだとすると、エンコードされると744バイトに展開されます。

Note

本来ライブラリが生成した出力には改行がありません。そのため、本ページ上で見易いようにわざとエンコードデータを改行しています。

$ python base64_b64encode.py
145 bytes before encoding
Expect 2 padding bytes
196 bytes after encoding

CgppbXBvcnQgYmFzZTY0CgojIOOBk+OBruOCveOD
vOOCueODleOCoeOCpOODq+OCkuiqreOBv+i+vOOC
k+OBp+ODmOODg+ODgOOCkuWPluOCiumZpOOBjeOB
vuOBmQppbml0aWFsX2RhdGEgPSBvcGVuKF9fZmls
ZV9fLCAncnQnKS5yZWFkKCkuc3BsaXQoJw==

Base64 デコーディング

エンコードされた文字列は、可逆的に4バイトからオリジナルの3バイトへ変換することでオリジナルの文字列へ戻すことができます。 b64decode() がその機能になります。

import base64

original_string = 'This is the data, in the clear.'
print 'Original:', original_string

encoded_string = base64.b64encode(original_string)
print 'Encoded :', encoded_string

decoded_string = base64.b64decode(encoded_string)
print 'Decoded :', decoded_string

エンコーディング処理は24ビット(3バイト)の入力シーケンスを見て、その24ビットの入力から4バイトへ展開した出力へエンコードします。最後の2文字 == はパディングになります。オリジナル文字列のビット数がこの例ではちょうど24ビットで分割できるサイズではなかったからです。

$ python base64_b64decode.py
Original: This is the data, in the clear.
Encoded : VGhpcyBpcyB0aGUgZGF0YSwgaW4gdGhlIGNsZWFyLg==
Decoded : This is the data, in the clear.

URL セーフな変形

デフォルトの base64 のアルファベットは +/ が使用されるかもしれません。その2つの文字は URL の文字列内でも使用されます。そのため、その2つの文字は代替のエンコーディング文字へ置換する必要性がありました。そして +-/ はアンダースコア(_) に置換されました。他の部分のアルファベットは同じです。

import base64

for original in [ chr(251) + chr(239), chr(255) * 2 ]:
    print 'Original         :', repr(original)
    print 'Standard encoding:', base64.standard_b64encode(original)
    print 'URL-safe encoding:', base64.urlsafe_b64encode(original)
    print
$ python base64_urlsafe.py
Original         : '\xfb\xef'
Standard encoding: ++8=
URL-safe encoding: --8=

Original         : '\xff\xff'
Standard encoding: //8=
URL-safe encoding: __8=

その他のエンコーディング

このモジュールは base64 に加えて、base32 と base16(16進数) でデータをエンコードする機能も提供します。

import base64

original_string = 'This is the data, in the clear.'
print 'Original:', original_string

encoded_string = base64.b32encode(original_string)
print 'Encoded :', encoded_string

decoded_string = base64.b32decode(encoded_string)
print 'Decoded :', decoded_string
$ python base64_base32.py
Original: This is the data, in the clear.
Encoded : KRUGS4ZANFZSA5DIMUQGIYLUMEWCA2LOEB2GQZJAMNWGKYLSFY======
Decoded : This is the data, in the clear.

base16 の機能は16進数のアルファベットを出力します。

import base64

original_string = 'This is the data, in the clear.'
print 'Original:', original_string

encoded_string = base64.b16encode(original_string)
print 'Encoded :', encoded_string

decoded_string = base64.b16decode(encoded_string)
print 'Decoded :', decoded_string
$ python base64_base16.py
Original: This is the data, in the clear.
Encoded : 546869732069732074686520646174612C20696E2074686520636C6561722E
Decoded : This is the data, in the clear.

See also

base64
本モジュールの標準ライブラリドキュメント
RFC 3548
Base16, Base32 と Base64 データエンコーディング
Bookmark and Share