最终目标:我想识别网格几何数据(和其他属性)的相等性
我选择的意思是:通过比较他们的“ top sha1 hash ”。
但是为了制作顶级哈希,我需要结合子例程中的哈希来散列他们自己的数据。
问题:如何组合加密哈希值,例如sha1
哈希值?
(我想要一个boost::hash_combine<160>(h1, h2)
)
NLEWTRM ( N L ong E nough W ant T o R ead M 矿石
在典型的过程编程中,你有一个“函数调用树”,相当于当你让编译器生成你的拷贝构造函数时发生的事情,当你从顶级类中使用它时,你会得到一个执行一个调用的级联调用“深层复制”。
所以,例如等价地,您可以(手动)编写一系列实现size_t hash_value()
(unordered
容器要求)的可散列类型,并且在任何类型上调用hash_value()
(通过ADL)将导致< strong>“深度哈希”,因为您在计算对象“本地顶部哈希”时关心使用boost::hash_combine
。
我已经看到了boost::hash_combine
的实施方式,这对size_t
来说非常好。
这种组合对于从尊重封装的子程序逐步计算散列是必要的。
我认为这个问题在某种程度上类似于“哈希树”或“哈希列表”,并且在“块”方面(根据我的知识)已经在MD5中解决了,当您对一个流不能进行哈希处理时一次存储所有数据。
请注意,在我的使用中,我不需要通过一次散列所有数据来进行的HASH。因为我的实现(调用树)将是稳定的,如果它们具有相同的数据,则2个不同的mesh-object将产生相同的哈希,并且这是唯一重要的事情。 (因为我需要可比性,而不是官方主义或规范主义,我也不需要加密力量。但我需要合理的唯一性保证(超过size_t
提供的))
显而易见的方式1 :我现在认为的解决方案是将子哈希本身用作消息,连接和重新哈希。 newsha = sha1(hash1 + hash2)
带有+消息(缓冲区)连接操作。
第二种显而易见的方式:将newsha = hash1 ^ hash2
应用于^
模运算符。
答案 0 :(得分:2)
如果您已经了解了hash_combine是如何实现的,那么#34; - 为什么不对160位SHA-1值使用相同的通用逻辑?也就是说,而不是......
seed ^= hash_value(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
...添加一个160位的常量,它有大约一半的位,并且是一个很好的随机排列。 (您需要实现160位算术或使用合适的库 - 例如GMP)。鉴于您的SHA1哈希值是高质量输入,因此没有特别需要更大量的移位 - 没有理由认为较低有效位一直或多或少地随机。如果你想按照boost的例子来选择常量,请使用2 ^ 160而不是2 ^ 32重新应用逻辑:
phi = (1 + sqrt(5)) / 2
the_constant = 2^160 / phi
= 0x4F1B BCDC BFA5 3E0A F9CE 6030 2E76 E41A 0841 13B5
警告 我没有分析这种方法对加密应用程序的影响。
答案 1 :(得分:1)
显而易见的方式:我现在想到的解决方案是将子哈希本身用作消息,连接和重新哈希。 newsha = sha1(hash1 + hash2),带有+消息(缓冲区)连接操作。
是的,这基本上就是你已经提到的hash-list。
不要使用XOR方法,每次使用它时都会让人更容易创建冲突(通常,哈希数据量会比低端数据量少得多)哈希列表的图层,因此性能不应该是一个问题)。完全忘记了相同的哈希相互抵消的问题,感谢Tony D提到它。
请注意,哈希列表的概念确实需要隐式的排序元素。如果您没有特定的订单,那么您可以在执行连接之前对内存中的哈希值进行排序。对哈希进行排序将是例如非常适合计算std:unordered_set
中元素的加密安全散列。