独特但逼真的对象哈希码

时间:2015-12-02 10:34:39

标签: c# hash unique

好的,我正在设计一个软件,让一个系统与另一个系统同步。问题是原始系统是一些遗留的DB2恶梦,我只有只读访问权限和没有时间戳功能的表,这意味着无法检测哪些行被更改。

我的想法是只加载所有行(总共我将有大约60000行,每半小时同步一次)计算它们的哈希值,同时在我的集成数据库中保留<ID, hash>元组。然后,更改检测成为比较哈希和更新目标系统中的记录的工作,其中哈希不匹配或完全丢失元组。 忘了提到阅读源很便宜,更新目的地很贵,它是一个有很多后台处理的网络服务,所以我不会每次都更新所有内容。

现在,我的问题,c#builtin哈希码声称它不适合这个目的(相同的哈希并不意味着相等的对象)和加密哈希看起来像256+位哈希的大矫一样。我认为不需要超过64位,这将给出10个 10 碰撞机会,给出完美分布式哈希并允许在x64 arch上进行快速哈希比较。

那么我应该使用什么来生成唯一的哈希?

2 个答案:

答案 0 :(得分:2)

另一种选择;使用这样的函数计算C#中的哈希值;

private readonly System.Security.Cryptography.HashAlgorithm hash = System.Security.Cryptography.SHA1.Create();

public static string CalculateSignature(IEnumerable<object> values)
{
    var sb = new StringBuilder();
    foreach (var value in values)
    {
        string valueToHash = value == null ? ">>null<<" : Convert.ToString(value, CultureInfo.InvariantCulture);
        sb.Append(valueToHash).Append(char.ConvertFromUtf32(0));
    }
    var signature = sb.ToString();
    var bytesToHash = Encoding.UTF8.GetBytes(signature);
    var hashedBytes = hash.ComputeHash(bytesToHash);
    signature = Encoding.UTF8.GetString(hashedBytes);

    return signature;
}

编辑:散列分析测试

为了显示SHA1散列的速度,这是一个快速测试。在我的开发机器上,我在176ms内得到60,000个哈希值。 MD5需要161

var hash = System.Security.Cryptography.MD5.Create();

var stringtoHash = "3490518cvm90wg89puse5gu3tgu3v0afgmvkldfjgmvvvvvsh,9semc9petgucm9234ucv0[vhd,flhgvzemgu904vq2m0";

var sw = System.Diagnostics.Stopwatch.StartNew();
for(var i = 0; i < 60000; i++)
{
    var bytesToHash = Encoding.UTF8.GetBytes(stringtoHash);
    var hashedBytes = hash.ComputeHash(bytesToHash);
    var signature = Encoding.UTF8.GetString(hashedBytes);
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);

答案 1 :(得分:0)

在您的暂存SQL表中,使用SQL's checksum函数添加“校验和”列;

像这样;

更新mysourcetable set check = checksum(id,field1,field2,field3,field4 ......)

<强>澄清

你提到过拥有一个集成数据库;我的想法是你将DB2中的数据读入临时数据库,比如SQL服务器,你已经存储了ID /哈希对。如果您从DB2中复制了所有数据,而不仅仅是ID,那么您可以计算集成数据库中的校验和。