私はSHA256を使って文字列をハッシュしようとしています、私は次のコードを使っています:
using System;
using System.Security.Cryptography;
using System.Text;
public class Hash
{
public static string getHashSha256(string text)
{
byte[] bytes = Encoding.Unicode.GetBytes(text);
SHA256Managed hashstring = new SHA256Managed();
byte[] hash = hashstring.ComputeHash(bytes);
string hashString = string.Empty;
foreach (byte x in hash)
{
hashString += String.Format("{0:x2}", x);
}
return hashString;
}
}
しかし、このコードは私の友人のphpやオンラインのジェネレータ( This generator のような)とはかなり違う結果をもたらします。
誰がエラーが何であるかを知っていますか?別の基地ですか?
Encoding.Unicode
は、MicrosoftのUTF-16に対する誤解を招くような名前です(歴史的な理由からWindowsの世界で使用されていますが、他の誰にも使用されていない倍幅エンコード)。 http://msdn.Microsoft.com/en-us/library/system.text.encoding.unicode.aspx
bytes
配列を調べると、2倍のバイトが0x00
であることがわかります(倍幅エンコードのため)。
代わりにEncoding.UTF8.GetBytes
を使用してください。
しかし、最後の'\0'
バイトをハッシュしているデータの一部と見なすかどうかによって、結果が異なります。 2バイト"Hi"
をハッシュすると、3バイトのバイト"Hi"
をハッシュした場合とは結果が異なります。あなたはどちらをしたいのか決める必要があります。 (たぶんあなたはあなたの友人のPHPコードがしているものをやってみたいのです。)
ASCII textには、Encoding.UTF8
が間違いなく適しています。もしあなたがあなたの友達のコードとの完璧な互換性を目指しているなら、たとえ非ASCII入力でさえも、あなたはもっと多くのテストケースを試したほうがいいです。 é
や家
などのASCII文字を使用して、結果がまだ一致するかどうかを確認します。そうでなければ、あなたはあなたの友人が実際にどんなエンコーディングを使っているのかを考え出す必要があるでしょう。これは、Unicodeが発明される前に普及していた8ビットの「コードページ」の1つです。 (繰り返しになりますが、誰もが「コードページ」を心配する必要がある主な理由は、Windowsだと思います。)
私はまた別のスタイルの実装でこの問題を抱えていました、しかし私はそれが2年前だったので私がどこでそれを手に入れたか忘れていました。
static string sha256(string randomString)
{
var crypt = new SHA256Managed();
string hash = String.Empty;
byte[] crypto = crypt.ComputeHash(Encoding.ASCII.GetBytes(randomString));
foreach (byte theByte in crypto)
{
hash += theByte.ToString("x2");
}
return hash;
}
何らかの理由でabcdefghi2013
のようなものを入力すると、結果が異なり、ログインモジュールでエラーが発生します。それから私はQuuxplusoneによって提案されたのと同じ方法でコードを修正しようとし、そしてASCII
からUTF8
にエンコーディングを変更し、そしてそれはついにうまくいきました!
static string sha256(string randomString)
{
var crypt = new System.Security.Cryptography.SHA256Managed();
var hash = new System.Text.StringBuilder();
byte[] crypto = crypt.ComputeHash(Encoding.UTF8.GetBytes(randomString));
foreach (byte theByte in crypto)
{
hash.Append(theByte.ToString("x2"));
}
return hash.ToString();
}
Quuxplusoneに素晴らしい詳細な回答をいただきありがとうございます。
PHPバージョンでは、最後のパラメータに 'true'を送信できますが、デフォルトは 'false'です。次のアルゴリズムは、最初のパラメータとして 'sha256'を渡すときのデフォルトのPHPのハッシュ関数と同じです。
public static string GetSha256FromString(string strData)
{
var message = Encoding.ASCII.GetBytes(strData);
SHA256Managed hashString = new SHA256Managed();
string hex = "";
var hashValue = hashString.ComputeHash(message);
foreach (byte x in hashValue)
{
hex += String.Format("{0:x2}", x);
}
return hex;
}