使用哈希码比较两个字符串列表是否相等?

Comparing if two list of strings are equal using hashcode?

我正在编写 Java/JEE 客户端服务器应用程序。我有一个要求,即服务器中存在的文件应与客户端中存在的文件相匹配。我只是想验证是否与特定目录中的文件名和文件数完全匹配。

要求示例:

Server
   DirectoryA
        FileA 
        FileB
        FileC

Client
   DirectoryA
       FileA
       FileB
       FileC

服务器确保所有客户端具有相同文件的最有效方法是什么,假设我可以有超过 100 个客户端并且我不希望我的 client/server 通信太冗长.

我目前的方法是使用 REST API 和 REST 客户端:

服务器:

  1. 查找目标目录中的文件列表
  2. 通过使用由文件名导出的哈希码并将其与数字 31 相加来为目录创建校验和。

客户:

  1. 在收到验证目标目录完整性的请求后,客户端获取服务器提供的校验和,并运行相同的算法在本地目录上生成校验和。 `
  2. 如果校验和匹配,则客户端成功响应服务器。

这种方法正确吗?

Is this approach correct?

该方法是正确的,但建议的实施不是 (IMO)。

我假设 "summing with 31" 的意思是这样的

  int hash = 0;
  for (String name : names) 
       hash = hash * 31 + name.hashCode();

Java 哈希码值是 32 位数量。如果我们假设文件名是均匀分布的,这意味着两个 不同 文件名集具有相同哈希值的概率为 2^32 分之一(如上计算)。换句话说,"hash collision".

40 亿次出错一次的算法可能是不可接受的。更糟糕的是,如果算法已知,那么有人可以简单地制造算法给出错误答案的情况(即一组文件名)。

如果你想避免这些问题,你需要更长的校验和。如果你想防止人为制造碰撞,那么你需要使用加密强哈希/校验和。 MD5 是一个流行的选择。

但如果是我,我也会考虑只发送完整的文件名列表...或使用(廉价的)基于哈希码的校验和作为目录内容 可能是一样。 (后者是否有意义取决于你接下来需要做什么。)