【发布时间】:2019-06-15 16:24:08
【问题描述】:
- 我有一堆 ID,它们是字符串形式的,例如
"enemy1", "enemy2"。 - 我想保存一个进度,取决于我杀死的每个敌人的数量。为此,我使用了像
{ { "enemy1", 0 }, { "enemy2", 1 } }这样的字典。 - 然后我想通过网络在他可以玩的几台机器(如 PC 和笔记本电脑)之间共享玩家的存档(首先将其序列化为 JSON 文件)。为了减小尺寸和提高性能,我使用哈希而不是完整字符串,使用该算法(因为 MDSN 说,默认哈希算法在不同的机器上可能不同):
int hash_ = 0;
public override int GetHashCode()
{
if(hash_ == 0)
{
hash_ = 5381;
foreach(var ch in id_)
hash_ = ((hash_ << 5) + hash_) ^ ch;
}
return hash_;
}
所以,问题是:C# 中的 alg 是否会在任何机器玩家使用的机器中返回相同的结果。
UPD:在 cmets 中,我注意到问题的主要部分不清楚。
所以。如果我可以保证反序列化之前的所有文件都将采用相同的编码,那么播放器可以使用的每台机器上的字符表示形式是否相同并且操作^ ch 会给出相同的结果?我的意思是 WinX64/WinX32/Mac/Linux/... 机器
【问题讨论】:
-
是的,该算法将在每台机器上给出相同的结果。但是,您不应该假设具有相同哈希值的两个字符串必然相等。但我不清楚这与问题的其余部分有什么关系。之后你将如何使用哈希? (如果您想要 close 来保证唯一性,我会在文件上使用加密哈希,例如使用 SHA-256 或 SHA-512。假设具有相同 SHA 哈希的两个文件是相同的。)
-
如果您正在创建自己的哈希码,那么它在每台机器上都是相同的。但是,如果您依赖 GetHashCode() 的任何默认实现,则无法保证。
-
@JonSkeet,谢谢。我认为不清楚,但主要部分是关于 C# 中的字符表示。如果我可以保证反序列化之前的所有 JSON 将采用相同的编码,那么 Winx86/Winx64/Unix/MAC... 机器上的字符表示形式是否相同?
-
是的,
char始终是 UTF-16 代码单元。但我仍然不清楚为什么你会使用这种方法而不是获取文件的加密哈希。 -
@JonSkeet 这真的没有意义,因为我没有大量的字符串条目,而且 6% 的交叉点对我来说是可以的。但这完全有道理,而且很重要,谢谢。