Hash 値を計算するパッケージを作ってみた
Windows で hash 値を計算するいい感じのツールがない1 ので,もう自分で作っちゃったよ。 といっても自前の部分は殆どないけどね。
詳しくは README.md を見ていただくとして,実際に計算をするのはこの関数。
package hash
import (
"crypto"
"io"
"strings"
"github.com/pkg/errors"
)
var (
//ErrNoImplement is error "no implementation"
ErrNoImplement = errors.New("no implementation")
)
//Value returns hash value string from io.Reader
func Value(r io.Reader, alg crypto.Hash) ([]byte, error) {
if !alg.Available() {
return nil, errors.Wrap(ErrNoImplement, "error "+algoString(alg))
}
h := alg.New()
io.Copy(h, r)
return h.Sum(nil), nil
}
呼び出し側はこんな感じ(空文字列の SHA1 値を取得する場合)。
v, err := hash.Value(bytes.NewBuffer([]byte("")), crypto.SHA1)
if err != nil {
return
}
fmt.Printf("%x\n", v)
// Output:
// da39a3ee5e6b4b0d3255bfef95601890afd80709
crypto
.Hash.New()
関数で hash
.Hash
のインスタンスを生成している。
hash
.Hash
はこんな感じの interface 型である。
// Hash is the common interface implemented by all hash functions.
type Hash interface {
// Write (via the embedded io.Writer interface) adds more data to the running hash.
// It never returns an error.
io.Writer
// Sum appends the current hash to b and returns the resulting slice.
// It does not change the underlying hash state.
Sum(b []byte) []byte
// Reset resets the Hash to its initial state.
Reset()
// Size returns the number of bytes Sum will return.
Size() int
// BlockSize returns the hash's underlying block size.
// The Write method must be able to accept any amount
// of data, but it may operate more efficiently if all writes
// are a multiple of the block size.
BlockSize() int
}
つまり,このインタフェースを備えていれば自前の hash アルゴリズムを簡単に組み込むことができるわけだ。
言い方を変えると, hash.Value()
関数で実際に hash 値を計算するにはこのパッケージだけではダメで, hash アルゴリズムを実装するパッケージをインポートする必要がある。
以下にアルゴリズム毎に必要なパッケージを示す。
hash algorithm | import package |
---|---|
crypto.MD4 |
golang.org/x/crypto/md4 |
crypto.MD5 |
crypto/md5 |
crypto.SHA1 |
crypto/sha1 |
crypto.SHA224 |
crypto/sha256 |
crypto.SHA256 |
crypto/sha256 |
crypto.SHA384 |
crypto/sha512 |
crypto.SHA512 |
crypto/sha512 |
crypto.SHA512_224 |
crypto/sha512 |
crypto.SHA512_256 |
crypto/sha512 |
crypto.RIPEMD160 |
golang.org/x/crypto/ripemd160 |
crypto.SHA3_224 |
golang.org/x/crypto/sha3 |
crypto.SHA3_256 |
golang.org/x/crypto/sha3 |
crypto.SHA3_384 |
golang.org/x/crypto/sha3 |
crypto.SHA3_512 |
golang.org/x/crypto/sha3 |
crypto.BLAKE2s_256 |
golang.org/x/crypto/blake2s |
crypto.BLAKE2b_256 |
golang.org/x/crypto/blake2b |
crypto.BLAKE2b_384 |
golang.org/x/crypto/blake2b |
crypto.BLAKE2b_512 |
golang.org/x/crypto/blake2b |
この中から必要なパッケージを main
パッケージでブランク・インポートする2。
全部インポートするならこんな感じ。
package main
import (
_ "crypto/md5"
_ "crypto/sha1"
_ "crypto/sha256"
_ "crypto/sha512"
_ "golang.org/x/crypto/blake2b"
_ "golang.org/x/crypto/blake2s"
_ "golang.org/x/crypto/md4"
_ "golang.org/x/crypto/ripemd160"
_ "golang.org/x/crypto/sha3"
)
これを CLI (Command-Line Interface) にしたのが以下に示す hash コマンドである。
$ hash -h
Usage:
hash [flags] [binary file]
Flags:
-a, --algo string hash algorithm (default "sha256")
-c, --compare string compare hash value
-h, --help help for hash
サイズがゼロの空ファイル empty.txt
を作って試してみると
$ hash -a sha1 empty.txt
da39a3ee5e6b4b0d3255bfef95601890afd80709
となる。 パイプにも対応してるので
$ cat empty.txt | hash -a sha1
da39a3ee5e6b4b0d3255bfef95601890afd80709
とすることもできる。
さらに -c
オプションで hash 値の計算結果をリファレンスの値と比較できる。
$ hash -a sha1 empty.txt -c da39a3ee5e6b4b0d3255bfef95601890afd80709
matched
なお,アルゴリズムには md4
, md5
, sha1
, sha224
, sha256
, sha384
, sha512
, sha512/224
, sha512/256
, ripemd160
, sha3-224
, sha3-256
, sha3-384
, sha3-512
, blake2s
, blake2b/256
, blake2b/384
, blake2b/512
を指定できるようにした。
既定は sha256
。
例えば,これで dep の実行モジュールの正当性確認が少し楽になる。 dep のリリースページで Windows 用の実行モジュールと SHA256 値を記述したファイルをダウンロードする。
dep-windows-amd64
dep-windows-amd64.sha256
dep-windows-amd64.sha256
の中身が
034f8cf6c225fde51aa025376df12450832f111b39050a7ec451a9ec2ce2cb54 release/dep-windows-amd64
とするなら
$ hash dep-windows-amd64 -c 034f8cf6c225fde51aa025376df12450832f111b39050a7ec451a9ec2ce2cb54
matched
で一発確認できる。
確認できたら dep-windows-amd64
を dep.exe
にリネームして使えばよい。
ブックマーク
参考図書
- プログラミング言語Go (ADDISON-WESLEY PROFESSIONAL COMPUTING SERIES)
- Alan A.A. Donovan (著), Brian W. Kernighan (著), 柴田 芳樹 (翻訳)
- 丸善出版 2016-06-20
- 単行本(ソフトカバー)
- 4621300253 (ASIN), 9784621300251 (EAN), 4621300253 (ISBN), 9784621300251 (ISBN)
- 評価
著者のひとりは(あの「バイブル」とも呼ばれる)通称 “K&R” の K のほうである。この本は Go 言語の教科書と言ってもいいだろう。
- 暗号技術入門 第3版 秘密の国のアリス
- 結城 浩 (著)
- SBクリエイティブ 2015-08-25 (Release 2015-09-17)
- Kindle版
- B015643CPE (ASIN)
- 評価
SHA-3 や Bitcoin/Blockchain など新しい知見や技術要素を大幅追加。暗号技術を使うだけならこれ1冊でとりあえず無問題。
-
Windows 標準ツールとしては, PowerShell 4.0 以上が入っている PC なら,
Get-FileHash
コマンドレットが使える。 Windows 7 の場合は “Windows Management Framework 4.0” をインストールすることで PowerShell 4.0 にアップグレードできる。 ↩︎ -
ブランク・インポートは
main
パッケージでしないと golint に怒られるのよ。まぁ言いたいことは分かるけど。 ↩︎