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

标签 java jakarta-ee collections jax-rs

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

要求示例:

Server
   DirectoryA
        FileA 
        FileB
        FileC

Client
   DirectoryA
       FileA
       FileB
       FileC

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

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

服务器:

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

客户:

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

这种方法是否正确?

最佳答案

Is this approach correct?

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

我假设“与 31 相加” 是这样的意思

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

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

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

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

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

关于java - 使用哈希码比较两个字符串列表是否相等?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30678207/

相关文章:

java - 在 Java 中是否有一种简单的方法可以使用自定义 equals 函数来获取两个集合之间的差异而不覆盖 equals?

java - LinkedHashMap 的 keySet() 和 values() 方法的行为

java - 我该如何改进这个 Point 类

JavaFX 取消过滤 FilteredList

java - 哪个先运行 : @AfterTest or @TestListener?

java - Google Drive api 保存到文件

JavaSE-1.6 和 Java 兼容性

jakarta-ee - 使用 QuartzInitializerServlet 的 quartz 调度程序

c# - 检查集合是否为空

java - JPA 内部运作。 MySQLIntegrityConstraintViolationException