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

时间:2015-06-06 01:59:59

标签: java java-ee collections jax-rs

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

需要的示例:

Server
   DirectoryA
        FileA 
        FileB
        FileC

Client
   DirectoryA
       FileA
       FileB
       FileC

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

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

服务器

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

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

1 个答案:

答案 0 :(得分:4)

  

这种做法是否正确?

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

我认为"与31&#34相结合; 意味着这样的事情

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

Java哈希码值是32位数量。如果我们假设文件名是均匀分布的,那意味着有两个不同的文件名集可能具有1 in in 2 ^ 32,具有相同的散列(如上所述)。换句话说,"哈希冲突"。

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

如果您想避免这些问题,则需要更长的校验和。如果您想要防止制造冲突的人,那么您需要使用加密强哈希/校验和。 MD5是一个受欢迎的选择。

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