原创快速哈希算法 FHA1

来源:互联网 发布:苗阜相声水平知乎 编辑:程序博客网 时间:2024/06/06 10:04

    快速哈希算法 FHA1

转载请注明来源:http://blog.csdn.net/letian0805/article/details/17031139

    FHA1:Fast Hash Algorithm,快速哈希算法第一版。是本人为解决MD5算法面对大文件时效率低而发明的一种信息摘要算法。

    公司的软件用到了MD5算法给每个大文件计算哈希值。

    MD5算法总共分4大轮,每一轮分16步,每一步有6~8个操作。综合下来,整个算法的核心有大约400个操作。经过测试,对一个2G的大文件计算MD5值,在我机器上MD5算法总共需要2.5~3秒。公司的服务器中有很多大文件,基本都是20G以上,给这些文件计算MD5值是特别耗费CPU的事情。为了解决这个问题,我们需要寻找一个效率要比MD5算法高很多的算法,允许有较低概率的碰撞。毕竟我们不是用该算法做加密。

    虽然来公司才半年,但表现很突出,总监比较看好我,所以自然而然就把这个重大的任务交给了我。

    首先,作为信息摘要算法,最重要的是:当修改文件中的某一数据位时,计算出来的哈希值要有很大的差异。而要做到这点,就需要对原始数据进行迭代计算。而且,做迭代计算时,我们不能完全用位与、位或、异或,因为位与的最终结果趋向全0,位或的最终结果趋向全1,异或和位与位或一样无法解决排列问题。所以,我们要利用原始数据,但我们还需要对原始数据加工。所以,设计一种新的信息摘要算法需要注意三点:1)如何加工原始数据。2)如何进行迭代计算。3)如何对待特殊情况(原始数据全0或者全1)。

    纵观MD5算法和SHA1,基本操作有:位反、位与、位或、异或。这两种算法都是利用这些基本操作对原始数据进行加工,并和前面计算的结果迭代计算。MD5是迭代64次,SHA1是迭代79次。然而,我们知道,位操作除了以上4种操作外,还存在移位。在这些操作里,最容易提高计算结果差异的是移位操作,因为移位操作还有一个因素:移多少位。为了充分迭代数据,FHA1算法采用了循环移位操作,移多少位则是由上一步的计算结果决定的。所以FHA1可以说是双重迭代,能够在更少的步骤里达到较大的哈希效果。

    针对特殊数据,MD5算法和SHA1算法都设定了一些常量,或者更好听的称作“魔数”(magic number)。MD5有64个魔数,SHA1有4个魔数。FHA1算法也有魔数,但只有一个,该魔数在32位上是按位对称的。FHA1有两个辅助常量28和13用于确定移位操作的参数。

    下面给出FHA1算法linux 64位版,仅仅是核心代码,没有实现位补全,输出128位结果。

#define CYCLE_SHIFT(_val, _bits) (((_val) << (_bits)) | (((uint64_t)(_val)) >> (64 - (_bits))))#define MAGIC   0xEA924957ullvoid FHA1(uint8_t *data, int n, uint8_t *out){    register uint64_t out0 = 0;    register uint64_t out1 = MAGIC;    register uint64_t *u64data = (uint64_t *)data;    register uint64_t val;    register uint64_t bits;    register int i = (n>>3) - 1;    for (i; i >= 0; i--){        bits = (out1 & 28);        val = (out1 ^ u64data[i]);        out0 ^= CYCLE_SHIFT(val, bits);        bits = (out0 & 13);        val = (~out0 ^ u64data[i]);        out1 ^= CYCLE_SHIFT(val, bits);    }    ((uint64_t *)out)[0] = out0;    ((uint64_t *)out)[1] = out1;}


上面只是64位版,32位版的代码和上面的有比较大的差别。一开始其实是以32位为最小操作单元的,但无奈在64位的服务器上效率低,所以以64位为最小操作单元了。原先的32位的算法就作废了,因为对64位的进行了不少优化,剔除了一些冗余的操作,所以32位的计算结果和这个肯定不一样了,所以需要重新实现一套32位的。

由于本人不擅长汇编,所以只能通过使用register来优化C代码,希望汇编牛人能出个汇编版。

由于该算法效率是MD5的2~2.7倍(视文件大小和程序优化选项而定),所以我给它取了个好听的名字:Fast Hash Algorithm。若抛开循环的影响,核心部分效率是MD5的10~15倍。对data和out的操作都是对内存的操作,是性能瓶颈。

2013.11.29 对一个2G的文件按每块16K大小来测试,碰撞率和MD5算法一样。更大的文件还有待进一步测试。

2013.12.2  对一个22G的压缩文件按每块16K大小测试,该文件有1420618个不同的16K块,计算结果和MD5一样。更大的文件还有待进一步测试


原创粉丝点击