[Go] base64の4つのエンコード方式の違いを整理する
Goのencoding/base64
には以下の4つのエンコーディング方式が定義されています。
- StdEncoding
- URLEncoding
- RawStdEncoding
- RawURLEncoding
この各方式の違いがよくわからなかったのでまとめておきました。
違い
結論から言うと以下です
方式 | 記号 | パディング |
---|---|---|
StdEncoding | +と/ | あり |
URLEncoding | -と_ | あり |
RawStdEncoding | +と/ | なし |
RawURLEncoding | -と_ | なし |
package main
import (
"encoding/base64"
"fmt"
)
func main() {
b := []byte("Hello, セカイ")
s1 := base64.StdEncoding.EncodeToString(b)
fmt.Println(s1) // SGVsbG8sIOOCu+OCq+OCpA==
s2 := base64.URLEncoding.EncodeToString(b)
fmt.Println(s2) // SGVsbG8sIOOCu-OCq-OCpA==
s3 := base64.RawStdEncoding.EncodeToString(b)
fmt.Println(s3) // SGVsbG8sIOOCu+OCq+OCpA
s4 := base64.RawURLEncoding.EncodeToString(b)
fmt.Println(s4) // SGVsbG8sIOOCu-OCq-OCpA
}
StdEncodingとURLEncodingの違い
URL SafeなのがURLEncoding
です。Base64は
-
a~z
の26文字 -
A~Z
の26文字 -
0~9
の10文字 -
+
と/
の2文字
の計64文字で任意のデータを表すエンコード方式です。このうち、+
と/
を用いるものはBase 64 encoding、GoではStdEncoding
と定義されています。
一方で、+
と/
はURLなどにおいて特別な意味を持ち、URL Safeではありません。そのために代わりに
-
+
を-
-
/
を_
としたものがBase 64 URL encoding、GoではURLEncoding
と定義されています。
Raw〇〇Encodingと〇〇Encodingの違い
パディングがないものがRawStdEncoding
とRawURLEncoding
です。この二つは、以下のように定義されています。
var RawStdEncoding = StdEncoding.WithPadding(NoPadding)
var RawURLEncoding = URLEncoding.WithPadding(NoPadding)
Base64におけるパディングは、エンコード後の文字列の長さが4の倍数になっていない場合に、4の倍数になるように付与されるものです。記号は=
が用いられます。
パディングは文字列の長さの調節のために付与されているので、なくともデータの欠損が起きることはありません。なぜ必要なのかはRFCの以下の部分に書いてあります(引用)。
In some circumstances, the use of padding ("=") in base-encoded data
is not required or used. In the general case, when assumptions about
the size of transported data cannot be made, padding is required to
yield correct decoded data.
つまり、データの大きさが推測できない場合に「データの区切り」を明示するために必要です。データの長さがある程度予想できる場合などはパディングが不要ということになります。
参考
Discussion