【问题标题】:Looking for hash algorithm where small change in input will result in small change on hash寻找哈希算法,其中输入的微小变化将导致哈希的微小变化
【发布时间】:2016-11-21 18:01:59
【问题描述】:

当前的哈希函数被设计成对哈希有很大的改变,即使只有很小一部分输入被改变。我需要的是一个哈希算法,它的输出变异将与输入变异成正比。例如,我需要类似这样的东西:

Hash("STR1") => 1000
Hash("STR2") => 1001
Hash("STR3") => 1002

等等。 我不擅长算法,但从未听说过这样的实现,尽管我几乎可以肯定应该已经有人提出了这个算法。

我目前的要求是具有大比特率(可能是 512 位?)以避免冲突。

谢谢

更新

我想我应该澄清我的目标,我发现我在解释我需要什么方面做得很糟糕。抱歉,我的母语不是英语,也不是很好的沟通者。

所以基本上我需要这个哈希算法来搜索类似的二进制文件。您可以将其视为防病毒散列算法。它计算文件校验和,但与传统的散列函数不同,即使在恶意软件二进制文件中进行一些小的修改后,它仍然能够检测到它。这几乎是我正在寻找的。

另一个方面是避免碰撞。让我解释一下我的意思。这不是一个矛盾的目标。我希望 Hash("STR1") 产生 1000 和 Hash("STR2") 产生 1001 或 1010 也许,只要该值与先前的哈希值接近,就没有关系。但是 Hash("这是一个非常大的字符串,甚至可能是二进制数据" + 100 个随机字符) 不应该产生接近 1000 的值。我知道它不会总是有效,并且会有一些哈希/哈希范围冲突,但是我想我可以引入另一种哈希算法并验证两者以尽量减少冲突。

那你怎么看?也许有更好的方法来实现我的目标,也许我要求太多了,我不知道。我不太精通密码学、数学或算法。

再次感谢您的时间和精力

【问题讨论】:

  • 我希望你知道这在安全方面非常薄弱,但我想我也许能找到一些东西......
  • 是的,这不是为了安全目的,而是为了搜索:)。谢谢你的努力劳雷尔:)
  • 你还需要“1str”、“2str”、“3str”来散列在一起吗?
  • 避免冲突与您保持哈希结果“接近性”的目标不相容。你必须选择一个。
  • Locality-sensitive hashing 可以做到这一点,尽管你最终会遇到更多的冲突。如果您的数据集是已知的并且相当小,您可以创建一个perfect hash function,尽管这不能满足您的目标,即小的输入变化导致小的输出变化。 minimal perfect hash 可能就是您要找的。​​span>

标签: c++ algorithm hash cryptography antivirus


【解决方案1】:

MD5 或 SHA-x 不是您想要的。

According to wikipedia,例如substitution cipher没有雪崩效应(这就是你的意思)。

在散列方面,您可以使用某种数字总计

例如:

char* hashme = "hallo123";
int result=0;
for(int i = 0; i<8; ++i) {
   result += hashme[i];
}

【讨论】:

    【解决方案2】:

    简单的求和怎么样?然后您的哈希可以以所需的大小进行包装,如果您在哈希比较期间考虑到这一点,则输入的微小差异应该会产生哈希的微小差异。

    但是,我认为“最小冲突”和“输出的比例变化”是相互矛盾的目标。

    【讨论】:

    • 我也在考虑这个问题,但还是决定试一试,也许有比我更聪明的人已经想出的更好的方法了 :)。无论如何谢谢,如果我找不到更好的方法,我会选择这条路
    【解决方案3】:

    它可能是面向儿童的,但旧的NSA Kid's section 有一些非常好的想法。

    当然,这些算法确实不安全,因此您不能使用它来代替 REAL 加密。 (但如果你只是想玩得开心,你也不能使用真正的加密算法。)


    数字网格涉及建立一个网格,然后使用每个字母的坐标:

    进一步的想法:

    • 混淆字母排列
    • 将数字转换为二进制以进行混淆

    蜿蜒的方式也使用了网格。本质上,字母从左到右排列在网格中,向下排列。输出是通过网格垂直切片产生的:

    【讨论】:

    • 谢谢劳雷尔。对不起,也许我在问一个愚蠢的问题,但是,这种方法比@Jonathon Reinhart 建议的所有字节相加更好吗?这是我的错,我处理的不仅仅是字符串,而是二进制数据。我更新了问题以更好地描述我的问题。再次感谢您的宝贵时间
    【解决方案4】:

    这在其他领域称为感知散列。

    一种方法如下:

    1. 获取训练多组 n-gram。 (例如,如果 n=2 并且您的训练数据是“这是一个测试”,那么您的训练集将是“Th”、“hi”、“is”、“s”等)
    2. 排序并计算所述 n-gram 的频率,降序。

    那么一个词的hash就是“对于数据库中的每个n-gram,这个词的频率是否高于n-gram的平均频率?”

    请注意,不幸的是,这可能并且将会导致与相似词的许多冲突,除非哈希长度过长。

    【讨论】:

      【解决方案5】:

      通常,面向密码学的散列和加密算法的行为方式与您正在寻找的完全相反(即输入的微小变化会导致输出的大变化,反之亦然),所以这个算法类是死路一条。

      作为对这些算法为何如此表现的快速题外话:必然地,它们旨在掩盖输入和输出之间的统计关系,以使它们更难破解。例如,在英语中,字母“e”是迄今为止最常用的字母;在一些非常弱的经典密码中,您可以简单地找到与“e”相对应的最常见的字母和数字(例如 - 如果 n 是最常见的字母,那么几率是 n = e)。实际上,像您描述的统计模式可能会使算法显着更容易受到选择明文、已知明文、中间人和重放攻击的攻击。

      中间人和重放攻击将变得更加容易,因为在不知道密钥的情况下编辑密文以获得所需的明文会更容易(特别是如果您可以访问几个选定的明文)。

      如果你知道

      7/19/2016 1:35 transfer $10 from account x to account y
      

      (日期戳用于防御重放攻击)编码为

      12345678910
      

      7/19/2016 1:40 transfer $10 from account x to account y
      

      编码为

      12445678910
      

      这是一个相当安全的猜测

      12545678910
      

      意思是

      7/19/2016 1:45 transfer $10 from account x to account y
      

      在无法访问原始密钥的情况下,您可以定期重放此数据包,以继续从某人的帐户中窃取资金,只需进行简单的编辑即可。当然,这是一个相当人为的例子,但它仍然说明了基本问题。

      我对您要查找的内容的理解是文件之间的统计相似性。这可能对一些人有所帮助:https://en.wikipedia.org/wiki/Semantic_similarity

      【讨论】:

        【解决方案6】:

        这确实存在。该术语是Locality-sensitive hashing。具体的实现可以在这里找到:https://github.com/trendmicro/tlsh。 根据源文档,您可能需要查看数字取证或 VisualRank(来自 google)以查找类似的图像和视频。对于文本数据,这通常用于反垃圾邮件(在此处阅读更多信息:http://spdp.di.unimi.it/papers/pdcs04.pdf)。对于二进制文件,您可能希望首先运行反汇编程序,然后在文本版本上运行算法 - 但这只是我的感觉,我没有研究支持这一说法,但这将是一个有趣的假设来测试。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-06-07
          • 2012-03-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-06-23
          • 1970-01-01
          相关资源
          最近更新 更多