ダウンロードした ZIP が途中で壊れていないか、バックアップしたファイルが元と本当に同じか。
見た目では判断できないこの手の確認を、1コマンドで片付けてくれるのが sha256sum です。
今回は Ubuntu 22.04.5(GNU coreutils 8.32)のサンドボックスで実際に叩きながら、基本の使い方を整理しました。
ハッシュ値は中身の指紋
sha256sum はファイルの中身を読んで、64文字の16進数を計算します。
同じ中身なら必ず同じ値になり、1バイトでも違えば全く別の値になるのが肝心なところ。
末尾の1文字だけを変えて比べると、値がまるごと入れ替わるのが分かります。
$ printf 'hello\n' > a.txt
$ printf 'hellp\n' > b.txt
$ sha256sum a.txt b.txt
5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03 a.txt
bf8c83416f31143ee2fa5db7ebbbb54589626c4c2046a91d28545bc403e3cda6 b.txt
「o」と「p」の違いしかないのに、共通する部分は1文字もありません。
だからこそ、値が一致すれば中身も一致していると言い切れるのです。
まずは1ファイルで試す
出力はハッシュ値とファイル名をスペース2つで区切った形です。
この形式は後で出てくる検証モードがそのまま読み取れるので、自分で整形しないほうが幸せになります。
標準入力から流し込むこともでき、そのときファイル名の欄はハイフンになりました。
$ printf 'hello\n' | sha256sum
5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03 -
-c でまとめて検証する
sha256sum の本領はこちらです。
先に一覧ファイルを作っておき、あとから -c で突き合わせます。
$ sha256sum a.txt b.txt > SHA256SUMS
$ sha256sum -c SHA256SUMS
a.txt: OK
b.txt: OK
この状態で b.txt の中身を書き換えてから、もう一度検証してみましょう。
$ printf 'hacked\n' > b.txt
$ sha256sum -c SHA256SUMS
sha256sum: WARNING: 1 computed checksum did NOT match
a.txt: OK
b.txt: FAILED
$ echo $?
1
壊れた行が FAILED で名指しされ、終了ステータスも 1 になります。
スクリプトから呼ぶなら、この終了ステータスだけを見れば十分。
OK 行が邪魔なときは –quiet を足すと、失敗した行だけが残ります。
配布元の値と1行だけ突き合わせる
公式サイトにハッシュ値が1つだけ書いてある、というケースも珍しくありません。
その場合は一覧ファイルを作らず、標準入力から -c に渡すのが手軽です。
$ printf '5891b5b5...be03 a.txt\n' | sha256sum -c -
a.txt: OK
注意点は大文字と小文字。
配布元が大文字で書いている場合、sha256sum の出力は小文字なので目視だと一致を見落とします。
$ EXPECT="5891B5B5...BE03"
$ ACTUAL=$(sha256sum c.txt | cut -d' ' -f1)
$ [ "$(printf %s "$EXPECT" | tr 'A-Z' 'a-z')" = "$ACTUAL" ] && echo MATCH || echo MISMATCH
MATCH
ディレクトリを丸ごと比べる
sha256sum にディレクトリを渡すと、エラーになって何も出ません。
$ sha256sum d
sha256sum: d: Is a directory
フォルダ単位で比べたいときは、find で列挙してから xargs へ渡します。
並び順が違うと差分だらけになるので、sort をはさむのが要点です。
$ (cd d && find . -type f -print0 | sort -z | xargs -0 sha256sum) > A.txt
$ (cd e && find . -type f -print0 | sort -z | xargs -0 sha256sum) > B.txt
$ diff A.txt B.txt
2c2
< 3bb2abb6...0877 ./sub/2.txt
---
> c865f6c5...70ab ./sub/2.txt
中身が違うファイルだけが行として浮かび上がりました。
コピー先が本当に同じか確かめたいときは、これがいちばん確実な方法。
md5sum と sha256sum、どちらを使うか
100MB のランダムなファイルで所要時間を測ってみました。
md5 0.10 s
sha256 0.20 s
sha512 0.14 s
md5 が速いのは想像どおりですが、sha512 が sha256 より速いのは意外に思うかもしれません。
sha512 は64ビット単位で計算するアルゴリズムなので、いまの64ビットCPUでは有利に働くのです。
速度差は 100MB で 0.1 秒程度なので、実用上は素直に sha256sum を選んでおけば困りません。
md5 は意図的に同じ値を持つ別ファイルを作れることが知られており、改ざん検知の用途では使わないのが原則です。
つまずきやすいところ
- 一覧ファイルに書式の崩れた行があると WARNING: 1 line is improperly formatted が出る
- 一覧に書いたファイルが存在しないときは –ignore-missing で無視できる
- -b を付けるとファイル名の前にアスタリスクが付く(バイナリモードの印)
- ハッシュ値は暗号ではないので、値から元のファイルは復元できない
最後に
sha256sum は覚えることが少ないわりに、「同じかどうか」を人間の目より正確に答えてくれる道具です。
とくに -c による一括検証は、バックアップの健全性チェックにそのまま使えます。
詳しいオプションは GNU Coreutils の公式マニュアル にまとまっているので、迷ったら一次情報を当たってください。
関連するコマンドの入門記事も置いてあります。
以上です。











コメントを残す