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

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

このコミットは、Go言語の標準ライブラリにおけるハッシュ関数(Adler32, CRC32, MD5, SHA1)の実装において、内部で使用される定数や型、関数名の命名規則を統一し、Go言語の慣習に沿った「unexported」(非公開)な識別子へと変更するものです。具体的には、識別子の先頭を大文字からアンダースコア(_)または小文字に変更することで、パッケージ外部からの直接参照を防ぎ、カプセル化を強化しています。

コミット

commit d2cdcfc1c8530c9b1185a86677535f0f1450a7f0
Author: Russ Cox <rsc@golang.org>
Date:   Fri Jan 16 10:14:28 2009 -0800

    casify hash
    
    R=r
    DELTA=235  (6 added, 26 deleted, 203 changed)
    OCL=22907
    CL=22938

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

https://github.com/golang/go/commit/d2cdcfc1c8530c9b1185a86677535f0f1450a7f0

元コミット内容

    casify hash
    
    R=r
    DELTA=235  (6 added, 26 deleted, 203 changed)
    OCL=22907
    CL=22938

変更の背景

このコミットが行われた2009年1月は、Go言語がまだ一般に公開される前の初期開発段階に当たります。Go言語の設計思想の一つに「シンプルさと明瞭さ」があり、その一環として、識別子の可視性(エクスポートされるか否か)を命名規則によって明確にするという特徴があります。

Go言語では、識別子(変数、関数、型、構造体のフィールドなど)の先頭が大文字で始まる場合、その識別子はパッケージ外部から参照可能("exported"または"public")になります。一方、先頭が小文字で始まる場合、その識別子はパッケージ内部からのみ参照可能("unexported"または"private")となります。

このコミットの背景には、ハッシュ関数ライブラリ(src/lib/hash)内の内部的な定数やヘルパー関数が、意図せずパッケージ外部に公開されてしまう可能性があったという問題意識があります。初期開発段階では、このような命名規則が完全に確立されていなかったり、適用が漏れていたりすることがあります。このコミットは、Go言語の設計原則に則り、ハッシュライブラリの内部実装の詳細を適切にカプセル化し、外部からの不必要な依存を防ぐことを目的としています。これにより、ライブラリのAPIがより明確になり、将来的な変更やリファクタリングが容易になります。

前提知識の解説

Go言語の識別子の可視性(Exported/Unexported)

Go言語における識別子の可視性は、その名前の先頭文字によって決定されます。

  • Exported (公開): 識別子の先頭が大文字で始まる場合(例: MyFunction, MyVariable, MyType)。これらの識別子は、その識別子が定義されているパッケージをインポートする他のパッケージから参照および使用することができます。これらはパッケージの公開APIの一部と見なされます。
  • Unexported (非公開): 識別子の先頭が小文字で始まる場合(例: myFunction, myVariable, myType)。これらの識別子は、その識別子が定義されているパッケージ内からのみ参照および使用することができます。パッケージ外部からは直接アクセスできません。これらはパッケージの内部実装の詳細と見なされ、カプセル化を促進します。

このシンプルなルールは、Go言語の設計哲学である「明示的であること」と「複雑さを避けること」を反映しています。他の言語に見られるようなpublic, private, protectedといったキーワードを導入することなく、命名規則だけで可視性を制御できるため、コードの読みやすさと記述の簡潔さが向上します。

ハッシュ関数

ハッシュ関数は、任意の長さの入力データを受け取り、固定長の出力(ハッシュ値またはメッセージダイジェスト)を生成するアルゴリズムです。主な特性として以下が挙げられます。

  • 一方向性: ハッシュ値から元の入力データを復元することは非常に困難であるべきです。
  • 衝突耐性: 異なる入力データから同じハッシュ値が生成されること(衝突)は、計算上非常に困難であるべきです。
  • 決定性: 同じ入力データからは常に同じハッシュ値が生成されます。

