试图获得一个简单的自定义POCO列表的HashCode

问题描述 投票:0回答:1

我正在尝试创建一个天气结果列表(自定义POCO)的简单HashCode,并想知道我正在做什么是好/好。

我有一个基于时间的过程,可以检查5个地点的天气结果。我将每个天气结果存储在一个List中:

{
  "results": [
    {
      "Id": 1,
      "Location": "New York City",
      "Temp": "21.7",
      "Metric": "Celsius"
    },
    {
      "Id": 2,
      "Location": "San Francisco",
      "Temp": "18.1",
      "Metric": "Celsius"
    },
    ....
    {
      "Id": 5,
      "Location": "Melbourne",
      "Temp": "33.1",
      "Metric": "Celsius"
    }
  ]
}

所以我希望得到一个HashCode /唯一指纹..将其存储在数据库中。稍后,我将再次获取最新的天气结果......这次将最近的结果与之前的结果(在数据库中)进行比较。

为此,我正在做以下事情:

private static string ToHash(IEnumerable<Weather> weatherResults)
{
    byte[] hash;

    // MD5 or SHA256?
    using (var algorithm = MD5.Create())
    {
        var json = JsonConvert.SerializeObject(weatherResults);
        hash = algorithm.ComputeHash(Encoding.UTF8.GetBytes(json));
    }

    return Encoding.UTF8.GetString(hash);
}
  1. 所以我使用的是MD5,因为我不关心安全性(例如,这不是我们存储的密码),并希望这很快。
  2. 我正在将列表转换为JSON,这是获取我的天气列表的标准文本表示的简单方法。 (简单序列化)

当我执行代码(上面)时,我得到一些奇怪的文本结果......这是一个快照:

enter image description here

所以代码似乎生成了我的列表的一些文本表示。我可以将此文本存储到数据库中。

所以感觉就像,我正在做的事情还可以 - >我希望有人确认我正在做的步骤是否正常。

c# .net hashcode
1个回答
3
投票

当我执行代码(上面)时,我得到了一些奇怪的文本结果

那是因为你将任意二进制数据(加密哈希)视为UTF-8编码的文本数据。这就像试图在记事本中打开JPG文件 - 你会看到垃圾,因为JPG文件不是文本文件。

如果需要可打印文本,则应转换为十六进制或base64。 Base64可能是最简单的:

return Convert.ToBase64String(hash);

请注意,如果将return语句放在using语句中,则甚至不需要额外的局部变量:

private static string ToHash(IEnumerable<Weather> weatherResults)
{
    using (var algorithm = MD5.Create())
    {
        var json = JsonConvert.SerializeObject(weatherResults);
        var hash = algorithm.ComputeHash(Encoding.UTF8.GetBytes(json));
        return Convert.ToBase64String(hash);
    }
}

这个人个人觉得有些脆弱 - 它依赖于POCO的精确JSON表示。特别是,如果您要更改序列化的某些方面,例如更改JSON中的字段名称,即使数据没有,哈希也会改变,这可能不是你想要的。再举一个例子,假设您在POCO中添加了一个int字段 - 所有现有数据的JSON表示将更改为包含该值,即使它为0,因此所有哈希值都会发生变化。

(这也是散列数据的效率很低的方法,但这可能并不重要。)

这对您来说可能都很好,但随着数据类型的发展,您需要考虑您的要求。

© www.soinside.com 2019 - 2024. All rights reserved.