C語言實現(xiàn)SHA1算法

1.頭文件及循環(huán)左移.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define SAL(x,n) (((x>>(32-n)))|(x<<n))

2.字符串擴充.

int sha1_pad_message(unsigned char *str, int len)
{
    unsigned long high, low;
    int u = len % 64;

    high = 0;
    low = len * 8;

    if(u < 56)
    {
        str[len++] = 0x80;
        u++;

        while(u < 56)
        {
            str[len++] = 0x00;
            u++;
        }
    }
    else if(u > 56)
    {
        str[len++] = 0x80;
        u++;

        while(u < 56+64)
        {
            str[len++] = 0x00;
            u++;
        }
    }

    str[len++] = high >> 24;
    str[len++] = high >> 16;
    str[len++] = high >> 8;
    str[len++] = high;
    str[len++] = low >> 24;
    str[len++] = low >> 16;
    str[len++] = low >> 8;
    str[len++] = low;

    return len;
}

3.字符串打印.

int print_str(unsigned char *str, int len)
{
    int i = 0;

    printf("str=[");

    for(i=0; i<len; i++)
    {
        printf("%02X", str[i]);
    }

    printf("], len=[%d]\n", len);

    return 0;
}

4.信息分組處理.

int sha1_str_group_xor(unsigned char *a, unsigned char *b, unsigned char *c, unsigned char *d, unsigned char *e, int len)
{
    int i = 0;

    for(i=0; i<len; i++)
    {
        e[i] = a[i] ^ b[i] ^ c[i] ^ d[i];
    }

    return 0;
}

int sha1_str_group_sal(unsigned char *a, int len)
{
    int x = 0;
    int y = 0;
    int i = 0;

    for(i=len-1; i>=0; i--)
    {
        //printf("a[%d]=%d\n", i, a[i]);
        x = a[i] >> 7;
        a[i] <<= 1;
        //printf("a[%d]=%d\n", i, a[i]);
        a[i] |= y;
        //printf("a[%d]=%d\n", i, a[i]);
        y = x;
    }

    a[len-1] |= y;

    return 0;
}

unsigned long sha1_str_to_long(unsigned char *a)
{
    unsigned long x = 0;
    unsigned char *b = (unsigned char *)&x;

    b[0] = a[3];
    b[1] = a[2];
    b[2] = a[1];
    b[3] = a[0];

    return x;
}

int sha1_long_to_str(unsigned long a, unsigned char *b)
{
    unsigned long x = a;
    unsigned char *d = (unsigned char *)&x;

    b[0] = d[3];
    b[1] = d[2];
    b[2] = d[1];
    b[3] = d[0];

    return 0;
}

int sha1_str_group(unsigned char *str, int len)
{
    unsigned char M[64];
    unsigned char W[80][4];
    int u = len / 64;
    int v = 64 / 16 * 80;
    int i = 0;
    int j = 0;

    for(i=u-1; i>=0; i--)
    {
        memset(M, 0x00, sizeof(M));

        memcpy(M, str+i*64, 64);
        memcpy(str+i*v, M, 64);

        for(j=0; j<16; j++)
        {
            memcpy(W[j], M+4*j, 4);
            printf("W[%02d], ", j);
            print_str(W[j], 4);
        }

        for(j=16; j<80; j++)
        {
            sha1_str_group_xor(W[j-3], W[j-8], W[j-14], W[j-16], W[j], 4);
            //printf("W[%02d], ", j);
            //print_str(W[j], 4);
            sha1_str_group_sal(W[j], 4);
            printf("W[%02d], ", j);
            print_str(W[j], 4);
            memcpy(str+i*v+4*j, W[j], 4);
            //printf("W[%02d], ", j);
            //print_str(W[j], 4);
        }
    }

    return  u * v;
}

5.計算信息摘要.

