c#中来自可变长度字符串的固定长度数字哈希码

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/548158/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 07:44:14  来源:igfitidea点击:

Fixed Length numeric hash code from variable length string in c#

c#.net-3.5hash

提问by Kishore A

I need to store fixed-length (up to 8 digits) numbers produced from a variable length strings. The hash need not be unique. It just needs to change when input string changes. Is there a hash function in .Net that does this?

我需要存储由可变长度字符串生成的固定长度(最多 8 位)数字。散列不必是唯一的。它只需要在输入字符串更改时更改。.Net 中是否有一个哈希函数可以做到这一点?

Thanks
Kishore.

由于
纪。

采纳答案by ShuggyCoUk

I assume you are doing this because you need to store the value elsewhere and compare against it. Thus Zach's answer (while entirely correct) may cause you issues since the contract for String.GetHashCode() is explicit about its scope for changing.

我假设您这样做是因为您需要将值存储在其他地方并与它进行比较。因此,Zach 的答案(虽然完全正确)可能会给您带来问题,因为 String.GetHashCode() 的合同明确说明了其更改范围。

Thus here is a fixed and easily repeatable in other languages version.

因此,这是一个固定且易于重复的其他语言版本。

I assume you will know at compile time the number of decimal digits available. This is based on the Jenkins One At a Time Hash (as implemented and exhaustively testedby Bret Mulvey), as such it has excellent avalanching behaviour (a change of one bit in the input propagates to all bits of the output) which means the somewhat lazy modulo reduction in bits at the end is not a serious flaw for most uses (though you could do better with more complex behaviour)

我假设你会在编译时知道可用的十进制数字的数量。这是基于 Jenkins One At a Time Hash(由 Bret Mulvey实施和详尽测试),因此它具有出色的雪崩行为(输入中的一位更改传播到输出的所有位),这意味着对于大多数用途来说,最后的位模数减少并不是一个严重的缺陷(尽管你可以用更复杂的行为做得更好)

const int MUST_BE_LESS_THAN = 100000000; // 8 decimal digits

public int GetStableHash(string s)
{
    uint hash = 0;
    // if you care this can be done much faster with unsafe 
    // using fixed char* reinterpreted as a byte*
    foreach (byte b in System.Text.Encoding.Unicode.GetBytes(s))
    {   
        hash += b;
        hash += (hash << 10);
        hash ^= (hash >> 6);    
    }
    // final avalanche
    hash += (hash << 3);
    hash ^= (hash >> 11);
    hash += (hash << 15);
    // helpfully we only want positive integer < MUST_BE_LESS_THAN
    // so simple truncate cast is ok if not perfect
    return (int)(hash % MUST_BE_LESS_THAN);
}

回答by Zach Scrivena

Simple approach (note that this is platform-dependent):

简单的方法(注意这是平台相关的):

int shorthash = "test".GetHashCode() % 100000000; // 8 zeros
if (shorthash < 0) shorthash *= -1;

回答by Sparr

Use System.Security.Cryptography.MD5CryptoServiceProvider.ComputeHashto get a MD5 hash, truncate it to the desired length.

使用System.Security.Cryptography.MD5CryptoServiceProvider.ComputeHash得到一个MD5哈希值,它截断到需要的长度。