Base64 や Base32 は任意のビット列(バイナリデータでも可)を文字列に変換する符号化方式です.Python では base64 モジュールをインポートすると簡単に符号化可能です.あらかじめプログラムの先頭で次のとおりインポートを行ってください.
import base64
Base64 は任意のビット列を64種類の文字(アルファベット「A-Z, a-Z」,数字 「0-9」,および「+」「/」)からなる文字列に変換する符号化方式です.例えば「KOBE」という文字列を Base64 でエンコードするコードは次のようになります.具体的には,3行目で文字列をバイト列に変換した後,4行目ではバイト列を Base64 に符号化し,「b'S09CRQ=='」という結果を得ました.ただし,得られた結果はまだバイト列のままであることに注意してください.
text = "KOBE"
# text = "神戸学院"
data = text.encode("utf-8") # 文字列をバイト列に符号化
b64 = base64.b64encode(data) # バイト列を Base64 で符号化
print(b64)
print(type(b64)) # まだバイト列
b'S09CRQ==' <class 'bytes'>
Base64 の結果を文字列形式で取得するには次のようにすると良いでしょう.
text = "KOBE"
# text = "神戸学院"
data = text.encode("utf-8") # 文字列をバイト列に符号化
s_b64 = base64.b64encode(data).decode("ascii") # バイト列を Base64 で符号化し,さらに ASCII 文字列に復号
print(s_b64)
print(type(s_b64))
S09CRQ== <class 'str'>
なお,「KOBE」のようなASCII文字列だけでなく「神戸学院」のような非アスキー文字列であっても Base64 で符号化できることを確認してください.もちろん,文字列だけでなく任意のバイナリデータを符号化可能です.
Base64 で符号化された文字列を復号するには次のコードを利用すると良いでしょう.具体的には,バイト列を b64decode() で復号(デコード)した後,これをさらに文字列に復号します.
s_b64 = "S09CRQ=="
b64 = s_b64.encode("utf-8") # 文字列をバイト列に符号化
text = base64.b64decode(b64).decode("utf-8") # バイト列をBase64でデコードしてさらに文字列にデコード
print(text)
KOBE
以上のとおり「KOBE」という文字列を Base64 で符号化すると「S09CRQ==」になりました.また逆に「S09CRQ==」から「KOBE」を得ることもできました.具体的にどのような処理が行われているかは次で確認します.
Base32は任意のビット列を32種類の文字(大文字アルファベット「A-Z」と数字「2-7」)からなる文字列に変換する符号化方式です.例えば「KOBE」という文字列を Base32 でエンコードするコードは次のようなります.具体的には,3行目で文字列をバイト列に変換した後,4行目ではバイト列を Base32 に符号化し,「b'JNHUERI='」という結果を得ました.ただし,得られた結果はまだバイト列のままであることに注意してください.
text = "KOBE"
# text = "神戸学院"
data = text.encode("utf-8") # 文字列をバイト列に符号化
b32 = base64.b32encode(data) # バイト列を Base32 で符号化
print(b32)
print(type(b32)) # まだバイト列
b'JNHUERI=' <class 'bytes'>
Base32 の結果を文字列形式で取得するには次のようにすると良いでしょう.
text = "KOBE"
# text = "神戸学院"
data = text.encode("utf-8") # 文字列をバイト列に符号化
s_b32 = base64.b32encode(data).decode("ascii") # バイト列を Base32 で符号化し,さらに ASCII 文字列に復号
print(s_b32)
print(type(s_b32))
JNHUERI= <class 'str'>
なお,「KOBE」のようなASCII文字列だけでなく「神戸学院」のような非アスキー文字列であっても Base32 で符号化できることを確認してください.もちろん,文字列だけでなく任意のバイナリデータを符号化可能です.
Base32 で符号化された文字列を復号するには次のコードを利用すると良いでしょう.具体的には,バイト列を b32decode() で復号(デコード)した後,これをさらに文字列に復号します.
s_b32 = "JNHUERI="
b32 = s_b32.encode("utf-8") # 文字列をバイト列に符号化
text = base64.b32decode(b32).decode("utf-8") # バイト列をBase32でデコードしてさらに文字列にデコード
print(text)
KOBE
以上のとおり「KOBE」という文字列を Base32 で符号化すると「JNHUERI=」になりました.また逆に「JNHUERI=」から「KOBE」を得ることもできました.具体的にどのような処理が行われているかは次で確認します.
データを Base64 エンコードする手順は次のとおりです.
データを Base32 エンコードする手順も次のとおりです.
2進 |
文字 |
2進 |
文字 |
|
|---|---|---|---|---|
| 000000 | A | 100000 | g | |
| 000001 | B | 100001 | h | |
| 000010 | C | 100010 | i | |
| 000011 | D | 100011 | j | |
| 000100 | E | 100100 | k | |
| 000101 | F | 100101 | l | |
| 000110 | G | 100110 | m | |
| 000111 | H | 100111 | n | |
| 001000 | I | 101000 | o | |
| 001001 | J | 101001 | p | |
| 001010 | K | 101010 | q | |
| 001011 | L | 101011 | r | |
| 001100 | M | 101100 | s | |
| 001101 | N | 101101 | t | |
| 001110 | O | 101110 | u | |
| 001111 | P | 101111 | v | |
| 010000 | Q | 110000 | w | |
| 010001 | R | 110001 | x | |
| 010010 | S | 110010 | y | |
| 010011 | T | 110011 | z | |
| 010100 | U | 110100 | 0 | |
| 010101 | V | 110101 | 1 | |
| 010110 | W | 110110 | 2 | |
| 010111 | X | 110111 | 3 | |
| 011000 | Y | 111000 | 4 | |
| 011001 | Z | 111001 | 5 | |
| 011010 | a | 111010 | 6 | |
| 011011 | b | 111011 | 7 | |
| 011100 | c | 111100 | 8 | |
| 011101 | d | 111101 | 9 | |
| 011110 | e | 111110 | + | |
| 011111 | f | 111111 | / |
2進 |
文字 |
2進 |
文字 |
|
|---|---|---|---|---|
| 00000 | A | 10000 | Q | |
| 00001 | B | 10001 | R | |
| 00010 | C | 10010 | S | |
| 00011 | D | 10011 | T | |
| 00100 | E | 10100 | U | |
| 00101 | F | 10101 | V | |
| 00110 | G | 10110 | W | |
| 00111 | H | 10111 | X | |
| 01000 | I | 11000 | Y | |
| 01001 | J | 11001 | Z | |
| 01010 | K | 11010 | 2 | |
| 01011 | L | 11011 | 3 | |
| 01100 | M | 11100 | 4 | |
| 01101 | N | 11101 | 5 | |
| 01110 | O | 11110 | 6 | |
| 01111 | P | 11111 | 7 |
Base64 で符号化される様子を詳細に確認します.まず,「KOBE」という文字列をバイト列にエンコードした結果を確認します.これは,ASCIIコード表を参照すると理解できることでしょう.
text = "KOBE"
data = text.encode("utf-8")
for c in data:
print(f'{c:#010b}', end=" ")
0b01001011 0b01001111 0b01000010 0b01000101
バイト列が得られたので,上の手順どおり処理を行っていきます.
上の結果は8ビットごとに区切られているので,6ビットごとに分割し直します.
01001011 01001111 01000010 01000101 010010 110100 111101 000010 010001 01
最後のブロックが2ビットしかないため,「0」を追加します.
010010 110100 111101 000010 010001 01 010010 110100 111101 000010 010001 010000
「010010」→「S」のように変換します.
010010 110100 111101 000010 010001 010000 S 0 9 C R Q
4文字ごとに分割すると最後のブロックが2文字しかないため,最後に「=」を追加します.
S09CRQ S09C RQ S09C RQ== S09CRQ==
この作業で「KOBE」という文字列が「S09CRQ==」に変換されました.これは上の結果と等しいことが分かります.また,逆の手順で処理を行うとデコードも行えます.
同じように Base32 についても上の手順どおり処理を行っていきます.
上の結果は8ビットごとに区切られているので,5ビットごとに分割し直します.
01001011 01001111 01000010 01000101 01001 01101 00111 10100 00100 10001 01
最後のブロックが2ビットしかないため,「0」を追加します.
01001 01101 00111 10100 00100 10001 01 01001 01101 00111 10100 00100 10001 01000
「01001」→「J」のように変換します.
01001 01101 00111 10100 00100 10001 01000 J N H U E R I
ブロックが7文字しかないため,最後に「=」を追加します.
JNHUERI JNHUERI=
この作業で「KOBE」という文字列が「JNHUERI=」に変換されました.これは上の結果と等しいことが分かります.また,逆の手順で処理を行うとデコードも行えます.