⚾
base64コマンドとpadding文字
tl;dr
mac版base64ではpaddingの後の文字列は処理されないよ。
パイプとかで処理する時注意したほうがいいよ。
base64
バイナリをアルファベット(a-zA-Z)、数字(0-9)、いくつかの記号(+/=)でエンコードするフォーマットです。画像などのバイナリデータを、JSONなどテキストで送りたい時に使えます。
padding
base64では24bit毎に4文字に変換します。入力が足りず4文字にならない時に、最後に付ける「=」がpaddingです。
base64コマンド
Linuxやmacではbase64コマンドでbase64のエンコード・デコードを行えます。
特にmacでは、組み込みのbase64コマンドと、GNU版のbase64コマンド(gbase64)コマンドの二種類を使うことが出来ます(※)。
用途・基本的な機能は同じですが、オプションや挙動が少し違います。
※ coreutilsのインストールが必要
base64コマンドのpaddingの扱いの違い
以下の違いがありそうです。
- GNU版base64(gbase64)では、paddingの後の文字列も処理される
- mac版base64では、paddingの後の文字列は処理されない
言及しているWebページを見つけられていないので、何かご存知の方は情報ください…
元データ
「ABCDEFG」、「hogehoge」、「hoge」の三行をbase64エンコードしたファイルです
QUJDREVGRwo=
aG9nZWhvZ2UK
aG9nZQo=
GNU版base64(gbase64)
cat buzz | gbase64 -d
ABCDEFG
hogehoge
hoge
mac版base64
「ABCDEFG」の一行だけ出力されていることに注目してください。
cat buzz | base64 -D
ABCDEFG
どんな影響が?
例えば、
- APIからbase64・paddingを含むJSONを取得
- base64を含む一部分だけを抽出
- base64コマンドでデコード
する時、一連の流れをパイプで繋ぐと、データの見落としやロストが発生しそうです。
回避
ループ
一番簡単・汎用的だと思います。
#!/bin/bash
while read line
do
echo $line | base64 -D
done < buzz
./decode.sh
ABCDEFG
hogehoge
hoge
jqコマンド
JSONに含まれるbase64をデコードしたい時に限れば、jqコマンドは組み込みでbase64のエンコード・デコードができます。
入力データ
cat buzz.json
[
"QUJDREVGRwo=",
"aG9nZWhvZ2UK",
"aG9nZQo="
]
cat buzz.json | jq ".[] | @base64d"
"ABCDEFG\n"
"hogehoge\n"
"hoge\n"
Discussion