【问题标题】:Checking if a string hash contains a substring hash检查字符串哈希是否包含子字符串哈希
【发布时间】:2019-08-08 21:08:00
【问题描述】:

假设我有大量文档以某种方式散列(例如 Sha256)并存储它们的散列。是否有一种散列技术可以让我通过查看它们的散列来检查string1 是否包含在string2 中?我想避免加载全文。

澄清一下:这与 sim/min-hashing、寻找近似重复或 Levenshtein 距离无关。我正在寻找一种散列算法,它可以让我通过查看散列来检查子字符串。

例如

var string1 = "bla bla bla cat dog bla bla";
var string2 = "cat dog";
var hash1 = HashAlgo(string1); // <-- magic goes here
var hash2 = HashAlgo(string2);
Assert.IsTrue(string1.Contains(string2));
Assert.IsTrue(hash1.Contains(hash2)); // <--- magic goes here

【问题讨论】:

  • 如果不扩展“哈希”的定义,我不确定这是否可行。据我所知,散列是一个有损的过程。
  • 我想这是不可能的。如果可能,这可能是一个巨大的安全风险
  • 堆积到最后两个 cmets。这是不可能的,也不应该是可能的。任何允许这种事情发生的散列都是一个安全漏洞,并且与“散列”的整个概念背道而驰。想象一下用这种“魔法”散列值aababcabcdabcde。每个散列都会包含前一个,基本上你最终得到的只是一些奇怪的翻译函数,而不是散列。
  • 如果你散列行并且主散列是来自那些散列的 函数 具有(不知道这个术语)能够检查它包含你给出的任何散列的能力,那么您可以对任何行进行哈希处理以检查它是否存在。段落更好。最简单的主散列函数是字符串连接。注意:hash hit 不代表真的,它的意思是“也许”。
  • 您需要索引而不是散列。建立所有文档中所有单词的索引。或者更好的是,使用为您执行此操作的数据库。谷歌搜索“全文索引”。

标签: c# string hash


【解决方案1】:

如果你仔细想想,这是不可能的。

首先,所有 SHA256 哈希的长度完全相同。我的答案基于 SHA256,但据我所知,这适用于任何散列方法。

  • 考虑一个 1000 个字符的文档,您已经对其进行了 SHA256 哈希处理。它的哈希长度为 64 位。
  • 考虑一个 100 个字符的文档,您已经对其进行了 SHA256 哈希处理。它的哈希是 64 位长。该文档的内容恰好是较大文档的第一章。
  • 考虑第二个 100 个字符的文档,您已经对其进行了 SHA256 哈希处理。它的哈希是 64 位长。这份文件的内容恰好是大文件的第二章。

较大文件的哈希值不可能同时包含两个较小文件的哈希值,因为只有在所有三个哈希值都相等的情况下才有可能

其次,想想我可以从 1000 个字符的文档中取出多少个 100 个字符的子字符串。不只是 10(如 1000/100 = 10),而是 900。将子字符串表示为索引边界,有很多可能性:

  • 0 到 100
  • 1 到 101
  • 2 到 102
  • ...
  • 897 到 997
  • 898 到 998
  • 899 到 999

总共有 900 个选项。假设您的初始文档不会以任何方式重复自身(因此您不会得到两个相等的子字符串),这将导致 900 个(假定的)唯一哈希。

这 900 个唯一哈希不能都是初始文件哈希的子字符串。

此外,考虑到我们甚至没有考虑过其他长度的子字符串!假设任何可能的子字符串长度,您最终可以得到 999,000 个不同的子字符串(当然其中一些会有重复)

这甚至还没有考虑到原始文档的长度可能超过 1000 个字符。对于任何具有 n 个字符的文档,您可以期望找到 n*(n-1) 个子字符串(长度在 1 和 n 之间),其中主要是唯一的哈希值。

这种可能值的扩展仅在您达到 1077(更准确地说,2256)的数量级时才会停滞,因为这是有多少独特的SHA 哈希可能存在。
餐巾纸的背面,这将是一个 1038 字节的文档。一旦达到该文件大小,所有可能的子字符串(任何长度)都必须包含至少一个重复。

我想你可以明白为什么你的建议在数学上根本不可能。

我将把它作为旁注,但superpermutations 是一个切题的话题,值得一看,以了解这是多么不可能。对于 7 个唯一字符,如果您想包含这 7 个字符的所有可能排列,则需要 5907 个数字 的超排列。这是我们发现的(最小)超排列的最高 N。

对于将全部包含在您的“主”哈希中的 900 个唯一哈希(= 十六进制字符的唯一排列)的初始示例,主哈希所需的最小长度简直无法计算。但是作为 绝对 最小值(您可能无法达到),您的主哈希必须是 963 个字符长(如果您假设每个 64 个字符的子字符串总是给您一个唯一的新哈希)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-02
    • 1970-01-01
    • 2012-05-16
    • 2020-07-19
    • 2017-04-28
    • 2016-02-22
    • 1970-01-01
    相关资源
    最近更新 更多