我正在尝试创建一个简单的HashCode,用于列出天气结果列表(自定义POCO),并且想知道我在做什么是否可以。
我有一个基于时间的过程,该过程检查5个地点的天气结果。我将每个天气结果存储在一个列表中:
{
"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);
}
MD5
是因为我不在乎安全性(例如,这不是我们要存储的密码),并且希望此速度很快。执行代码时(上面),我得到一些奇怪的文本结果...这是快照:
因此,代码似乎生成了我的列表的一些文本表示形式。我可以将此文本存储到数据库中。
所以感觉,我在做什么就可以->我只想找一个人确认我正在执行的步骤是否正确。
答案 0 :(得分: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的 precise JSON表示。特别是如果您要更改序列化的某些方面,例如更改JSON中的字段名称,那么即使数据没有更改,哈希也将更改,这可能不是您想要的。再举一个例子,假设您在POCO中添加了一个int
字段-所有现有数据的JSON表示都会更改为包括该值,即使该值为0,因此所有哈希也会更改
(这也是一种无效的散列数据方式,但这可能并不重要。)
这 可能对您都很好,但是随着数据类型的发展,您需要考虑自己的要求。