当与一系列的数字打交道,和想要使用散列结果出于安全考虑,什么将是从给定的一系列数字的哈希值的最佳方式是什么? 输入的例子是信用卡号码或银行账号。 优选的输出将是一个单一的无符号整数,以协助匹配的目的。
我的感觉是,大部分的字符串实现的时候出现对人物如此近距离运行,正因为如此,碰撞率可能是对的时候更大样本运行高于具有较低的熵。
目标语言是德尔福,但是从其他语言的答案,欢迎,如果他们可以提供一个工科数学基础这可能会导致一个最佳的解决方案。
该例程的目的将是,以确定是否先前接收到的卡/帐户先前被处理或没有。 输入文件可以有针对的多个记录的数据库多个记录,因此性能是一个因素。
随着安全问题的所有答案躺在从最安全 最方便的连续性 。 我给你两个答案,一个是非常安全的,另外一个是非常方便的。 鉴于各的解释,你可以选择适合您的系统的最佳解决方案。
你说,你的目标是这个值存储在代替实际的信用卡,所以你以后可以知道,如果相同的信用卡号被重新使用。 这意味着它只能包含信用卡号码,也许一个统一的盐。 在CCV,到期日期,姓名等夹杂物会使其无用的,因为它的价值可以用相同的信用卡号码不同。 因此,我们将假定你垫所有的信用卡号码与相同的盐值将保持统一的所有条目。
该方便的解决方案是使用一个FNV (如Zebrabox和尼克建议的)。 这将产生一个32位的数字将很快指数进行搜索。 当然,缺点是,它仅允许在最多4个十亿不同的号码,并在实践中会产生碰撞更快那么。 因为它有如此高的碰撞率强力攻击可能会产生足够无效的结果,使之没有多大用处。
在安全的解决方案是依靠SHA哈希函数(越大越好),但多次迭代。 我建议10000顺序上的某个地方。 是的,我知道,10,000次重复很多,它会需要一段时间,但是当涉及到对实力蛮力攻击速度是我们的敌人。 如果你想成为安全的,那么你希望它是缓慢的。 SHA被设计成没有输入任何规模的冲突。 如果发现冲突,则散列被认为不再可行。 据我所知的SHA-2家族仍然是可行的。
现在,如果你想有一个解决方案, 安全和快速的在数据库中进行搜索,那么我会建议使用安全解决方案(SHA-2×10K),然后储存在一列完整的哈希值,然后取前32位,将其存储在不同的列中,与第二列的索引。 首先进行的32位值的查找。 如果产生不匹配,那么你就没有比赛。 如果它确实产生匹配,那么你可以比较完整的SHA值,看看它是否是相同的。 这意味着你正在执行完整的二进制比较(散列实际上是二元的,但只表示为便于人类阅读的字符串和基于文本传输协议)要小得多集。
如果你真的关心速度,那么你可以减少迭代的次数。 坦率地说它仍然是快,即使1000次迭代。 你会希望你期望有多大的数据库中获得一些现实的主观判断和其他因素(通信速度,硬件响应,负载等),可能效果的持续时间。 你可能会发现你优化的过程中,这将有很少或几乎没有实际影响最快的点 。
另外,我建议你基准上完整的哈希值与32位的子集查找。 大多数现代数据库系统是相当快的,并且包含一些优化和经常优化为我们做事情的简单方法。 当我们试图让我们的智能有时只是慢下来。 是什么样的过早优化该报价。 。 。 ?
这似乎是一个情况下, 密钥导出函数 。 看一看PBKDF2 。
刚开始使用加密散列函数(如SHA系列)会给你想要的分配,但对于非常有限的输入空间(如信用卡号码),他们可以用蛮力很容易受到攻击,因为这个哈希算法通常设计得一样快可能。
UPDATE
好了,安全是你的任务没有问题。 因为你已经有一个数字输入,你可以只使用这个(账户)数模的散列表的大小。 如果你处理它作为字符串,你可能确实遇到不好的分布,因为十位形成唯一的所有可能的字符的一小部分。
另一个问题可能是,这些数字形成分配(账户)的大簇号与他们之间的未分配号码的大区域。 在这种情况下,我会建议尝试高度非线性的散列函数来传播这个集群。 这又让我们回到了加密散列函数。 也许好老MD5。 只是分裂128位散列在四组的32位,使用XOR将它们结合起来,并解释该结果作为一个32位的整数。
虽然没有直接的关系,你也可以看看本福德定律 -它提供了一些见解,为什么数字通常不是均匀分布的。
如果你需要的安全,使用加密的安全散列,如SHA-256。
我需要深入调查的散列函数在几个月前。 这里有一些事情我发现。
您希望散列在您的整个目标空间均匀地随机散布命中(通常为32位,但可能是16或64位。)你想输入的每一个字符有,而在输出同样大的影响。
ALL简单散列(如ELF或PJW),简单地通过环与移位或国防部每个字节串和XOR将失败,对于一个简单的原因标准:所加的最后一个字符有最效果。
但也有在Delphi和ASM提供一些非常好的算法。 下面是一些参考:
见1997年burtleburtle.net/bob/hash/doobs.html布斯博士的文章
在burtleburtle.net/bob/c/lookup3.c代码
由保罗·谢SuperFastHash功能c2004-2008(AKA HsiehHash)
www.azillionmonkeys.com/qed/hash.html
你会发现德尔福(可选ASM)在这个参考源代码:
http://landman-code.blogspot.com/2008/06/superfasthash-from-paul-hsieh.html
2008年7月13日
“一年多前尤哈尼Suhonen要求快速哈希使用他的哈希表。我建议老了,但很好地执行精灵散,但也注意到一个更好的哈希函数我最近发现,它被称为SuperFastHash(SFH)和由保罗·谢创造克服自己的“问题”与鲍勃·詹金斯。尤哈尼·哈希函数问,如果有人可以写在BASM的SFH功能。几个人在一个简易工况法的实施工作,并张贴“。
散列传奇仍在继续:
2007-03-13安德鲁:当坏散列办法不错缓存
www.team5150.com/~andrew/blog/2007/03/hash_algorithm_attacks.html
2007-03-29安德鲁:打破SuperFastHash
floodyberry.wordpress.com/2007/03/29/breaking-superfasthash/
2008-03-03奥斯汀艾波比:murmur哈希2.0
murmurhash.googlepages.com/
SuperFastHash - 985.335173 MB /秒
lookup3 - 988.080652 MB /秒
murmur哈希2.0 - 2056.885653 MB /秒
供应C ++代码MurmurrHash2.cpp并排列成行的只读实现 -
MurmurHashAligned2.cpp
// ================================================ ========================
//这里是兰德曼的MurmurHash2在C#
// 2009-02-25戴维·兰德曼确实SuperFashHash和MurmurHash2的C#implimentations
//landman-code.blogspot.com/search?updated-min=2009-01-01T00%3A00%3A00%2B01%3A00&updated-max=2010-01-01T00%3A00%3A00%2B01%3A00&max-results=2
//
//兰德曼impliments在C#都SuperFastHash和MurmurHash2 4种方式:
// 1:托管代码2:内嵌位转换器3的:int哈克4:不安全指针
// SuperFastHash 1:281 2:780 3:1204 4:1308 MB / s的
// MurmurHash2 1:486 2:759 3:1430 4:2196
很抱歉,如果上述原来看起来像一个烂摊子。 我只是剪切和粘贴。
至少其中一个引用上面给你走出一个64位的哈希,这必将有没有冲突的信用卡号码的空间的选项,并可以很容易地存储在一个BIGINT场在MySQL。
你并不需要一个密码散列。 他们更CPU密集型。 和“密码”的目的是为了阻止黑客,而不是避免冲突。
如果性能是一个因素,我建议看看在CodeCentral进入彼得下方。 这对于大量物品有很好的表现。
默认情况下,它使用PJ温伯格ELF 散列函数 。 但也提供了其他。
根据定义,密码散列将很好地工作为您的使用情况。 即使人物接近,哈希应该很好地分配。
所以,我建议你使用任何加密散列(SHA-256为例),用的盐。
对于非加密的方法,你可以看看在FNV哈希它的快速与低碰撞率。
作为一个非常快的选择,我也用这个算法了几年,很少有冲突的问题,但是我不能给你一个数学分析它的内在合理性,但因为这是它的价值在这里
=编辑 - 我的代码示例是不正确的 - 现在固定=
在C / C ++
unsigned int Hash(const char *s)
{
int hash = 0;
while (*s != 0)
{
hash *= 37;
hash += *s;
s++;
}
return hash;
}
请注意,“37”是一个神奇的数字,这样选择是因为它的黄金