このコミットで変更が加えられているのは、以下のハッシュ関数に関連するコードです。

  • Adler32: チェックサムアルゴリズムの一種で、CRC32よりも高速ですが、衝突耐性は低いです。データの整合性チェックによく使用されます。
  • CRC32 (Cyclic Redundancy Check): データの転送や保存におけるエラー検出によく用いられるチェックサムアルゴリズムです。
  • MD5 (Message-Digest Algorithm 5): かつては広く使われた暗号学的ハッシュ関数ですが、現在ではセキュリティ上の脆弱性が指摘されており、データの完全性検証には使用されますが、セキュリティ目的での利用は推奨されません。
  • SHA-1 (Secure Hash Algorithm 1): MD5と同様に、かつては広く使われた暗号学的ハッシュ関数ですが、現在では衝突攻撃が可能であることが示されており、セキュリティ目的での利用は推奨されません。

これらのハッシュ関数は、データの整合性チェック、ファイルの一意な識別、デジタル署名など、様々な場面で利用されます。

技術的詳細

このコミットの技術的な変更点は、主に以下の3つのパターンに分類できます。

  1. 定数名の変更:

    • adler32.goでは、ModMaxiterという定数が_Mod_MaxIterに変更され、constブロック内にまとめられました。
    • md5.goでは、Chunk, A, B, C, Dという定数が_Chunk, _Init0, _Init1, _Init2, _Init3に変更され、constブロック内にまとめられました。
    • sha1.goでは、Chunk, H0, H1, H2, H3, H4という定数が_Chunk, _Init0, _Init1, _Init2, _Init3, _Init4に変更され、constブロック内にまとめられました。
    • sha1block.goでは、K0, K1, K2, K3という定数が_K0, _K1, _K2, _K3に変更されました。 これらの変更により、これらの定数がパッケージ内部でのみ使用されることが明確になります。
  2. 内部ヘルパー関数名の変更:

    • md5.gomd5block.goでは、Blockという関数が_Blockに変更されました。
    • sha1.gosha1block.goでは、Blockという関数が_Blockに変更されました。 これらのBlock関数は、ハッシュ計算のコアロジックを担う内部関数であり、パッケージ外部から直接呼び出されるべきではありません。命名規則の変更により、その意図が明確化されました。
  3. テストコード内の型名および変数名の変更:

    • adler32_test.goでは、Adler32Testという型が_Adler32Testに変更され、goldenという変数も_Adler32Test型を使用するように変更されました。
    • crc32_test.goでは、Crc32Testという型が_Crc32Testに変更され、goldenという変数も_Crc32Test型を使用するように変更されました。
    • md5_test.goでは、Md5Testという型がmd5Testに変更され、goldenという変数もmd5Test型を使用するように変更されました。
    • sha1_test.goでは、Sha1Testという型がsha1Testに変更され、goldenという変数もsha1Test型を使用するように変更されました。 テストコード内のこれらの型や変数は、テストの内部的な構造を定義するものであり、パッケージ外部に公開する必要はありません。Go言語の慣習に従い、これらも非公開の識別子に変更されています。
  4. MD5/SHA1テストにおけるハッシュ値のフォーマット変更:

    • md5_test.gosha1_test.goでは、ハッシュ値を16進数文字列に変換する際に、独自のHex関数を使用していた箇所が、Go標準ライブラリのfmt.Sprintf("%x", ...)を使用するように変更されました。これは、より標準的で簡潔な方法への移行を示しています。

これらの変更は、Go言語の初期段階において、言語の設計原則(特に可視性に関する命名規則)がコードベース全体にわたって統一的に適用されていく過程を示しています。これにより、コードの品質、保守性、そしてAPIの明確性が向上しています。

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

このコミットは、Go言語の標準ライブラリにおけるハッシュ関数(Adler32, CRC32, MD5, SHA1)の実装ファイルと、それらのテストファイルにわたる広範な変更を含んでいます。

src/lib/hash/adler32.go

