好的,我正在设计一个软件,让一个系统与另一个系统同步。问题是原始系统是一些遗留的DB2恶梦,我只有只读访问权限和没有时间戳功能的表,这意味着无法检测哪些行被更改。
我的想法是只加载所有行(总共我将有大约60000行,每半小时同步一次)计算它们的哈希值,同时在我的集成数据库中保留<ID, hash>
元组。然后,更改检测成为比较哈希和更新目标系统中的记录的工作,其中哈希不匹配或完全丢失元组。 忘了提到阅读源很便宜,更新目的地很贵,它是一个有很多后台处理的网络服务,所以我不会每次都更新所有内容。
现在,我的问题,c#builtin哈希码声称它不适合这个目的(相同的哈希并不意味着相等的对象)和加密哈希看起来像256+位哈希的大矫一样。我认为不需要超过64位,这将给出10个 10 碰撞机会,给出完美分布式哈希并允许在x64 arch上进行快速哈希比较。
那么我应该使用什么来生成唯一的哈希?
答案 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,那么您可以计算集成数据库中的校验和。