C# 唯一但真实的对象哈希代码

C# 唯一但真实的对象哈希代码,c#,hash,unique,C#,Hash,Unique,好的,我正在设计一个软件,它可以使一个系统与另一个系统保持同步。问题是原始系统是某种遗留的DB2噩梦,我只有只读访问权限,表没有任何时间戳功能,这意味着无法检测哪些行被更改 我的想法是只加载所有行(总共我将有大约60000行,每半小时同步一次)计算它们的哈希值,同时在我的集成数据库中保留元组。然后,更改检测变成了一项比较哈希和更新目标系统中哈希不匹配或元组完全缺失的记录的工作。忘了提到阅读源是便宜的,更新目的地是昂贵的,这是一个需要大量后台处理的web服务,所以我会避免每次都更新所有内容 现在,

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

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

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


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

在您的暂存SQL表中,使用函数添加一个“校验和”列

像这样的东西

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;
}
更新mysourcetable集合检查=校验和(id、字段1、字段2、字段3、字段4…)

澄清


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

另一种选择;使用如下函数计算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;
}
private readonly System.Security.Cryptography.HashAlgorithm hash=System.Security.Cryptography.SHA1.Create();
公共静态字符串CalculateSignature(IEnumerable值)
{
var sb=新的StringBuilder();
foreach(值中的var值)
{

字符串valueToHash=value==null?">>Null您可以使用另一个哈希函数,如128位上的MD5、CRC32或CRC64……您也可以使用加密哈希生成256位,只保留前64位。您是否需要现成的解决方案,而不是自己编写代码?如果没有现成的解决方案,我可以编写代码。说到加密,如果我需要的话,我对它的数学不是那么精通SHA256和更低的64位,这对我来说足够统一吗?加密哈希的一些替代方案可能是错误检测和纠正或压缩算法。例如,或。汉明码计算起来相对昂贵,但适用于固定长度的数据和“哈希”。LZW计算起来更便宜,但您无法命令最后得到的“散列”的大小。这两种方法都允许您检测到高(但不完整)的更改信心。不是选项,我没有对源数据库的写入或架构更改访问权限。我需要对源数据计算哈希。这是使用加密哈希,SHA1。我想避免加密哈希,即使我使用它,我也会使用二进制序列化对象,而不是字符串操作。这是因为CPU开销吗?计算60000个SHA1哈希值对于半小时的导入来说足够便宜了。或者,在同一个命名空间中替换为MD5,它是128位。但是,在您分析并能够证明哈希算法太昂贵之前,不要浪费时间担心!@mmix——只是添加了一段代码来显示SHA1的速度。在我的机器上,60000 SHA1 hash花了176毫秒。干杯。希望能有所帮助。