--- a/src/lib/hash/adler32.go
+++ b/src/lib/hash/adler32.go
@@ -19,8 +19,10 @@ export type Digest struct {
 	n int;
 }
 
-const Mod = 65521;
-const Maxiter = 5552;	// max mod-free iterations before would overflow uint32
+const (
+	_Mod = 65521;
+	_MaxIter = 5552;  // max mod-free iterations before would overflow uint32
+)
 
 export func NewDigest() *Digest {
 	return &Digest{1, 0, 0};
@@ -32,9 +34,9 @@ func (d *Digest) Write(p []byte) (nn int, err *os.Error) {
 		a += uint32(p[i]);
 		b += a;
 		n++;
-		if n == Maxiter {
-			a %= Mod;
-			b %= Mod;
+		if n == _MaxIter {
+			a %= _Mod;
+			b %= _Mod;
 			n = 0;
 		}
 	}
@@ -44,9 +46,9 @@ func (d *Digest) Write(p []byte) (nn int, err *os.Error) {
 
 func (d *Digest) Sum32() uint32 {
 	a, b := d.a, d.b;
-	if a >= Mod || b >= Mod {
-		a %= Mod;
-		b %= Mod;
+	if a >= _Mod || b >= _Mod {
+		a %= _Mod;
+		b %= _Mod;
 	}
 	return b<<16 | a;
 }

src/lib/hash/crc32.go

--- a/src/lib/hash/crc32.go
+++ b/src/lib/hash/crc32.go
@@ -44,7 +44,7 @@ export func MakeTable(poly uint32) Table {
 	return t;
 }
 
-export var ieee = MakeTable(IEEE);
+export var IEEETable = MakeTable(IEEE);
 
 export type Digest struct {
 	crc uint32;
@@ -56,7 +56,7 @@ export func NewDigest(tab Table) *Digest {
 }
 
 export func NewIEEEDigest() *Digest {
-	return NewDigest(ieee);
+	return NewDigest(IEEETable);
 }
 
 func (d *Digest) Write(p []byte) (n int, err *os.Error) {

src/lib/hash/md5.go

--- a/src/lib/hash/md5.go
+++ b/src/lib/hash/md5.go
@@ -8,54 +8,52 @@ package md5
 
 import "os"
 
-package const (
-	Chunk = 64
-)
-
 const (
-	A = 0x67452301;
-	B = 0xEFCDAB89;
-	C = 0x98BADCFE;
-	D = 0x10325476;
+	_Chunk = 64;
+
+	_Init0 = 0x67452301;
+	_Init1 = 0xEFCDAB89;
+	_Init2 = 0x98BADCFE;
+	_Init3 = 0x10325476;
+)
 
 export type Digest struct {
 	s [4]uint32;
-	x [Chunk]byte;
+	x [_Chunk]byte;
 	nx int;
 	len uint64;
 }
 
 export func NewDigest() *Digest {
 	d := new(Digest);
-	d.s[0] = A;
-	d.s[1] = B;
-	d.s[2] = C;
-	d.s[3] = D;
+	d.s[0] = _Init0;
+	d.s[1] = _Init1;
+	d.s[2] = _Init2;
+	d.s[3] = _Init3;
 	return d;
 }
 
-package func Block(dig *Digest, p []byte) int
+func _Block(dig *Digest, p []byte) int
 
 func (d *Digest) Write(p []byte) (nn int, err *os.Error) {
 	nn = len(p);
 	d.len += uint64(nn);
 	if d.nx > 0 {
 		n := len(p);
-		if n > Chunk-d.nx {
-			n = Chunk-d.nx;
+		if n > _Chunk-d.nx {
+			n = _Chunk-d.nx;
 		}
 		for i := 0; i < n; i++ {
 			d.x[d.nx+i] = p[i];
 		}
 		d.nx += n;
-		if d.nx == Chunk {
-			Block(d, d.x);
+		if d.nx == _Chunk {
+			_Block(d, d.x);
 			d.nx = 0;
 		}
 		p = p[n:len(p)];
 	}
-	n := Block(d, p);
+	n := _Block(d, p);
 	p = p[n:len(p)];
 	if len(p) > 0 {
 		for i := 0; i < len(p); i++ {

src/lib/hash/md5block.go

--- a/src/lib/hash/md5block.go
+++ b/src/lib/hash/md5block.go
@@ -10,79 +10,79 @@ package md5
 
 import "md5"
 
-// T[i] = int((1<<32) * abs(sin(i+1 radians))).\n-var T = []uint32 {
+// table[i] = int((1<<32) * abs(sin(i+1 radians))).\n+var table = []uint32 {
 	// round 1
-	0xd76aa478,	
+	0xd76aa478,
 	0xe8c7b756,
-	0x242070db,	
-	0xc1bdceee,	
-	0xf57c0faf,	
-	0x4787c62a,	
-	0xa8304613,	
-	0xfd469501,	
-	0x698098d8,	
-	0x8b44f7af,	
-	0xffff5bb1,	
-	0x895cd7be,	
-	0x6b901122,	
-	0xfd987193,	
-	0xa679438e,	
+	0x242070db,
+	0xc1bdceee,
+	0xf57c0faf,
+	0x4787c62a,
+	0xa8304613,
+	0xfd469501,
+	0x698098d8,
+	0x8b44f7af,
+	0xffff5bb1,
+	0x895cd7be,
+	0x6b901122,
+	0xfd987193,
+	0xa679438e,
 	0x49b40821,
 
 	// round 2
-	0xf61e2562,	
-	0xc040b340,	
-	0x265e5a51,	
-	0xe9b6c7aa,	
-	0xd62f105d,	
-	0x2441453,	
-	0xd8a1e681,	
-	0xe7d3fbc8,	
-	0x21e1cde6,	
-	0xc33707d6,	
-	0xf4d50d87,	
-	0x455a14ed,	
-	0xa9e3e905,	
-	0xfcefa3f8,	
-	0x676f02d9,	
+	0xf61e2562,
+	0xc040b340,
+	0x265e5a51,
+	0xe9b6c7aa,
+	0xd62f105d,
+	0x2441453,
+	0xd8a1e681,
+	0xe7d3fbc8,
+	0x21e1cde6,
+	0xc33707d6,
+	0xf4d50d87,
+	0x455a14ed,
+	0xa9e3e905,
+	0xfcefa3f8,
+	0x676f02d9,
 	0x8d2a4c8a,
 
 	// round 3
-	0xfffa3942,	
-	0x8771f681,	
-	0x6d9d6122,	
-	0xfde5380c,	
-	0xa4beea44,	
-	0x4bdecfa9,	
-	0xf6bb4b60,	
-	0xbebfbc70,	
-	0x289b7ec6,	
-	0xeaa127fa,	
-	0xd4ef3085,	
-	0x4881d05,	
-	0xd9d4d039,	
-	0xe6db99e5,	
-	0x1fa27cf8,	
-	0xc4ac5665,	
+	0xfffa3942,
+	0x8771f681,
+	0x6d9d6122,
+	0xfde5380c,
+	0xa4beea44,
+	0x4bdecfa9,
+	0xf6bb4b60,
+	0xbebfbc70,
+	0x289b7ec6,
+	0xeaa127fa,
+	0xd4ef3085,
+	0x4881d05,
+	0xd9d4d039,
+	0xe6db99e5,
+	0x1fa27cf8,
+	0xc4ac5665,
 
 	// round 4
-	0xf4292244,	
-	0x432aff97,	
-	0xab9423a7,	
-	0xfc93a039,	
-	0x655b59c3,	
-	0x8f0ccc92,	
-	0xffeff47d,	
-	0x85845dd1,	
-	0x6fa87e4f,	
-	0xfe2ce6e0,	
-	0xa3014314,	
-	0x4e0811a1,	
-	0xf7537e82,	
-	0xbd3af235,	
-	0x2ad7d2bb,	
-	0xeb86d391,	
+	0xf4292244,
+	0x432aff97,
+	0xab9423a7,
+	0xfc93a039,
+	0x655b59c3,
+	0x8f0ccc92,
+	0xffeff47d,
+	0x85845dd1,
+	0x6fa87e4f,
+	0xfe2ce6e0,
+	0xa3014314,
+	0x4e0811a1,
+	0xf7537e82,
+	0xbd3af235,
+	0x2ad7d2bb,
+	0xeb86d391,
 }
 
 var shift1 = []uint { 7, 12, 17, 22 };
@@ -90,16 +90,16 @@ var shift2 = []uint { 5, 9, 14, 20 };
 var shift3 = []uint { 4, 11, 16, 23 };
 var shift4 = []uint { 6, 10, 15, 21 };
 
-package func Block(dig *Digest, p []byte) int {
+func _Block(dig *Digest, p []byte) int {
 	a := dig.s[0];
 	b := dig.s[1];
 	c := dig.s[2];
 	d := dig.s[3];
 	n := 0;
 	var X [16]uint32;
-	for len(p) >= Chunk {
+	for len(p) >= _Chunk {
 		aa, bb, cc, dd := a, b, c, d;
-	
+
 		for i := 0; i < 16; i++ {\n 			j := i*4;\n 			X[i] = uint32(p[j]) | uint32(p[j+1])<<8 | uint32(p[j+2])<<16 | uint32(p[j+3])<<24;\n@@ -119,43 +119,43 @@ package func Block(dig *Digest, p []byte) int {
 			t := i;\n 			s := shift1[i%4];\n 			f := ((c ^ d) & b) ^ d;\n-			a += f + X[x] + T[t];\n+			a += f + X[x] + table[t];\n 			a = a<<s | a>>(32-s);\n 			a += b;\n 			a, b, c, d = d, a, b, c;\n 		}\n-	
+
 		// Round 2.\n 		for i := 0; i < 16; i++ {\n 			x := (1+5*i)%16;\n 			t := 16+i;\n 			s := shift2[i%4];\n 			g := ((b ^ c) & d) ^ c;\n-			a += g + X[x] + T[t];\n+			a += g + X[x] + table[t];\n 			a = a<<s | a>>(32-s);\n 			a += b;\n 			a, b, c, d = d, a, b, c;\n 		}\n-	
+
 		// Round 3.\n 		for i := 0; i < 16; i++ {\n 			x := (5+3*i)%16;\n 			t := 32+i;\n 			s := shift3[i%4];\n 			h := b ^ c ^ d;\n-			a += h + X[x] + T[t];\n+			a += h + X[x] + table[t];\n 			a = a<<s | a>>(32-s);\n 			a += b;\n 			a, b, c, d = d, a, b, c;\n 		}\n-		
+
 		// Round 4.\n 		for i := 0; i < 16; i++ {\n 			x := (7*i)%16;\n 			s := shift4[i%4];\n 			t := 48+i;\n 			ii := c ^ (b | ^d);\n-			a += ii + X[x] + T[t];\n+			a += ii + X[x] + table[t];\n 			a = a<<s | a>>(32-s);\n 			a += b;\n 			a, b, c, d = d, a, b, c;\n@@ -165,11 +165,11 @@ package func Block(dig *Digest, p []byte) int {
 		b += bb;\n 		c += cc;\n 		d += dd;\n-		
-		p = p[Chunk:len(p)];
-		n += Chunk;\n+		
+		p = p[_Chunk:len(p)];
+		n += _Chunk;\n 	}\n-	
+
 	dig.s[0] = a;\n 	dig.s[1] = b;\n 	dig.s[2] = c;\

src/lib/hash/sha1.go

--- a/src/lib/hash/sha1.go
+++ b/src/lib/hash/sha1.go
@@ -8,56 +8,54 @@ package sha1
 
 import "os"
 
-package const (
-	Chunk = 64;
-)
-
 const (
-	H0 = 0x67452301;
-	H1 = 0xEFCDAB89;
-	H2 = 0x98BADCFE;
-	H3 = 0x10325476;
-	H4 = 0xC3D2E1F0;
+	_Chunk = 64;
+
+	_Init0 = 0x67452301;
+	_Init1 = 0xEFCDAB89;
+	_Init2 = 0x98BADCFE;
+	_Init3 = 0x10325476;
+	_Init4 = 0xC3D2E1F0;
+)
 
 export type Digest struct {
 	h [5]uint32;
-	x [Chunk]byte;
+	x [_Chunk]byte;
 	nx int;
 	len uint64;
 }
 
 export func NewDigest() *Digest {
 	d := new(Digest);
-	d.h[0] = H0;
-	d.h[1] = H1;
-	d.h[2] = H2;
-	d.h[3] = H3;
-	d.h[4] = H4;
+	d.h[0] = _Init0;
+	d.h[1] = _Init1;
+	d.h[2] = _Init2;
+	d.h[3] = _Init3;
+	d.h[4] = _Init4;
 	return d;
 }
 
-package func Block(dig *Digest, p []byte) int
+func _Block(dig *Digest, p []byte) int
 
 func (d *Digest) Write(p []byte) (nn int, err *os.Error) {
 	nn = len(p);
 	d.len += uint64(nn);
 	if d.nx > 0 {
 		n := len(p);
-		if n > Chunk-d.nx {
-			n = Chunk-d.nx;
+		if n > _Chunk-d.nx {
+			n = _Chunk-d.nx;
 		}
 		for i := 0; i < n; i++ {
 			d.x[d.nx+i] = p[i];
 		}
 		d.nx += n;
-		if d.nx == Chunk {
-			Block(d, d.x);
+		if d.nx == _Chunk {
+			_Block(d, d.x);
 			d.nx = 0;
 		}
 		p = p[n:len(p)];
 	}
-	n := Block(d, p);
+	n := _Block(d, p);
 	p = p[n:len(p)];
 	if len(p) > 0 {
 		for i := 0; i < len(p); i++ {

src/lib/hash/sha1block.go

--- a/src/lib/hash/sha1block.go
+++ b/src/lib/hash/sha1block.go
@@ -11,18 +11,18 @@ package sha1
 import "sha1"
 
 const (
-	K0 = 0x5A827999;
-	K1 = 0x6ED9EBA1;
-	K2 = 0x8F1BBCDC;
-	K3 = 0xCA62C1D6;
+	_K0 = 0x5A827999;
+	_K1 = 0x6ED9EBA1;
+	_K2 = 0x8F1BBCDC;
+	_K3 = 0xCA62C1D6;
 )
 
-package func Block(dig *Digest, p []byte) int {
+func _Block(dig *Digest, p []byte) int {
 	var w [80]uint32;
 
 	n := 0;
 	h0, h1, h2, h3, h4 := dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4];
-	for len(p) >= Chunk {
+	for len(p) >= _Chunk {
 		// Can interlace the computation of w with the
 		// rounds below if needed for speed.
 		for i := 0; i < 16; i++ {
@@ -41,33 +41,33 @@ package func Block(dig *Digest, p []byte) int {
 
 		// Each of the four 20-iteration rounds
 		// differs only in the computation of f and
-		// the choice of K (K0, K1, etc).\n+		// the choice of K (_K0, _K1, etc).\n 		for i := 0; i < 20; i++ {\n 			f := b&c | (^b)&d;\n 			a5 := a<<5 | a>>(32-5);\n 			b30 := b<<30 | b>>(32-30);\n-			t := a5 + f + e + w[i] + K0;\n+			t := a5 + f + e + w[i] + _K0;\n 			a, b, c, d, e = t, a, b30, c, d;\n 		}\n 		for i := 20; i < 40; i++ {\n 			f := b ^ c ^ d;\n 			a5 := a<<5 | a>>(32-5);\n 			b30 := b<<30 | b>>(32-30);\n-			t := a5 + f + e + w[i] + K1;\n+			t := a5 + f + e + w[i] + _K1;\n 			a, b, c, d, e = t, a, b30, c, d;\n 		}\n 		for i := 40; i < 60; i++ {\n 			f := b&c | b&d | c&d;\n 			a5 := a<<5 | a>>(32-5);\n 			b30 := b<<30 | b>>(32-30);\n-			t := a5 + f + e + w[i] + K2;\n+			t := a5 + f + e + w[i] + _K2;\n 			a, b, c, d, e = t, a, b30, c, d;\n 		}\n 		for i := 60; i < 80; i++ {\n 			f := b ^ c ^ d;\n 			a5 := a<<5 | a>>(32-5);\n 			b30 := b<<30 | b>>(32-30);\n-			t := a5 + f + e + w[i] + K3;\n+			t := a5 + f + e + w[i] + _K3;\n 			a, b, c, d, e = t, a, b30, c, d;\n 		}\n 
@@ -77,8 +77,8 @@ package func Block(dig *Digest, p []byte) int {
 		h3 += d;\n 		h4 += e;\n 
-		p = p[Chunk:len(p)];
-		n += Chunk;\n+		p = p[_Chunk:len(p)];
+		n += _Chunk;\n 	}\n 
 	dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4] = h0, h1, h2, h3, h4;\

コアとなるコードの解説

上記の差分は、Go言語の命名規則における「unexported」(非公開)の原則を適用していることを明確に示しています。

  • 定数名の変更 (Mod -> _Mod, Chunk -> _Chunk, A -> _Init0など):

    • Go言語では、パッケージ外部に公開する必要のない定数や変数は、小文字で始めるか、アンダースコア(_)をプレフィックスとして付けることが慣習です。この変更により、adler32, md5, sha1パッケージ内で使用されるこれらの定数が、そのパッケージの内部実装の詳細であり、外部から直接アクセスされるべきではないことが明確になります。
    • 特に、MD5やSHA1の初期ハッシュ値(A, B, C, DH0H4)は、ハッシュアルゴリズムの内部的な初期状態を表すものであり、外部から変更されたり参照されたりすることは想定されていません。これらを_InitXのような名前に変更することで、その内部的な性質が強調されます。
  • 内部ヘルパー関数名の変更 (Block -> _Block):

    • Block関数は、ハッシュ計算の主要な処理ブロックを処理する内部関数です。この関数は、Digest型のWriteメソッドから呼び出されることを想定しており、パッケージの外部から直接呼び出されるべきではありません。_Blockという名前に変更することで、この関数がパッケージの内部実装の一部であることが明確になり、不適切な外部からの利用を防ぎます。
  • テストコード内の型名および変数名の変更 (Adler32Test -> _Adler32Test, Md5Test -> md5Testなど):

    • テストコード内で定義される型や変数は、通常、そのテストファイル内でのみ使用されます。Go言語の命名規則に従い、これらも非公開の識別子に変更することで、テストの内部構造が外部に漏れることを防ぎ、コードベース全体の整合性を保ちます。
  • MD5/SHA1テストにおけるハッシュ値のフォーマット変更 (Hex関数からfmt.Sprintf("%x", ...)へ):

    • これは、Go言語の標準ライブラリが成熟していく過程で、より汎用的で慣用的な方法が採用されていく一例です。独自の16進数変換関数Hexを定義する代わりに、標準のfmtパッケージが提供するSprintf関数と%xフォーマット指定子を使用することで、コードがより簡潔になり、Go言語の標準的な慣習に沿うようになります。

これらの変更は、Go言語の初期段階におけるコードベースの洗練と、言語設計原則の厳密な適用を示すものです。これにより、Go言語のコードはより一貫性があり、保守しやすく、理解しやすいものへと進化していきました。

関連リンク

参考にした情報源リンク