散列函数从C#中的输入字符串生成16个字母数字字符

时间:2015-05-07 05:15:24

标签: c# hash cryptography

我需要一个接收输入字符串的函数,无论其长度如何,都会输出一个16字符0-9A-Z的修复长度。如果由相同的字符串输入,则该函数应具有相同的输出。

有什么建议吗?谢谢

5 个答案:

答案 0 :(得分:2)

您可以使用以下内容:

public static string HashString(string text)
{
    const string chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    byte[] bytes = Encoding.UTF8.GetBytes(text);

    SHA256Managed hashstring = new SHA256Managed();
    byte[] hash = hashstring.ComputeHash(bytes);

    char[] hash2 = new char[16];

    // Note that here we are wasting bits of hash! 
    // But it isn't really important, because hash.Length == 32
    for (int i = 0; i < hash2.Length; i++)
    {
        hash2[i] = chars[hash[i] % chars.Length];
    }

    return new string(hash2);
}

SHA256Managed将生成32字节的哈希值。然后使用%(模数)运算符,我们为每个字节选择一个char。请注意,我们以这种方式浪费了很多位,但它并不重要,因为我们有比我们需要的更多的位(我们需要log2(36) * 16 == 82.7,我们有256位的散列)

答案 1 :(得分:0)

如果你想创建一个哈希,你应该看看hash algorythms。其中一个主要是 MD5 ,但这是 128bits 哈希算法。这意味着如果你将原始字节转换为十六进制字符串,它将是32chars长(因为大多数人都知道),这意味着你需要一个 64bits 的散列函数。我做了一个快速搜索,遇到了 SipHash http://en.wikipedia.org/wiki/SipHash)然后我找到了一个C#实现(https://github.com/BrandonHaynes/siphash-csharp

如果你使用 SipHash algorythm,你应该得到一个16char长度的字符串。

答案 2 :(得分:0)

试试这个,它使用MD5Hash算法。

public string GenerateHash(string str)
{
    using (var md5Hasher = MD5.Create())
    {
        var data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(str));
        return BitConverter.ToString(data).Replace("-", "").Substring(0, 16);
    }
}

答案 3 :(得分:0)

我真的很喜欢@Xanatos的答案,并决定实施它。 那时我意识到我正在创建一个常见问题的实例。

当我输入用于安装Windows的密钥时,有时我会弄错数字。特别是当我正在读取的条形码被刮擦或褪色时。这只是类似字符,视力不好和条形码磨损的组合。

在@Xanatos的回答中The窃以下内容作为扩展方法,但删除了类似的字符(例如'1','I','O','0'等)。

public static string ConstantLengthHash(this string Input)
{
    const string chars = "234679ACDEFGHJKLMNPQRTUVWXYZ";
    byte[] bytes = Encoding.UTF8.GetBytes(Input);

    SHA256Managed hashstring = new SHA256Managed();
    byte[] hash = hashstring.ComputeHash(bytes);

    char[] hash2 = new char[16];

    // Note that here we are wasting bits of hash! 
    // But it isn't really important, because hash.Length == 32
    for (int i = 0; i < hash2.Length; i++)
    {
        hash2[i] = chars[hash[i] % chars.Length];
    }

    return new string(hash2);
}

答案 4 :(得分:-1)

您可以使用LINQ:

var c = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var rn = new Random();
var res = new string(Enumerable.Repeat(c, 16)
              .Select(x => x[rn.Next(x.Length)])
              .ToArray());

另请参阅:RNGCryptoServiceProvider Class

  

使用。实现加密随机数生成器(RNG)   由加密服务提供商(CSP)提供的实现。   这个类不能被继承。

或者你可以试试这个:

Guid g = Guid.NewGuid();
MD5 md5 = MD5.Create();
Guid hashed = new Guid(md5.ComputeHash(g.ToByteArray()));