[インデックス 11575] ファイルの概要
このコミットは、Go言語の標準ライブラリである encoding/base32
パッケージに関連する変更です。具体的には、以下の2つのファイルが変更されています。
src/pkg/encoding/base32/base32.go
: Base32エンコーディング/デコーディングの主要なロジックが実装されているファイルです。ここに新しいヘルパーメソッドが追加されました。src/pkg/encoding/base32/base32_test.go
:base32.go
で実装された機能のテストコードが含まれるファイルです。新しいヘルパーメソッドのテストが追加・修正されました。
コミット
commit cce3de7de79f69c4bccc606776f84f0b9a022ac1057
Author: David Symonds <dsymonds@golang.org>
Date: Fri Feb 3 11:52:04 2012 +1100
encoding/base32: add DecodeString and EncodeToString helper methods.
This makes encoding/base32 be consistent with encoding/base64.
R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/5615053
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/cce3de79f69c4bccc606776f84f0b9a022ac1057
元コミット内容
このコミットは、Go言語の encoding/base32
パッケージに DecodeString
および EncodeToString
という2つのヘルパーメソッドを追加するものです。これらのメソッドは、encoding/base64
パッケージが既に提供している同様の機能との一貫性を保つために導入されました。
変更の背景
Go言語の標準ライブラリには、様々なエンコーディング方式を扱う encoding
パッケージ群があります。その中でも encoding/base64
は、バイナリデータをBase64形式の文字列にエンコードしたり、その逆を行ったりするための機能を提供しています。この encoding/base64
パッケージには、バイトスライスと文字列の間で直接変換を行うための便利な EncodeToString
および DecodeString
メソッドが以前から存在していました。
一方、encoding/base32
パッケージは、Base32エンコーディングを扱うためのものですが、base64
パッケージのような直接的な文字列変換ヘルパーメソッドがありませんでした。そのため、Base32エンコードされたバイトスライスを文字列として扱いたい場合や、Base32文字列をデコードしてバイトスライスに戻したい場合には、ユーザーが自分でバッファを確保し、Encode
や Decode
メソッドを呼び出した後に、明示的に型変換を行う必要がありました。
このコミットの目的は、encoding/base32
パッケージのAPIを encoding/base64
パッケージと一貫させることで、開発者がより直感的に、かつ少ないコード量でBase32エンコーディング/デコーディングを扱えるようにすることです。これにより、Go言語の標準ライブラリ全体としての使いやすさと統一性が向上します。
前提知識の解説
Base32エンコーディング
Base32エンコーディングは、バイナリデータをASCII文字列形式に変換するエンコーディング方式の一つです。Base64と同様に、主にバイナリデータをテキストベースのプロトコル(例: 電子メール、URL)で安全に転送するために使用されます。
- 特徴: Base32は、32種類の文字(A-Zと2-7)とパディング文字(=)を使用します。各Base32文字は5ビットの情報を表します。これにより、5バイト(40ビット)のバイナリデータが8文字のBase32文字列に変換されます。
- 用途: Base64と比較して、Base32は生成される文字列が長くなりますが、大文字・小文字の区別がなく、数字も限られているため、手動での入力や読み取りが比較的容易であるという利点があります。また、ファイルシステム名やURLの一部など、特定の文字セットの制約がある環境で利用されることがあります。
Go言語の encoding
パッケージ
Go言語の標準ライブラリには、様々なデータエンコーディングおよびデコーディングを扱うための encoding
パッケージ群が含まれています。これには、encoding/base64
、encoding/base32
、encoding/json
、encoding/xml
などがあります。
encoding/base32
パッケージ: このパッケージは、RFC 4648で定義されているBase32エンコーディングを実装しています。Encoding
型がエンコーディング方式(標準Base32、拡張Hexなど)を定義し、Encode
およびDecode
メソッドがバイトスライス間の変換を行います。encoding/base64
パッケージ: 同様に、RFC 4648で定義されているBase64エンコーディングを実装しています。Encoding
型を持ち、Encode
およびDecode
メソッドに加えて、EncodeToString
およびDecodeString
といった文字列変換ヘルパーメソッドを提供しています。
ヘルパーメソッドの重要性
プログラミングにおいて、特定の操作をより簡単に行えるようにするための補助的な関数やメソッドを「ヘルパーメソッド」と呼びます。このコミットで追加される EncodeToString
と DecodeString
はまさにその典型です。
EncodeToString(src []byte) string
: バイトスライスsrc
を直接Base32エンコードし、結果をstring
型で返します。これにより、ユーザーは自分で出力用のバイトスライスを確保し、string()
にキャストする手間を省くことができます。DecodeString(s string) ([]byte, error)
: Base32エンコードされたstring
型のデータs
を直接デコードし、結果を[]byte
型で返します。これも、入力文字列を[]byte
に変換し、出力バッファを確保する手間を省きます。
これらのヘルパーメソッドの追加は、APIの使いやすさを向上させ、開発者の生産性を高める上で非常に重要です。
技術的詳細
このコミットでは、encoding/base32
パッケージの Encoding
型に以下の2つの新しいメソッドが追加されました。
-
EncodeToString(src []byte) string
:- このメソッドは、入力としてバイトスライス
src
を受け取ります。 - まず、
enc.EncodedLen(len(src))
を呼び出して、エンコード後の文字列に必要なバイト数を計算し、そのサイズのバイトスライスbuf
を作成します。 - 次に、既存の
enc.Encode(buf, src)
メソッドを呼び出して、src
の内容をbuf
にBase32エンコードします。 - 最後に、
string(buf)
を使ってbuf
を文字列に変換し、その結果を返します。 - このメソッドは、エンコード処理中にエラーが発生する可能性がないため、エラー値を返しません。
- このメソッドは、入力としてバイトスライス
-
DecodeString(s string) ([]byte, error)
:- このメソッドは、入力としてBase32エンコードされた文字列
s
を受け取ります。 - まず、
enc.DecodedLen(len(s))
を呼び出して、デコード後のバイトスライスに必要なバイト数を計算し、そのサイズのバイトスライスdbuf
を作成します。 - 次に、既存の
enc.Decode(dbuf, []byte(s))
メソッドを呼び出して、s
の内容(バイトスライスに変換したもの)をdbuf
にBase32デコードします。この際、デコードされたバイト数n
とエラーerr
が返されます。 - 最後に、
dbuf[:n]
を使って実際にデコードされた部分のみを含むスライスを返し、デコード中に発生したエラーerr
も一緒に返します。 - デコード処理は、入力文字列が不正なBase32形式である場合などにエラーを返す可能性があります。
- このメソッドは、入力としてBase32エンコードされた文字列
これらのメソッドは、既存の Encode
および Decode
メソッドを内部的に利用しており、新しいエンコーディング/デコーディングロジックを導入するものではありません。あくまで、バイトスライスと文字列間の変換をより簡潔に行うためのラッパーとして機能します。
テストファイル base32_test.go
では、これらの新しいメソッドが正しく機能するかを確認するためのテストケースが追加されています。特に TestEncode
関数では、以前は手動でバッファを確保して Encode
を呼び出していた部分が、新しく追加された EncodeToString
を使用するように変更され、コードが簡潔になっています。同様に TestDecode
関数では、DecodeString
を呼び出してその結果を検証するテストが追加されています。
コアとなるコードの変更箇所
src/pkg/encoding/base32/base32.go
--- a/src/pkg/encoding/base32/base32.go
+++ b/src/pkg/encoding/base32/base32.go
@@ -125,6 +125,13 @@ func (enc *Encoding) Encode(dst, src []byte) {
}\n
}\n
\n
+// EncodeToString returns the base32 encoding of src.\n
+func (enc *Encoding) EncodeToString(src []byte) string {\n
+\tbuf := make([]byte, enc.EncodedLen(len(src)))\n
+\tenc.Encode(buf, src)\n
+\treturn string(buf)\n
+}\n
+\n
type encoder struct {\n
\terr error\n
\tenc *Encoding\n
@@ -298,6 +305,13 @@ func (enc *Encoding) Decode(dst, src []byte) (n int, err error) {
return\n
}\n
\n
+// DecodeString returns the bytes represented by the base32 string s.\n
+func (enc *Encoding) DecodeString(s string) ([]byte, error) {\n
+\tdbuf := make([]byte, enc.DecodedLen(len(s)))\n
+\tn, err := enc.Decode(dbuf, []byte(s))\n
+\treturn dbuf[:n], err\n
+}\n
+\n
type decoder struct {\n
\terr error\n
\tenc *Encoding\n
src/pkg/encoding/base32/base32_test.go
--- a/src/pkg/encoding/base32/base32_test.go
+++ b/src/pkg/encoding/base32/base32_test.go
@@ -51,9 +51,8 @@ func testEqual(t *testing.T, msg string, args ...interface{}) bool {
\n
func TestEncode(t *testing.T) {\n
\tfor _, p := range pairs {\n
-\t\tbuf := make([]byte, StdEncoding.EncodedLen(len(p.decoded)))\n
-\t\tStdEncoding.Encode(buf, []byte(p.decoded))\n
-\t\ttestEqual(t, \"Encode(%q) = %q, want %q\", p.decoded, string(buf), p.encoded)\n
+\t\tgot := StdEncoding.EncodeToString([]byte(p.decoded))\n
+\t\ttestEqual(t, \"Encode(%q) = %q, want %q\", p.decoded, got, p.encoded)\n
\t}\n
}\n
\n
@@ -99,6 +98,10 @@ func TestDecode(t *testing.T) {\n
\t\ttestEqual(t, \"Decode(%q) = %q, want %q\", p.encoded,\n
\t\t\tstring(dbuf[0:count]),\n
\t\t\tp.decoded)\n
+\n+\t\tdbuf, err = StdEncoding.DecodeString(p.encoded)\n+\t\ttestEqual(t, \"DecodeString(%q) = error %v, want %v\", p.encoded, err, error(nil))\n+\t\ttestEqual(t, \"DecodeString(%q) = %q, want %q\", string(dbuf), p.decoded)\n \t}\n }\n
コアとなるコードの解説
base32.go
の変更
-
EncodeToString
メソッドの追加: このメソッドは、Encoding
型のレシーバーを持つ新しい公開メソッドとして追加されました。内部では、まずenc.EncodedLen
を使ってエンコード後の文字列の長さを計算し、その長さのバイトスライスbuf
を作成します。次に、既存のenc.Encode
メソッドを呼び出して実際のエンコード処理を行い、最後にstring(buf)
でバイトスライスを文字列に変換して返します。これにより、Base32エンコードされた文字列を直接取得できるようになりました。 -
DecodeString
メソッドの追加: 同様に、Encoding
型のレシーバーを持つ新しい公開メソッドとして追加されました。このメソッドは、入力としてBase32エンコードされた文字列s
を受け取ります。内部では、enc.DecodedLen
を使ってデコード後のバイトスライスの長さを計算し、その長さのバイトスライスdbuf
を作成します。そして、既存のenc.Decode
メソッドを呼び出してデコード処理を行い、デコードされたバイト数n
とエラーerr
を取得します。最終的にdbuf[:n]
で実際にデコードされた部分のスライスを返し、エラーも一緒に返します。これにより、Base32文字列を直接デコードしてバイトスライスとして取得できるようになりました。
base32_test.go
の変更
-
TestEncode
関数の修正: 以前は、StdEncoding.Encode
を呼び出す前に手動でbuf
を作成し、その後にstring(buf)
で文字列に変換していました。このコミットでは、新しく追加されたStdEncoding.EncodeToString
メソッドを直接呼び出すように変更され、テストコードがより簡潔になりました。これは、新しいヘルパーメソッドが意図通りに機能していることを示す良い例です。 -
TestDecode
関数の修正: 既存のTestDecode
関数内に、StdEncoding.DecodeString
メソッドをテストするための新しいアサーションが追加されました。これにより、DecodeString
がエラーなく正しくデコードを行い、期待されるバイトスライスを返すことを確認しています。
これらの変更により、encoding/base32
パッケージは encoding/base64
パッケージと同様の使いやすいAPIを提供し、Go言語の標準ライブラリ全体の一貫性が向上しました。
関連リンク
- Go CL 5615053: https://golang.org/cl/5615053
参考にした情報源リンク
- RFC 4648: Base32 Encoding (https://datatracker.ietf.org/doc/html/rfc4648)
- Go言語
encoding/base32
パッケージドキュメント (https://pkg.go.dev/encoding/base32) - Go言語
encoding/base64
パッケージドキュメント (https://pkg.go.dev/encoding/base64) - Go言語のソースコード (https://github.com/golang/go)
- Base32 - Wikipedia (https://ja.wikipedia.org/wiki/Base32)
- Base64 - Wikipedia (https://ja.wikipedia.org/wiki/Base64)