
私はSHA1(特にGit)を学んでいて、他の方法を使って文字列のSHA1を計算して私の理解を確認したかったです。私は同じSHA1ハッシュを期待しましたが、代わりに4つの方法のうち3つの方法で異なる結果が得られました。
>git hash-object --stdin <<< "Apple Pie"
23991897e13e47ed0adb91a0082c31c82fe0cbe5
。
>sha1sum <<< "blob 9\0Apple Pie"
332cd56150dc8b954c0b859bd4aa6092beafa00f -
。
>printf 'blob 9\0Apple Pie' > foo.txt
>sha1sum foo.txt
9eed377bbdeb4aa5d14f8df9cd50fed042f41023 foo.txt
。
>openssl sha1 foo.txt
SHA1(foo.txt)= 9eed377bbdeb4aa5d14f8df9cd50fed042f41023
受け入れられた回答このスタックオーバーフローの質問git hash-object
「blob [ファイルサイズ] / 0」というプレフィックスが付いた指定されたコンテンツでSHA1ハッシュが実行されることを示します。したがって、私はGit以外のメソッドを使用して、テスト中の文字列の接頭辞にそのテキストを明示的に追加します。
なぜこんなに違う結果が出るのでしょうか?私はSHA1が与えられた文字列の具体的でユニークなハッシュ値であり、SHA1の他の「タイプ」がないと思いました。そうではありませんか?
答え1
違いは、SHA1ではなく入力で発生します。ここの文字列構文は、次のように改行文字を追加しますod
。
$ od -c <<< foo
0000000 f o o \n
したがって、コマンドgit
の入力は10文字ですApple Pie\n
。
また、ここで文字列に使用する二重引用符は、または\n
同じバックスラッシュエスケープをサポートしてい\nnn
ない<<< "blob 9\0Apple Pie"
ため、リテラルバックスラッシュとゼロを含む文字列を提供します。
printf
ただし、これは\0
NULバイトとして解釈され、末尾の改行文字を追加しないため、改行文字を追加して長さを変更してから予想される出力を取得する必要があります。
$ printf 'blob 10\0Apple Pie\n' | sha1sum
23991897e13e47ed0adb91a0082c31c82fe0cbe5 -
$''
NULバイトの表示をサポートする引用符を使用して、ここで文字列に対して同じ操作を実行できますが、\0
NULバイトは文字列を終了するため、すべてのシェルで機能しない可能性があります。たとえば、Bashはこれを処理できませんzsh
。次のことができます。
$ zsh -c "sha1sum <<< $'blob 10\0Apple Pie'"
23991897e13e47ed0adb91a0082c31c82fe0cbe5 -