int sha1_str_summ(unsigned char *str, unsigned char *summ, int len)
{
    unsigned char W[80][4];
    unsigned char Q[20] = {0x67, 0x45, 0x23, 0x01, 0xEF, 0xCD, 0xAB, 0x89, 0x98, 0xBA, 0xDC, 0xFE, 0x10, 0x32, 0x54, 0x76, 0xC3, 0xD2, 0xE1, 0xF0};
    unsigned long K[4]={0x5A827999,0x6ED9EBA1,0x8F1BBCDC,0xCA62C1D6};
    unsigned long N[5]={0, 0, 0, 0, 0};
    unsigned long A = sha1_str_to_long(Q);
    unsigned long B = sha1_str_to_long(Q+4);
    unsigned long C = sha1_str_to_long(Q+8);
    unsigned long D = sha1_str_to_long(Q+12);
    unsigned long E = sha1_str_to_long(Q+16);
    unsigned long F = 0;
    unsigned long G = 0;
    unsigned long H = 0;

    int u = len / 320;
    int i = 0;
    int j = 0;
    int k = 0;

    N[0] += A;
    N[1] += B;
    N[2] += C;
    N[3] += D;
    N[4] += E;

    for(i=0; i<u; i++)
    {
        for(j=0; j<80; j++)
        {
            memcpy(W[j], str+i*320+j*4, 4);
        }

        A = N[0];
        B = N[1];
        C = N[2];
        D = N[3];
        E = N[4];

        for(k=0; k<20; k++)
        {
            printf("A=[%08x]\n", A);

            G = sha1_str_to_long(W[k]);

            printf("W[%d]=[%08x]\n", i, G);
            F = ((B & C) | (~B & D));
            H = SAL(A,5) + F + E + G + K[0];
            E = D;
            D = C;
            C = SAL(B,30);
            B = A;
            A = H;

            printf("A=[%08x]\n", A);
        }

        for(k=20; k<40; k++)
        {
            G = sha1_str_to_long(W[k]);
            F = (B ^ C ^ D);
            H = SAL(A,5)+ F + E + G + K[1];
            E = D;
            D = C;
            C = SAL(B,30);
            B = A;
            A = H;

            printf("A=[%08x]\n", A);
        }

        for(k=40; k<60; k++)
        {
            G = sha1_str_to_long(W[k]);
            F = ((B & C) | (B & D) | (C & D));
            H = SAL(A,5)+ F + E + G + K[2];
            E = D;
            D = C;
            C = SAL(B,30);
            B = A;
            A = H;

            printf("A=[%08x]\n", A);
        }

        for(k=60; k<80; k++)
        {
            G = sha1_str_to_long(W[k]);
            F = (B ^ C ^ D);
            H = SAL(A,5)+ F + E + G + K[3];
            E = D;
            D = C;
            C = SAL(B,30);
            B = A;
            A = H;

            printf("A=[%08x]\n", A);
        }

        N[0] += A;
        N[1] += B;
        N[2] += C;
        N[3] += D;
        N[4] += E;
    }

    sha1_long_to_str(N[0], Q);
    sha1_long_to_str(N[1], Q+4);
    sha1_long_to_str(N[2], Q+8);
    sha1_long_to_str(N[3], Q+12);
    sha1_long_to_str(N[4], Q+16);

    memcpy(summ, Q, 20);

    return 0;
}

6.主函數(shù)部分.

int main()
{
    unsigned char str[256/16*80] = {0};
    unsigned char str_sha1[20];
    int len = 6;

    str[0] = 'a';
    str[1] = 'b';
    str[2] = 'c';
    str[3] = 'd';
    str[4] = 'e';
    str[5] = 'f';

    print_str(str, len);

    len = sha1_pad_message(str, len);

    print_str(str, len);

    len = sha1_str_group(str, len);

    print_str(str, len);

    sha1_str_summ(str, str_sha1, len);

    print_str(str_sha1, 20);

    return 0;
}
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末菇晃,一起剝皮案震驚了整個濱河市颅眶,隨后出現(xiàn)的幾起案子克滴,更是在濱河造成了極大的恐慌,老刑警劉巖庵佣,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件企蹭,死亡現(xiàn)場離奇詭異又兵,居然都是意外死亡,警方通過查閱死者的電腦和手機枫笛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進店門吨灭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人刑巧,你說我怎么就攤上這事喧兄。” “怎么了啊楚?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵吠冤,是天一觀的道長。 經(jīng)常有香客問我恭理,道長拯辙,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任颜价,我火速辦了婚禮涯保,結果婚禮上,老公的妹妹穿的比我還像新娘周伦。我一直安慰自己夕春,他們只是感情好,可當我...
    茶點故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布专挪。 她就那樣靜靜地躺著及志,像睡著了一般片排。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上速侈,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天率寡,我揣著相機與錄音,去河邊找鬼锌畸。 笑死勇劣,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的潭枣。 我是一名探鬼主播比默,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼盆犁!你這毒婦竟也來了命咐?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤谐岁,失蹤者是張志新(化名)和其女友劉穎醋奠,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體伊佃,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡窜司,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了航揉。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片塞祈。...
    茶點故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖帅涂,靈堂內(nèi)的尸體忽然破棺而出议薪,到底是詐尸還是另有隱情,我是刑警寧澤媳友,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布斯议,位于F島的核電站,受9級特大地震影響醇锚,放射性物質(zhì)發(fā)生泄漏哼御。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一搂抒、第九天 我趴在偏房一處隱蔽的房頂上張望艇搀。 院中可真熱鬧,春花似錦求晶、人聲如沸焰雕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽矩屁。三九已至辟宗,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間吝秕,已是汗流浹背泊脐。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留烁峭,地道東北人容客。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像约郁,于是被迫代替她去往敵國和親缩挑。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,077評論 2 355

推薦閱讀更多精彩內(nèi)容