是否存在适合比较相似但不完全匹配的数据的散列算法?

信息安全 验证 哈希
2021-09-08 08:18:57

是否存在适合比较相似但不完全匹配的数据的散列算法?

例如,相似的输入数据生成相似的散列,散列的差异与数据的差异成正比。

所有传感器都具有精度、准确度和噪声规格。一般来说,这样的散列对于依赖来自传感器的数据的任何类型的身份验证都是有用的。

一个例子是生物特征识别。例如,同一根手指的两次扫描或一张脸的图片会非常相似,但并不完全相同。拥有这种类型的算法将允许身份验证服务存储散列而不是实际的指纹或面部数据。

3个回答

通常这被称为模糊散列

它的效果如何会因使用和数据而有很大差异。

我过去成功用于各种类型数据的两种模糊散列算法是:

  • ssdeep - ssdeep是一个用于计算上下文触发的分段哈希 (CTPH) 的程序。CTPH 也称为模糊哈希,可以匹配具有同源性的输入。这样的输入具有相同顺序的相同字节序列,尽管这些序列之间的字节在内容和长度上可能不同。
  • deeptoad - DeepToad是一个 (python) 库和一个使用模糊散列技术对相似文件进行聚类的工具。这个项目的灵感来自著名的工具 ssdeep。

澄清

你说,“ ......拥有这种类型的算法将允许身份验证服务存储哈希而不是实际的指纹或面部数据......

通常生物特征参考数据不存储为文字图像。相反,它被存储为匹配细节点的子集。这允许有效的存储以及隐式模糊搜索和匹配能力。这对于指纹和面部匹配等生物特征数据至关重要,因为永远不会发生完美匹配。

根据您的应用程序,您可能正在尝试重新发明轮子。

对于人脸的图片示例,您可以尝试使用 OpenCV 的图像哈希比较工具来寻找足够近的距离。这被称为感知散列,可以在Image hashing with OpenCV and Python 中找到一个很好的教程。

指纹通过从扫描中提取的某些点进行比较,称为细节(此处为进一步阅读的论文),然后根据精确而不是“哦,读数相似”进行比较。您可能会散列传感器数据的粗略特征以进行比较,以提供更二进制的散列比较,并存储实际的准确读数,但是由于预映像电阻设计,其中散列很难从原始输入中以数学方式推导出来,a散列的微小变化会影响整个散列,通常会完全改变它。

tl;dr 作为快速思考,您可能会为每个指纹生成一个哈希组合(而不是单个哈希),这样您就可以检查两个不同组合的内容是否重叠。或者,同态加密。


我想你可以朝两个方向走:

  1. 使用哈希组合。
    生成一组大致相等的指纹,然后分别对它们中的每一个进行哈希处理。将所有哈希值存储在投资组合中;比较两个投资组合中的哈希值以评估潜在的相似性。

  2. 使用同态加密。
    做正常的指纹比较,但使用同态加密。


选项 1:哈希组合。

基本思想是:

  1. 将您的指纹四舍五入到局部近似值。

  2. 生成一个投资组合,其中包括局部近似值以及所有足够接近的匹配点。

  3. 分别散列投资组合中的每个项目。

例如,假设您想要存储一个日期(例如某人的出生日期)并且您想要对其进行散列处理,但您希望能够在散列处理之后评估另一个日期是否接近。然后:

  1. 将日期舍入最接近的粗粒度近似值。

    • 例如,如果您估计 3 个月内的日期并且某人出生于 2021 年 8 月 7 日,则将其四舍五入为 2021 年 9 月 1 日。
  2. 在每个方向上生成一组关于该舍入值的点。

    • 例如,如果某人四舍五入为 2021-09-01,则为 { 2020-09-01, 2020-12-01, [...], 2022-09-01} 生成分数。
  3. 散列每个点,然后忘记原始数据。散列集现在是散列指纹组合。

然后比较两个散列指纹组合,循环每个组合的指纹组合。例如:

public static bool AreMatching(
      Portfolio portfolio_A
    , Portfolio portfolio_B
  )
{
  foreach (var fingerPrint_A in portfolio_A)
  {
    foreach (var fingerPrint_B in portfolio_B)
    {
      if (fingerPrint_A == fingerPrint_B) { return true; }
    }
  }

  return false;
}

从概念上讲,基本问题是加密散列故意消除了比较两个值是否接近的能力,但我们仍然可以在散列之前计算附近点的集合。

然后每个指纹哈希编码一个被认为是匹配的局部近似值。