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

[インデックス 14087] ファイルの概要

このコミットは、Go言語の標準ライブラリであるencoding/base32およびencoding/base64パッケージに、それぞれのエンコーディングおよびデコーディング機能の使用例を追加するものです。これにより、これらのパッケージの利用方法がより明確になり、開発者がコードを理解しやすくなります。

コミット

commit 05e4e805e0367ef9688c95bcecad4b8d3efc0584
Author: David Symonds <dsymonds@golang.org>
Date:   Tue Oct 9 08:56:34 2012 +1100

    encoding/base{32,64}: add examples.
    
    Fixes #4136.
    
    R=golang-dev, r
    CC=golang-dev
    https://golang.org/cl/6615061

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/05e4e805e0367ef9688c95bcecad4b8d3efc0584

元コミット内容

このコミットは、encoding/base32encoding/base64パッケージに、それぞれのエンコーディングとデコーディングの具体的な使用例を追加します。これにより、これらのパッケージの機能がどのように利用されるべきかを示す、実用的なコードスニペットが提供されます。特に、ExampleEncoding_EncodeToStringExampleEncoding_DecodeStringという関数が追加され、それぞれ文字列のエンコードとデコードのプロセスを示しています。これらの例は、GoのテストフレームワークのExample機能を利用しており、ドキュメントとしても機能します。

変更の背景

このコミットは、GoのIssue #4136を修正するために行われました。Issue #4136は、encoding/base32およびencoding/base64パッケージにExampleコードが不足していることを指摘していました。Goの標準ライブラリでは、各パッケージの機能を示すExampleコードを提供することが推奨されており、これにより開発者がライブラリの利用方法を迅速に理解できるようになります。Exampleコードは、単なるドキュメントとしてだけでなく、テストとしても機能し、コードの変更によってExampleの出力が変わらないことを保証します。このコミットは、これらの重要なパッケージのドキュメントと使いやすさを向上させることを目的としています。

前提知識の解説

Base32/Base64エンコーディング

Base32およびBase64は、バイナリデータをASCII文字列形式に変換するためのエンコーディング方式です。主に、バイナリデータをテキストベースのプロトコル(例: 電子メール、HTTPヘッダー)で安全に転送するために使用されます。

  • Base64: 64種類のASCII文字(A-Z, a-z, 0-9, +, /)とパディング文字(=)を使用してバイナリデータを表現します。3バイトのバイナリデータを4文字のBase64文字列に変換するため、データサイズは約33%増加します。WebサービスやAPIで広く利用されています。
  • Base32: 32種類のASCII文字(A-Z, 2-7)とパディング文字(=)を使用してバイナリデータを表現します。5バイトのバイナリデータを8文字のBase32文字列に変換するため、データサイズは約60%増加します。Base64よりも効率は低いですが、大文字・小文字の区別がなく、特定の環境(例: ファイルシステム名、DNS名)での利用に適しています。

Go言語のencodingパッケージ

Go言語の標準ライブラリには、様々なエンコーディング方式を扱うためのencodingパッケージ群が含まれています。

  • encoding/base32: Base32エンコーディングを扱うためのパッケージです。
  • encoding/base64: Base64エンコーディングを扱うためのパッケージです。

これらのパッケージは、Encoding型を提供し、EncodeToStringDecodeStringといったメソッドを通じて、バイトスライスと文字列間の変換機能を提供します。

Go言語のExampleテスト

Go言語のテストフレームワークには、Exampleテストという特殊な機能があります。これは、Exampleプレフィックスを持つ関数として定義され、その関数の出力がコメントとして記述された// Output:行と一致するかどうかを検証します。Exampleテストは、以下の点で非常に有用です。

  1. ドキュメント: コードの具体的な使用例を直接示すため、開発者がライブラリの使い方を理解しやすくなります。
  2. テスト: Exampleの出力が常に期待通りであることを保証するため、コードの変更によってExampleの動作が壊れていないかを自動的に検証します。
  3. GoDocとの統合: go docコマンドやGoの公式ドキュメントサイト(pkg.go.devなど)で、Exampleコードが自動的に表示されます。

技術的詳細

このコミットでは、encoding/base32encoding/base64パッケージのExampleテストファイルが追加されています。

src/pkg/encoding/base32/example_test.go

このファイルでは、base32_testパッケージとして、以下の2つのExample関数が定義されています。

  • ExampleEncoding_EncodeToString():

    • data := []byte("any + old & data")というバイトスライスを定義します。
    • base32.StdEncoding.EncodeToString(data)を使用して、このバイトスライスをBase32文字列にエンコードします。StdEncodingは、標準のBase32エンコーディング(RFC 4648)を表します。
    • fmt.Println(str)でエンコード結果を出力します。
    • // Output: MFXHSIBLEBXWYZBAEYQGIYLUME======というコメントにより、期待される出力が定義されており、テスト時にこの出力と実際の出力が比較されます。
  • ExampleEncoding_DecodeString():

    • str := "ONXW2ZJAMRQXIYJAO5UXI2BAAAQGC3TEEDX3XPY="というBase32エンコードされた文字列を定義します。
    • base32.StdEncoding.DecodeString(str)を使用して、この文字列をバイトスライスにデコードします。
    • エラーハンドリングも含まれており、デコード中にエラーが発生した場合はその旨を出力します。
    • fmt.Printf("%q\\n", data)でデコード結果を引用符で囲んで出力します。%qフォーマット動詞は、文字列をGoの構文で表現し、非表示文字をエスケープして表示します。
    • // Output: "some data with \\x00 and \\ufeff"というコメントにより、期待される出力が定義されています。この出力には、ヌルバイト(\x00)やBOM(Byte Order Mark、\ufeff)のような特殊文字が含まれていることが示唆されており、デコードが正しく行われることを確認しています。

