原創快速哈希算法 FHA1

    快速哈希算法 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   0xEA924957ull
void 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一樣。更大的文件還有待進一步測試


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章