【问题标题】:How to avoid crc16 collisions?如何避免 crc16 冲突?
【发布时间】:2015-10-21 12:30:32
【问题描述】:

我遇到了一个非常烦人的问题,使用 crc16 哈希来管理我的一些信息。

在我的应用程序中,我将一些信息传递给一个 url 参数,一个巨大的编码上下文。该上下文允许用户恢复他们的旧搜索。在这种情况下,我会散列一些元素以确保不会占用太多字符。

似乎有些元素返回相同的哈希(crc16 算法)。

我将 has 转换为字符串: crc.ToString("X4"); 例如,两个不同的元素给了我:5A8E。

我尝试使用 crc32,但如果这样做,旧的上下文将无法识别。

您知道我该如何找到解决方案吗?非常感谢

【问题讨论】:

  • 使用冲突较少的哈希算法并重新哈希数据。
  • 是的,但是如果我这样做,旧的散列值将无法恢复?
  • 为什么要恢复/保留它们?
  • 因为用户可以在这个上下文中保存一些 url,即使我做了一些更改,它也必须工作。
  • CRC 不是哈希。这是一个校验和,不适合用作哈希函数。

标签: algorithm hash crc16


【解决方案1】:

即使 CRC16 是一个理想的散列函数(它不是),只有 16 位,Birthday Paradox 意味着在一组只有 2^8 = 256 个项目中存在大约 50% 的散列冲突机会。你几乎肯定需要更多位。

你不能让旧的哈希值继续工作并且让它们区分现有的冲突——这是一个矛盾。但是你可以实现一个新的、更好的散列方案,在 URL 参数中添加一个标志来表明你正在使用这个新方案,确保你的所有页面只生成这些新样式的 URL,并且“祖父”在旧的-style URL(将继续产生与以前相同的冲突)。我建议在收到旧式 URL 时向用户发送一个大而明亮的信息来更新他们的书签,并自动重定向页面。

【讨论】:

  • 谢谢 j_random_hacker,这是个好主意。我会试试你的。
【解决方案2】:

解释我想到并正在实施的其他解决方案。

我只是为我的元素准备了一个 crc32 和一个 crc16 哈希。我将 32 用于我现在构建的新 url,但使用 crc16 哈希作为旧 url 的后备。

所以,当我尝试比较哈希时,我从新的哈希开始,如果找不到任何元素,我会转到我的后备并将其与 crc16 哈希进行比较。

这让我可以得到任何情况。

【讨论】:

  • 新哈希是否更长? (如果大小相同,您只会为每个人引入更多碰撞 - 新旧。)
  • 是的,新的基于 8 个字符 :) 现在它就像一个魅力,等待测试团队完成他们疯狂的测试:)
  • 听起来您仍然在尝试使用哈希来唯一标识某物。如果散列冲突的后果是灾难性的,您可能不应该使用散列 - 而且您绝对不应该使用短的、非加密安全的散列。
猜你喜欢
  • 2011-07-02
  • 2018-02-03
  • 1970-01-01
  • 1970-01-01
  • 2019-05-16
  • 1970-01-01
  • 1970-01-01
  • 2019-08-11
  • 1970-01-01
相关资源
最近更新 更多