//---------------------------------------------------------------------------
#include <stdio.h>
#include <string.h>
//---------------------------------------------------------------------------
const unsigned long K1 = 0x5A827999;
const unsigned long K2 = 0x6ED9EBA1;
const unsigned long K3 = 0x8F1BBCDC;
const unsigned long K4 = 0xCA62C1D6;

inline unsigned long f1(unsigned long B, unsigned long C, unsigned long D)
{
    return (B & C) | (~B & D);
}

inline unsigned long f2(unsigned long B, unsigned long C, unsigned long D)
{
    return B ^ C ^ D;
}

inline unsigned long f3(unsigned long B, unsigned long C, unsigned long D)
{
    return (B & C) | (B & D) | (C & D);
}

unsigned long S(int n,unsigned long X)
{
    return (X << n) | (X >> (32-n));
}

int SHA_1(unsigned char* InputData, unsigned long inlen, unsigned char* Digest)
{
    int nBlockNum = 0;
//    int nPaddingLen = 0;
    int nLeftLen = 0;
    int temp = inlen * 8;
    unsigned char* buffer = NULL;
    unsigned char* pt = NULL;
    unsigned long H[5] = {0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0};
    unsigned long A=0, B=0, C=0, D=0, E=0;
    unsigned long W[80] = {0};
    unsigned char reverse[4];
    int i=0,t=0;

    if ((InputData == NULL) || (Digest == NULL))
        return 1;    //not allocate memory

    //starting padding

    nBlockNum = (temp>>9)+1;
    nLeftLen = 512-((temp)%512);
    nBlockNum+=((nLeftLen-1) < 64);
//printf("nBlockNum : %d\n",nBlockNum);
/*
    if ((nLeftLen-1) < 64)
    {
        nPaddingLen = nLeftLen + 512;
        nBlockNum++;
    }
    else
    {
        nPaddingLen = nLeftLen;
    }
*/
//    buffer = new unsigned char[nBlockNum*64];
    buffer = (unsigned char *)malloc(nBlockNum*64);
    memset(buffer,0x00,nBlockNum*64);
    memcpy(buffer,InputData,inlen);
    *(buffer+inlen) = 0x80;
    memcpy(reverse,&temp,4);
    for (i=0;i<4;i++)
    {
        *(buffer+nBlockNum*64-4+i) = reverse[3-i];
    }
    //end of padding

    //computing the digest
//printf("nBlockNum : %d\n",nBlockNum);
    for (i=0;i<nBlockNum;i++)
    {
        pt = buffer + 64*i;
       
        for (t=0;t<16;t++)
        {
            reverse[0] = *(pt+4*t+3);
            reverse[1] = *(pt+4*t+2);
            reverse[2] = *(pt+4*t+1);
            reverse[3] = *(pt+4*t);
            memcpy(&W[t],reverse,4);
        }//end for t
       
        for (t=16;t<80;t++)
        {
            W[t] = S(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
        }//end for t

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

        for (t=0;t<80;t++)
        {
            if (t>=0 && t<20)
            {
                temp = S(5,A) + f1(B,C,D) + E + W[t] + K1;
                E = D; D = C; C = S(30,B); B = A; A = temp;
            }
            if (t>=20 && t<40)
            {
                temp = S(5,A) + f2(B,C,D) + E + W[t] + K2;
                E = D; D = C; C = S(30,B); B = A; A = temp;
            }
            if (t>=40 && t<60)
            {
                temp = S(5,A) + f3(B,C,D) + E + W[t] + K3;
                E = D; D = C; C = S(30,B); B = A; A = temp;
            }
            if (t>=60 && t<80)
            {
                temp = S(5,A) + f2(B,C,D) + E + W[t] + K4;
                E = D; D = C; C = S(30,B); B = A; A = temp;
            }
        }//end fot t
        H[0] = H[0] + A;
        H[1] = H[1] + B;
        H[2] = H[2] + C;
        H[3] = H[3] + D;
        H[4] = H[4] + E;
//printf("i : %d\n",i);
    }//end for i
    //end of computing

    for (i=0;i<5;i++)
    {
    memcpy(reverse,&H[i],4);
        for (t=0;t<4;t++)
        {
            *(Digest+4*i+t) = reverse[3-t];
        }//end for t
    }//end for i

    free(buffer);
    return 0;
}

kenny23 發表在 痞客邦 PIXNET 留言(0) 人氣()