⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sha1.c

📁 美国安全散列算法,可兼容于嵌入式C程序.已在ICC, KEIL中得到验证
💻 C
字号:


#include	"SHA1.H"

////////////////////////////////////////////////////////////////////////////////////////////////////
//
static u8 SHA1_Padding[64] = {
				0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
				};
		
////////////////////////////////////////////////////////////////////////////////////////////////////
//将字节串中的4字节转换成32位整型数,低地址为高位
#define GET_u32(num,bytes,index)                    	\
{															\
	(num)	= ( (u32) (bytes)[(index) + 0] << 24 )      \
			| ( (u32) (bytes)[(index) + 1] << 16 )      \
			| ( (u32) (bytes)[(index) + 2] <<  8 )      \
			| ( (u32) (bytes)[(index) + 3]       );     \
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//将32位整型数存放在字节串中指定位置,低地址放高位
#define PUT_u32(num,bytes,index)                    	\
{															\
	(bytes)[(index) + 0] = (u8) ( (num) >> 24 );		\
	(bytes)[(index) + 1] = (u8) ( (num) >> 16 );		\
	(bytes)[(index) + 2] = (u8) ( (num) >>  8 );		\
	(bytes)[(index) + 3] = (u8) ( (num)       );		\
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//SHA移位算法,将32位整型数移位n位
#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
////////////////////////////////////////////////////////////////////////////////////////////////////
//SHA算法初始化,即中间变量赋初值
void SHA1_Init( SHA1_CONTEXT *ctx )
{
    ctx->total[0] = 0;
    ctx->total[1] = 0;

    ctx->Hash[0] = 0x67452301;
    ctx->Hash[1] = 0xEFCDAB89;
    ctx->Hash[2] = 0x98BADCFE;
    ctx->Hash[3] = 0x10325476;
    ctx->Hash[4] = 0xC3D2E1F0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//SHA算法模块
void SHA1_Process( SHA1_CONTEXT *ctx, u8 data[64] )
{
	u16	i;
    u32 temp, W[16], A, B, C, D, E;
	for(i=0;i<16;i++){
		GET_u32(W[i],data,i*4);
	}
	#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
	#define R(t)                                            \
	(                                                       \
	    temp = W[(t -  3) & 0x0F] ^ W[(t - 8) & 0x0F] ^     \
	           W[(t - 14) & 0x0F] ^ W[(t -16) & 0x0F],      \
	    ( W[t & 0x0F] = S(temp,1) )                         \
	)
	#define P(a,b,c,d,e,x) {e += S(a,5) + F(b,c,d) + K + x; b = S(b,30);}
    A = ctx->Hash[0];
    B = ctx->Hash[1];
    C = ctx->Hash[2];
    D = ctx->Hash[3];
    E = ctx->Hash[4];
	#define F(x,y,z) (z ^ (x & (y ^ z)))
	#define K 0x5A827999
	for(i=0;i<20;i++){
		if(i<16){
			P( A, B, C, D, E, W[i]  );
		}else{
			P( A, B, C, D, E, R(i) );
		}
		temp=E;
		E=D;D=C;C=B;B=A;A=temp;					
	}
	#undef K
	#undef F
	#define F(x,y,z) (x ^ y ^ z)
	#define K 0x6ED9EBA1
	for(i=20;i<40;i++){
		P( A, B, C, D, E, R(i) );
		temp=E;
		E=D;D=C;C=B;B=A;A=temp;					
	}
	#undef K
	#undef F
	#define F(x,y,z) ((x & y) | (z & (x | y)))
	#define K 0x8F1BBCDC
    for(i=40;i<60;i++){
		P( A, B, C, D, E, R(i) );
		temp=E;
		E=D;D=C;C=B;B=A;A=temp;					
	}
	#undef K
	#undef F
	#define F(x,y,z) (x ^ y ^ z)
	#define K 0xCA62C1D6
    for(i=60;i<80;i++){
		P( A, B, C, D, E, R(i) );
		temp=E;
		E=D;D=C;C=B;B=A;A=temp;					
	}
	#undef K
	#undef F
    ctx->Hash[0] += A;
    ctx->Hash[1] += B;
    ctx->Hash[2] += C;
    ctx->Hash[3] += D;
    ctx->Hash[4] += E;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
//功能:	对输入数据的SHA算法
//输入:	ctx:	SHA1算法需要的上下文变量,
//		input:	以字节为单位的输入数据指针
//		length:	输入数据的字节长度
//输入:	ctx:
void SHA1_Update( SHA1_CONTEXT *ctx, u8 *input, u32 length )
{
    u32 left, fill;
    u16	i;

    if(!length) return;

    left = ctx->total[0] & 0x3F;	//64 Bytes = 512 bits
    fill = 64 - left;

    ctx->total[0] += length;
    ctx->total[0] &= 0xFFFFFFFF;

    if( ctx->total[0] < length )
        ctx->total[1]++;

    if( left && length >= fill ) {
    	for(i=0;i<fill;i++){
    		*(u8 *)(ctx->buffer + left+i) = *(u8 *)(input+i);
    	}
        SHA1_Process( ctx, ctx->buffer );
        length -= fill;
        input  += fill;
        left = 0;
    }

    while( length >= 64 ){
        SHA1_Process( ctx, input );
        length -= 64;
        input  += 64;
    }

    if( length ){
    	for(i=0;i<length;i++){
    		*(u8 *)(ctx->buffer + left+i) = *(u8 *)(input+i);
    	}
    }
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//功能:	对输入数据的SHA算法
//输入:	ctx:	SHA1算法需要的上下文变量,
//输出:	digest:	输入信息的SHA1算法结果--摘要信息,以字节为单位存放
void SHA1_Finish( SHA1_CONTEXT *ctx, u8 digest[20] )
{
    u32 last, padn;
    u32 high, low;
    u8 	msglen[8];

    high = ( ctx->total[0] >> 29 )
         | ( ctx->total[1] <<  3 );
    low  = ( ctx->total[0] <<  3 );

    PUT_u32( high, msglen, 0 );
    PUT_u32( low,  msglen, 4 );

    last = ctx->total[0] & 0x3F;
    padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );

    SHA1_Update( ctx, SHA1_Padding, padn );
    SHA1_Update( ctx, msglen, 8 );

    PUT_u32( ctx->Hash[0], digest,  0 );
    PUT_u32( ctx->Hash[1], digest,  4 );
    PUT_u32( ctx->Hash[2], digest,  8 );
    PUT_u32( ctx->Hash[3], digest, 12 );
    PUT_u32( ctx->Hash[4], digest, 16 );
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -