• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

简化版的SHA1算法C语言版

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

最近用到了一些常规散列算法,学习一下SHA算法,网上SHA1介绍很多,也有实例,但代码风格似乎不符合我的审美。

经过学习验证,编写了一个简化版的SHA1算法,为什么叫简化版呢?

因为这个算法只能处理56字节以内的数据,大于等于56字节的情况要分组计算。

分组补位有点麻烦,怎么合理分组,还有待思考。

先贴出简化版的代码吧。

/*
* SHA1散列算法
* <[email protected]>
* 参考:http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
*/
#include <stdio.h>
#include <string.h>
#include "sha1.h"

#define S(x,n)	(((x)<<n)|(x)>>(32-n))	//SHA定义S函数为循环左移

static unsigned long h[5];
static unsigned long m[16];
static unsigned long w[80];

//补位(余数=448)+补长度(64位)=512位M
static void sha1_pad(unsigned char *input, int len)
{
	int i;
	int n;

	for(i=0;i<16;i++)
	{
		m[i] = 0;
	}

	for(i=0;i<len;i++)
	{
		n = 24-((i&0x03)<<3);
		m[i/4] |= input[i]<<n;
	}
	n = 24-((i&0x03)<<3);
	m[i/4] |= 0x80<<n;
	m[15] = len*8;
}

//由512位M生成80字W
static void sha1_prepare(void)
{
	int i;
	for(i=0;i<16;i++)
	{
		w[i]=m[i];
	}
	for(i=16;i<80;i++)
	{
		w[i]=w[i-16]^w[i-14]^w[i-8]^w[i-3];
		w[i]=S(w[i],1);
	}
}

//由80字W计算sha1
static void sha1_calc(void)
{
	int i;
	unsigned long a,b,c,d,e,f,k;
	unsigned long temp;
	
	h[0]=0x67452301;
	h[1]=0xEFCDAB89;
	h[2]=0x98BADCFE;
	h[3]=0x10325476;
	h[4]=0xC3D2E1F0;
	
	a = h[0];
	b = h[1];
	c = h[2];
	d = h[3];
	e = h[4];
	for(i=0;i<80;i++)
	{
		switch(i/20)
		{
		case 0:
			k=0x5A827999;
			f=(b&c)|(~b&d);
			break;
		case 1:
			k=0x6ED9EBA1;
			f=b^c^d;
			break;
		case 2:
			k=0x8F1BBCDC;
			f=(b&c)|(b&d)|(c&d);
			break;
		case 3:
			k=0xCA62C1D6;
			f=b^c^d;
			break;
		}
		temp=S(a,5)+f+e+w[i]+k;
		e=d;
		d=c;
		c=S(b,30);
		b=a;
		a=temp;
	}
	h[0]+=a;
	h[1]+=b;
	h[2]+=c;
	h[3]+=d;
	h[4]+=e;
}

//SHA1算法接口
//input:待校验的数据
//len:数据长度(小于56字节)
unsigned long* sha1(void* input, int len)
{
	sha1_pad(input,len);
	sha1_prepare();
	sha1_calc();
	return h;
}



测试用例:

void main(void)
{
	char str[1024];
	unsigned long* mac;
	while(1)
	{
		puts("input:");
		gets(str);
		mac=sha1(str,strlen(str));
		printf("SHA1=%08X%08X%08X%08X%08X\n",mac[0],mac[1],mac[2],mac[3],mac[4]);
		system("pause");
	}
}

运算结果:

input:
123
SHA1=40BD001563085FC35165329EA1FF5C5ECBDBBEEF
请按任意键继续. . .
input:
123456
SHA1=7C4A8D09CA3762AF61E59520943DC26494F8941B
请按任意键继续. . .




鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
C#实现office文档转换为PDF格式发布时间:2022-07-14
下一篇:
c++优先队列(堆)发布时间:2022-07-14
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap