Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 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文字列をデコードしてバイトスライスに戻したい場合には、ユーザーが自分でバッファを確保し、EncodeDecode メソッドを呼び出した後に、明示的に型変換を行う必要がありました。

このコミットの目的は、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/base64encoding/base32encoding/jsonencoding/xml などがあります。

  • encoding/base32 パッケージ: このパッケージは、RFC 4648で定義されているBase32エンコーディングを実装しています。Encoding 型がエンコーディング方式(標準Base32、拡張Hexなど)を定義し、Encode および Decode メソッドがバイトスライス間の変換を行います。
  • encoding/base64 パッケージ: 同様に、RFC 4648で定義されているBase64エンコーディングを実装しています。Encoding 型を持ち、Encode および Decode メソッドに加えて、EncodeToString および DecodeString といった文字列変換ヘルパーメソッドを提供しています。

ヘルパーメソッドの重要性

プログラミングにおいて、特定の操作をより簡単に行えるようにするための補助的な関数やメソッドを「ヘルパーメソッド」と呼びます。このコミットで追加される EncodeToStringDecodeString はまさにその典型です。

  • EncodeToString(src []byte) string: バイトスライス src を直接Base32エンコードし、結果を string 型で返します。これにより、ユーザーは自分で出力用のバイトスライスを確保し、string() にキャストする手間を省くことができます。
  • DecodeString(s string) ([]byte, error): Base32エンコードされた string 型のデータ s を直接デコードし、結果を []byte 型で返します。これも、入力文字列を []byte に変換し、出力バッファを確保する手間を省きます。

これらのヘルパーメソッドの追加は、APIの使いやすさを向上させ、開発者の生産性を高める上で非常に重要です。

技術的詳細

このコミットでは、encoding/base32 パッケージの Encoding 型に以下の2つの新しいメソッドが追加されました。

  1. EncodeToString(src []byte) string:

    • このメソッドは、入力としてバイトスライス src を受け取ります。
    • まず、enc.EncodedLen(len(src)) を呼び出して、エンコード後の文字列に必要なバイト数を計算し、そのサイズのバイトスライス buf を作成します。
    • 次に、既存の enc.Encode(buf, src) メソッドを呼び出して、src の内容を buf にBase32エンコードします。
    • 最後に、string(buf) を使って buf を文字列に変換し、その結果を返します。
    • このメソッドは、エンコード処理中にエラーが発生する可能性がないため、エラー値を返しません。
  2. 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形式である場合などにエラーを返す可能性があります。

これらのメソッドは、既存の 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言語の標準ライブラリ全体の一貫性が向上しました。

関連リンク

参考にした情報源リンク

  • 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)