通过字节序列化比较对象

本文关键字:比较 对象 序列化 字节 | 更新日期: 2023-09-27 18:18:48

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

我解决问题的第一次尝试是在字段上做一个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();
    }

通过字节序列化比较对象

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

例如:(Using 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

我注意到它可能是不稳定的(如果有人)更新。net版本(例如)。

这是我需要担心的事情吗?

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

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

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