背景(このセクションはスキップできます)
数百台のマシンで最新の状態に保つ必要がある大量のデータ(約3 mb)があります。一部のマシンはC#を実行し、一部のマシンはJavaを実行します。データはいつでも変更される可能性があり、数分以内にクライアントに伝達する必要があります。データは、4つの負荷分散サーバーからJson形式で配信されます。これらの4つのサーバーは、Mvc 3およびC#4.0でASP.NET4.0を実行しています。
4台のサーバーで実行されるコードには、Json応答をハッシュしてから、ハッシュを文字列に変換するハッシュアルゴリズムがあります。このハッシュはクライアントに渡されます。次に、数分ごとに、クライアントはハッシュを使用してサーバーにpingを実行し、ハッシュが古くなっている場合は新しいJsonオブジェクトが返されます。ハッシュがまだ最新の場合は、本文が空の304が返されます。
時折、4つのボックスによって生成されたハッシュがボックス間で一貫していないことがあります。これは、クライアントが常にデータをダウンロードしていることを意味します(各要求が異なるサーバーにヒットする可能性があります)。
コードスニペット
ハッシュを生成するために使用されるコードは次のとおりです。
internal static HashAlgorithm Hasher { get; set; }
...
Hasher = new SHA1Managed();
...
Convert.ToBase64String(Hasher.ComputeHash(Encoding.ASCII.GetBytes(jsonString)));
問題をデバッグするために、次のように分割しました。
Prehash = PreHashBuilder.ToString();
ASCIIBytes = Encoding.ASCII.GetBytes(Prehash);
HashedBytes = Hasher.ComputeHash(ASCIIBytes);
Hash = Convert.ToBase64String(HashedBytes);
次に、上記の値を吐き出すルートを追加し、BeyondCompareを使用して違いを比較しました。
バイト配列は、以下を使用してBeyondCompareで使用するために文字列形式に変換されます。
private static string GetString(byte[] bytes)
{
StringBuilder sb = new StringBuilder();
foreach (byte b in bytes)
{
sb.Append(b);
}
return sb.ToString();
}
ご覧のとおり、バイト配列はバイトのシーケンスとして文字通り表示されます。「変換」されません。
問題
PrehashとASCIIBytesの値は同じであることがわかりましたが、HashedBytesの値が異なっていました。つまり、ハッシュも異なっていました。
4つのサーバーボックスでIISWebサイトを数回再起動し、ハッシュが異なる場合は、BeyondCompareの値を比較しました。いずれの場合も、異なるのは「HashedBytes」値でした(SHA1Managed.ComputeHash(...)の結果)
質問
私は何が間違っているのですか?ComputeHash関数への入力は同じです。SHA1Managedマシンは依存していますか?4台のマシンの半分の時間は同じハッシュを持っているので、それはうまくいきません。
StackOverFlowとBingを検索しましたが、この問題を抱えている人を見つけることができませんでした。私が見つけた最も近いものは彼らのエンコーディングに問題がある人々でした、しかし私はエンコーディングが問題ではないことを証明したと思います。
出力
私はそれが長いのでここにすべてを捨てないことを望んでいました、しかしここに私が比較しているダンプのスニペットがあります:
Hash:o1ZxBaVuU6OhE6De96wJXUvmz3M =
HashedBytes:163861135165110831631611916022224717299375230207115
ASCIIBytes:.... Prehash:.. ..
異なるサーバー上の2つのページを比較すると、ASCIIバイトは同一ですが、HashedBytesは同一ではありません。私がバイトに使用するダンプメソッドは変換を行わず、各バイトを順番にダンプするだけです。'。'でバイトを区切ることができます。私は考えます。
フォローアップ b.ToString(CultureInfo.InvariantCulture)を変更し、HashAlgorithmを静的プロパティではなくローカル変数にしました。コードがサーバーにデプロイされるのを待っています。