🔩

[Go] base64の4つのエンコード方式の違いを整理する

2022/05/03に公開約2,100字

Goのencoding/base64には以下の4つのエンコーディング方式が定義されています。

  • StdEncoding
  • URLEncoding
  • RawStdEncoding
  • RawURLEncoding

この各方式の違いがよくわからなかったのでまとめておきました。

https://pkg.go.dev/encoding/base64

違い

結論から言うと以下です

方式 記号 パディング
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
}

https://go.dev/play/p/R7s6Rvz6hQ0

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の違い

パディングがないものがRawStdEncodingRawURLEncodingです。この二つは、以下のように定義されています。

var RawStdEncoding = StdEncoding.WithPadding(NoPadding)
var RawURLEncoding = URLEncoding.WithPadding(NoPadding)

Base64におけるパディングは、エンコード後の文字列の長さが4の倍数になっていない場合に、4の倍数になるように付与されるものです。記号は=が用いられます。

パディングは文字列の長さの調節のために付与されているので、なくともデータの欠損が起きることはありません。なぜ必要なのかはRFCの以下の部分に書いてあります(引用)。

https://datatracker.ietf.org/doc/html/rfc4648#section-3.2

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.

つまり、データの大きさが推測できない場合に「データの区切り」を明示するために必要です。データの長さがある程度予想できる場合などはパディングが不要ということになります。

参考

https://datatracker.ietf.org/doc/html/rfc4648
https://qiita.com/PlanetMeron/items/2905e2d0aa7fe46a36d4
https://pkg.go.dev/encoding/base64

Discussion

ログインするとコメントできます