src/pkg/encoding/base64/example_test.go

このファイルも同様に、base64_testパッケージとして、以下の2つのExample関数が定義されています。

  • ExampleEncoding_EncodeToString():

    • data := []byte("any + old & data")というバイトスライスを定義します。
    • base64.StdEncoding.EncodeToString(data)を使用して、このバイトスライスをBase64文字列にエンコードします。StdEncodingは、標準のBase64エンコーディング(RFC 4648)を表します。
    • fmt.Println(str)でエンコード結果を出力します。
    • // Output: YW55ICsgb2xkICYgZGF0YQ==というコメントにより、期待される出力が定義されています。
  • ExampleEncoding_DecodeString():

    • str := "c29tZSBkYXRhIHdpdGggACBhbmQg77u/"というBase64エンコードされた文字列を定義します。
    • base64.StdEncoding.DecodeString(str)を使用して、この文字列をバイトスライスにデコードします。
    • エラーハンドリングも含まれています。
    • fmt.Printf("%q\\n", data)でデコード結果を引用符で囲んで出力します。
    • // Output: "some data with \\x00 and \\ufeff"というコメントにより、期待される出力が定義されています。ここでも、ヌルバイトやBOMのような特殊文字のデコードが正しく行われることを確認しています。

これらのExampleテストは、Goの標準的なテストコマンドであるgo testを実行する際に自動的に実行され、期待される出力と実際の出力が比較されます。これにより、これらのエンコーディング/デコーディング機能が正しく動作していることが保証されます。

コアとなるコードの変更箇所

このコミットでは、既存のコードの変更ではなく、新しいファイルが2つ追加されています。

  1. src/pkg/encoding/base32/example_test.go
  2. src/pkg/encoding/base64/example_test.go

それぞれのファイルは、Base32およびBase64エンコーディング/デコーディングのExample関数を含んでいます。

コアとなるコードの解説

src/pkg/encoding/base32/example_test.go

// Copyright 2012 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package base32_test

import (
	"encoding/base32"
	"fmt"
)

func ExampleEncoding_EncodeToString() {
	data := []byte("any + old & data")
	str := base32.StdEncoding.EncodeToString(data)
	fmt.Println(str)
	// Output:
	// MFXHSIBLEBXWYZBAEYQGIYLUME======
}

func ExampleEncoding_DecodeString() {
	str := "ONXW2ZJAMRQXIYJAO5UXI2BAAAQGC3TEEDX3XPY="
	data, err := base32.StdEncoding.DecodeString(str)
	if err != nil {
		fmt.Println("error:", err)
		return
	}
	fmt.Printf("%q\\n", data)
	// Output:
	// "some data with \\x00 and \\ufeff"
}
  • package base32_test: これは、encoding/base32パッケージの外部テストパッケージであることを示します。これにより、テストコードがパッケージの内部実装に依存せず、公開されたAPIのみを使用していることを確認できます。
  • import ("encoding/base32", "fmt"): base32パッケージと、出力のためのfmtパッケージをインポートしています。
  • ExampleEncoding_EncodeToString(): base32.StdEncoding.EncodeToString()メソッドを使ってバイトスライスをBase32文字列にエンコードする例です。
  • ExampleEncoding_DecodeString(): base32.StdEncoding.DecodeString()メソッドを使ってBase32文字列をバイトスライスにデコードする例です。エラーハンドリングも含まれています。
  • // Output:コメント: GoのExampleテストの重要な部分で、この関数が標準出力に出力するべき内容を定義しています。go test実行時に、実際の出力とこのコメントの内容が比較されます。

src/pkg/encoding/base64/example_test.go

// Copyright 2012 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package base64_test

import (
	"encoding/base64"
	"fmt"
)

func ExampleEncoding_EncodeToString() {
	data := []byte("any + old & data")
	str := base64.StdEncoding.EncodeToString(data)
	fmt.Println(str)
	// Output:
	// YW55ICsgb2xkICYgZGF0YQ==
}

func ExampleEncoding_DecodeString() {
	str := "c29tZSBkYXRhIHdpdGggACBhbmQg77u/"
	data, err := base64.StdEncoding.DecodeString(str)
	if err != nil {
		fmt.Println("error:", err)
		return
	}
	fmt.Printf("%q\\n", data)
	// Output:
	// "some data with \\x00 and \\ufeff"
}

このファイルもbase32_testと同様の構造を持ち、encoding/base64パッケージのStdEncodingを使用して、エンコードとデコードのExampleを提供しています。基本的なロジックはBase32の例と同じですが、使用するパッケージと期待される出力がBase64に特化しています。

これらのExampleコードは、Goのドキュメント生成ツール(go doc)によって自動的に抽出され、パッケージのドキュメントに組み込まれます。これにより、開発者はGoの公式ドキュメントを参照するだけで、これらのエンコーディング機能の具体的な使用方法を学ぶことができます。

関連リンク

参考にした情報源リンク