唯一但现实的对象哈希代码

本文关键字:对象 哈希 代码 唯一 | 更新日期: 2023-09-27 18:25:16

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

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

现在,我的问题是,c#内置哈希代码声称它不适合这个目的(相等的哈希并不意味着相等的对象),而加密哈希对于256+位的哈希来说似乎是一个很大的过度。我认为不需要超过64位,这将使我在给定完美分布的哈希的情况下,有十分之一的机会发生冲突,并允许在x64 arch上进行快速哈希比较。

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

唯一但现实的对象哈希代码

另一个选项;使用这样的函数计算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哈希的速度,这里有一个快速测试。在我的开发机器上,我在176毫秒内获得了60000个哈希。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);

在暂存SQL表中,使用SQL的校验和函数添加一个"checksum"列;

像这样的东西;

update-mysourcetable set check=校验和(id,field1,field2,field3,field4…)

澄清

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