Macからコマンドを呼び出すと
echo hello | shasum -a 256
またはubuntuから
echo hello | sha256sum
次に、次の結果が得られます
5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03 -
最後にダッシュがあることに気づきました。
しかし、Python hashlib
またはJava Java.security.MessageDigest
、次のように同じ結果が得られます。
2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
それで、誰かが私がそれを間違えたところを指摘できますか?
ありがとう。
Python:
>>> import hashlib
>>> hashlib.sha256("hello").hexdigest()
Java:
MessageDigest md = MessageDigest.getInstance("SHA-256");
String text = "hello";
md.update(text.getBytes("UTF-8"));
byte[] digest = md.digest();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < digest.length; i++) {
sb.append(String.format("%02x", digest[i] & 0xFF))
}
System.out.println(sb.toString());
echo
コマンドは、文字列に末尾の改行を追加しています。試してみてください:
hashlib.sha256("hello\n").hexdigest()
sha256sum
および関連するコマンドは、出力にダッシュ:-
を追加しています。これらのコマンドは、* filesのハッシュ値を表示するために作成されました。ダッシュが1つあるということは、入力が標準のinpuItストリームからのものであることを意味します(つまり、ファイル名がありません)。残念ながら、出力を抑制するオプションが表示されないため、実際のハッシュ値を取得するには、自分で出力を削除する必要があります。
したがって、ハッシュユーティリティはハッシュ値を返すだけではありません。 SHA-256ハッシュ値は単純に32バイトで構成されます。人間はバイナリを読み取ることができないため、バイナリは16進数を使用して表示されますが、実際の値はバイトと見なす必要があります。 16進文字は、これらのバイトの表現です。
ハッシュ関数の入力もビットまたはバイトで構成されます。これは、テキストのエンコードに違いがあると、ハッシュ値が異なることを意味します。これは、空白と行末のエンコーディングに関しては特に注意が必要です。ただし、「hello」の場合は、末尾の改行を追加する代わりに、echo
コマンドの-n
コマンドラインオプションを使用して改行を抑制する方がよいでしょう。
したがって、次のことを試してください。
echo -n "hello" | sha256sum | tr -d "[:space:]-"
または、OpenSSL(同様の問題があります)の場合:
echo -n hello | openssl sha256 -binary | od -An -tx1 | tr -d "[:space:]"
これにより、末尾の改行も削除されるため、16進比較を実行できます。
Javaの場合は、テキストエンコーディングがシステムのデフォルトエンコーディングと一致していることも確認する必要があります。一致していないと、問題が発生する可能性があります。
md.update(text.getBytes("UTF-8"));
に
md.update(text.getBytes());
プラットフォームの文字エンコーディングを取得します。そうしないと、プラットフォームのエンコーディングが、比較する文字列のUTF-8と互換性がない場合、比較は失敗します。
そして、Python行末なしで、この答えを終了するには:
print(hashlib.sha256("hello").hexdigest(), end="")
16進数自体もさまざまな方法で表示できることに注意してください。空白が存在しないこと、比較で大文字と小文字が区別されないこと、またはバイトの表現が常に同じ大文字と小文字を使用することを確認します。