【问题标题】:Calculating a "based" data checksum. (SHA1/2, etc)计算“基于”的数据校验和。 (SHA1/2 等)
【发布时间】:2011-06-03 06:59:28
【问题描述】:

我不知道该怎么问这个问题,但这就是我所希望的,因为它的结构可能包含5+n 键(因此,我的系统必须有 5 个键,其他键是可选的) - 我想要一种散列机制,能够确定具有5 相同键的6 键散列是5 键结构的超集,并提供附加信息。特别是散列机制,因为存在一些限制,无法在每次请求时通过线路发送完整的结构。

为了澄清,这里有一些信息(示例需要2+n 键):

---
  name: codebeaker
  occupation: developer

SHA-512-256 散列后看起来像:

SHA-512
04fe500f2b3e779aba9ecb171224a04d35cc8453eb1521c7e31fd48b56b1cce9
b1e8af775e177e110982bfb16a6ca8652d7d9812ab8a8c316015dc9d6b3b54f7

SHA-256
4833be7086726e7ffd82db206f94f0a4f9fdf7fba00692f626157afed4587c74

当添加一个额外的键时,(下面的例子)我希望能够推断出扩展数据集是第一个的超集。

---
  name: codebeaker
  occupation: developer
  telephone: 49 (0) 123 45 67

但是,不出所料,在MD5SHA-n 和我研究过的任何其他散列函数中,没有办法做到这一点,例如:

SHA-512
2fe2c1f01e39506010ea104581b737f95db6b6f71b1497788afc80a4abe26ab0
fc4913054278af69a89c152406579b7b00c3d4eb881982393a1ace83aeb7b6a2

SHA-256
77c2942e9095e55e13c548e5ef1f874396bfb64f7653e4794d6d91d0d3a168e2

(显然)没有相似之处......

我们的用例,即格式化为结构的数据,由第 3 方输入我们的系统。处理数据非常昂贵,每次操作需要 2-3 秒,如果我们知道我们有上一次运行的结果,我们可以获得大约 50% 的时间,但是 - 贝叶斯和 Levenstein 文本差异算法不是适合这里,因为我们经常看到作为首字母缩略词的键/值对,以及在完全不相关时可能看起来相似的其他文本。

我们需要的是一种校验和数据的方法(我可能会偏向于我的回答)——这样我们就可以确定 BA 的超集,如果它包含所有相同的键和相同的数据.但是,我们的struc 中的键/值条目中经常有太多数据,以至于每次通过网络发送它,只是为了确定我们已经看到了更完整的副本,这既昂贵又浪费。

【问题讨论】:

  • “密钥”是否已知且已修复?如果不是,例如,对于您的 (name,occupation, phone) 三元组,您必须创建 3 个可能的超集进行比较 (name,occupation), (name, phone), (occupation, phone) .如果提供的密钥数量与所需数量之间存在较大差距,那么组合的数量可能会激增。
  • 我在 Twitter 上链接了这个,有人指出标记 crypto 可能是一个错误,我标记它是因为我记得 something 关于能够以编程方式确定如果一个键是从另一个键派生的,这就是我希望在这里做的事情,除了我们谈论的是结构的文本表示,而不是键(但在这种情况下它们会有多大不同?)
  • @Damien_The_Unbeliever,这些密钥大部分是已知的 - 假设现在可能有 10 个已知密钥,5 个强制性(如上所述)并且可能多达 15 个允许增长和更改系统寿命。对于具有额外已知键的部分,API 的语义版本控制用于控制允许的字段。例如v1.3 允许比 v1.2 更多的密钥。不允许 v0.9 客户端使用 1.0 API,因为它们不提供所有 5 个(强制)密钥。 API 格式当前为 JSON,但可以更改。 (我们写了客户端。)
  • 你需要使用哈希做什么?听起来您需要能够存储昂贵操作的结果,并搜索作为当前请求子集的先前结果。它是否正确?如果是这样,那就是搜索/缓存问题,而不是散列问题。

标签: c cryptography checksum data-integrity sha


【解决方案1】:

一个想法是对每个键值对使用不同的哈希值。因此,完整结构的“散列”是散列的集合。

如果您的用例始终是五个相同顺序的相同键,然后是任何其他键,您可以将一个哈希用于强制键,一个用于可选键 - 但您将无法检测到包含可选键的一个结构keys 是另一个包含可选键的结构的超集。

一个细微的变化是对所需的键使用一个散列,对整个结构使用一个散列。

您还可以(根据您的要求)对键值对使用较小的校验和,以便能够快速丢弃不相同的内容 - 但仍需要较大的哈希值才能更准确地确定某些内容是匹配的.

【讨论】:

  • 感谢您的提示,我自然曾考虑过 - 散列单个键将允许我查找键列表,并确定我是否已经知道该列表...如果没有“正确”回答这可能是我要走的路。
【解决方案2】:

加密哈希是专门为这些属性设计的:

  • 它们是单向函数。重新计算给定哈希值的特定输入,甚至是哈希到该值的任何随机输入,实际上是不可行的。
  • 虽然由于输入大小远大于固定输出大小,因此必然存在冲突,但实际上也无法找到两个不同的输入值导致相同的哈希值。
  • 完全相同的输入值总是哈希到完全相同的哈希值。
  • 输入中的任何微小变化都会导致完全不同的哈希值。翻转任何单个输入位平均会改变 50% 的输出位。

因此,加密哈希可以并且实际上用作任何二进制数据的唯一标识符。甚至 "name: codebeaker" 的哈希值也与 "name: Codebeaker" 不同。

如果您的一组键是固定的,以固定的顺序,始终完整且仅由新键扩展,并且每个键只有一个允许的表示形式,那么您可以计算五个旧键的哈希值并将其与当前集合的现有哈希。

如果键始终是唯一的,但集合可以混合,那么您可以为每个键计算单独的散列,并将这些存储并在单独的数据库中搜索现有集合。

除此之外,加密哈希可能不是适合这项工作的工具。

[编辑]

另一种方法是首先按字母顺序对键进行排序,然后从排序集中获取哈希值。这现在可以识别您的集合,而无需关心订单。首先获取单个键的单个哈希值,然后对哈希值进行排序,然后对排序的哈希值列表进行哈希处理,这可能更实用。这仍然需要唯一键。

【讨论】:

  • 感谢@secure - 我对加密哈希非常了解,但这应该可以帮助任何来到这里的人。也许您可以告诉我,一个人如何能够确定一个密钥是否是从另一个密钥派生的? (这是我想象中的一个功能吗?)在 SSL 证书升级的情况下,为了避免警告,新密钥被加密设计为显示为前证书的派生/孩子(当然,他们也必须由根 CA 颁发)
  • @Beaks:证书非常复杂,包含大量数据。它使用父证书签名,使用 -- 加密哈希。可以验证该符号来自父证书。但是还有第三个想法你可以做什么,我会扩展我的答案。
猜你喜欢
  • 2017-06-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-30
  • 2017-03-21
  • 2015-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多