3

重複の可能性:
短い文字列(タグ名)に最適な32ビットハッシュ関数は何ですか?

多くの文字列を32ビット(uint)にハッシュする必要があります。

MD5またはSHA1を使用して、そこから4バイトを取得できますか?または、より良い選択肢はありますか?

セキュリティやひび割れなどの心配はありません。32ビットに高速かつ均一にハッシュする必要があります。MD5とSHA1は均一である必要があります。

しかし、私が使用できるより良い(より速い)組み込みの代替手段はありますか?そうでない場合は、両方のどちらを使用しますか?

ここで誰かがどちらが良いか尋ねましたが、代替案はなく、セキュリティの問題がありました(私はセキュリティを気にしません):
C#でSHA1またはMD5を使用する方法(認証のパフォーマンスとセキュリティのどちらが優れているか)

4

3 に答える 3

9

暗号強度のハッシュが必要ですか?必要なのが32ビットだけの場合、私は賭けません。

Fowler-Noll-Voハッシュを試してください。高速で、分散と雪崩効果が高く、ハッシュテーブルやチェックサムなどに一般的に受け入れられます。

    public static uint To32BitFnv1aHash(this string toHash, 
       bool separateUpperByte = false)
    {
        IEnumerable<byte> bytesToHash;

        if (separateUpperByte)
            bytesToHash = toHash.ToCharArray()
                .Select(c => new[] { (byte)((c - (byte)c) >> 8), (byte)c })
                .SelectMany(c => c);
        else
            bytesToHash = toHash.ToCharArray()
                .Select(Convert.ToByte);

        //this is the actual hash function; very simple
        uint hash = FnvConstants.FnvOffset32;

        foreach (var chunk in bytesToHash)
        {
            hash ^= chunk;
            hash *= FnvConstants.FnvPrime32;
        }

        return hash;
    }

public static class FnvConstants
{
    public static readonly uint FnvPrime32 = 16777619;
    public static readonly ulong FnvPrime64 = 1099511628211;
    public static readonly uint FnvOffset32 = 2166136261;
    public static readonly ulong FnvOffset64 = 14695981039346656037;
}

これは、各オブジェクトの文字列ダイジェスト(カスタムToString()など)に基づいて、GetHashCodeの意味的に同等のハッシュを作成する場合に非常に便利です。これをオーバーロードして、IEnumerable<byte>ストリームデータのチェックサムなどに適したものにすることができます。64ビットハッシュ(ulong)が必要な場合は、関数をコピーして、使用する定数を64ビット定数に置き換えてください。ああ、もう1つ。ハッシュは(ほとんどの場合と同様に)チェックされていない整数のオーバーフローに依存しています。このハッシュを「チェック済み」ブロックで実行しないでください。実行すると、例外がスローされることが事実上保証されます。

于 2012-09-04T23:23:24.437 に答える
4

セキュリティが役割を果たさない場合は、暗号化ハッシュ関数(MD5やSHA1など)を使用してハッシュを生成し、そこから4バイトを取得することが機能します。ただし、これらの関数は主に速度ではなくセキュリティを目的として設計されているため、さまざまな非暗号化ハッシュ関数よりも低速です。

FNVMurmurなどの非暗号化ハッシュ関数を見てください。

編集: floodyberry.comドメインがドメインパーキングサービスによって登録されるようになりました-デッドリンクが削除されました

于 2012-09-04T22:41:36.157 に答える
3

文字列の最も簡単でありながら優れたアルゴリズムは次のとおりです。

int Hash(string s)
{
  int res = 0; 
  for(int i = 0; i < str.Length; i++)
  {
     res += (i * str[i]) % int.MaxValue;
  }
  return res;
}

明らかに、これは絶対に安全なハッシュアルゴリズムではありませんが、高速(本当に高速)で32ビットを返し、私が知る限り、均一です(多くのアルゴリズムの課題で試してみましたが、良い結果が得られました)。

パスワードや重要なデータをハッシュするために使用することはできません。

于 2012-09-04T23:14:21.003 に答える