通过字节序列化比较对象

时间:2014-08-20 17:22:07

标签: c# object serialization comparison md5

所以我有一个对象将以太存储在数据库表中或在文件中找到;用于更新该表。我们需要在表和更新文件之间进行比较,以避免在更新时出现重复。

我解决问题的第一个尝试是在字段上执行string.join然后将其转换为字节,最后md5哈希该字节数组。问题是,当某些(但不是全部)字段为空时,有时我们会得到一个空字符串。

所以我们决定这样做的第二种方法是将对象序列化为字节,并将md5散列为字符串。到目前为止,它的工作正常,但我注意到它可能不稳定(如果有人更新.net版本)。

这是我需要担心的吗?

想要它的人的示例代码:

public void GenerateHash()
    {
        md5 = returnHash();
    }

    public byte[] returnHash()
    {
        if (this == null)
            return null;
        BinaryFormatter bf = new BinaryFormatter();
        MemoryStream ms = new MemoryStream();
        bf.Serialize(ms, this);
        string str = System.Text.Encoding.Default.GetString(ms.ToArray());
        return SensitiveNamespace.Hashing.MD5(str).ToBytes();
    }

2 个答案:

答案 0 :(得分:2)

BinaryFormatter 将程序集的类型+版本存储在序列化数据中。如果将代码升级到新版本,则无法获得相同的二进制数据。因此我会使用Xml或Json作为序列化格式。

例如:(使用Json.Net

byte[] GenerateHash(object o)
{
    using (var sha = SHA256.Create())
    {
        var json = JsonConvert.SerializeObject(o);
        return sha.ComputeHash(Encoding.UTF8.GetBytes(json));
    }
}

BTW:您可以使用SHA256

来减少发生碰撞的几率

答案 1 :(得分:0)

  

引起我的注意,它可能不稳定(如果有人   例如更新.net版本。)

     

这是我需要担心的吗?

你在比较哈希是什么?您是否持久保存数据库数据的哈希值?如果没有,也就是说,如果您在运行时计算它们,则不应该出现问题。

如果是这样,您可以在应用程序启动时运行某种验证作业,验证哈希值并在必要时进行更改。

由于您无法控制的拼图部分是序列化代码,因此您可能应该回到字符串连接方法并包含一些保证唯一的字段组合。