1. 程式人生 > >簡化版的SHA1演算法C語言版

簡化版的SHA1演算法C語言版

最近用到了一些常規雜湊演算法,學習一下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
請按任意鍵繼續. . .



相關推薦

簡化SHA1演算法C語言

最近用到了一些常規雜湊演算法,學習一下SHA演算法,網上SHA1介紹很多,也有例項,但程式碼風格似乎不符合我的審美。 經過學習驗證,編寫了一個簡化版的SHA1演算法,為什麼叫簡化版呢? 因為這個演算法只能處理56位元組以內的資料,大於等於56位元組的情況要分組計算。 分組補

資料結構與演算法C語言分析概述

本節開始將帶領大家系統地學習資料結構,作為一門計算機專業大二學生的必修課程,該課程面對的目標人群為初步具備基本程式設計能力和程式設計思想的程式設計師(大一接觸了 C 語言或者 C++)。通過系統地學習資料結構,可以提高程式設計師分析問題和解決問題的能力。 首先,先來揭開資料結構的神祕面紗,看看什麼是資料結構

CRC32校驗演算法C語言(查表法)

最近用到CRC校驗演算法,就找了些資料,學習了一下,網上關於CRC32的資料也多,但感覺不是很完整,或者太高深。 CRC演算法查表法很常見,但表是怎麼來的,有些資料說得不很清楚。 我來說一下我的看法:

迪傑斯特拉演算法(可列印最短路徑)(資料結構題集C語言7.11)

轉自 https://blog.csdn.net/cxllyg/article/details/7604812   #include <iostream> #include <iomanip> #include <string> usi

資料結構c語言 嚴蔚敏 順序線性表12個基本操作及演算法的實現

標頭檔案: c1.h (相關標頭檔案及函式結果狀態程式碼集合) /* c1.h (程式名) */ #include<string.h> #include<ctype.h> #include<malloc.h> /

資料結構c語言 嚴蔚敏(演算法2.1 將所有在Lb中但不在La中的元素插入到La中)

標頭檔案: c1.h (相關標頭檔案及函式結果狀態程式碼集合) /* c1.h (程式名) */ #include<string.h> #include<ctype.h> #include<malloc.h> /

排序演算法C語言

交換類 氣泡排序(Bubble Sort) O(n2)O(n^2)O(n2) 最簡單的一種排序演算法。先從陣列中找到最大值(或最小值)並放到陣列最左端(或最右端),然後在剩下的數字中找到次大值(或次小值),以此類推,直到陣列有序排列。 void Bubble

LZ77解壓演算法程式(C語言)

壓縮演算法後面有需要再補寫,先記錄一下解壓演算法吧。 壓縮演算法用Java寫的,壓縮的是位元組流。(測試原資料1024bytes–壓縮後為201bytes) 直接上菜吧 #include <stdio.h> #include <stdlib

大學經典教材《資料結構》(C語言 嚴蔚敏 吳為民 編著) 中該演算法的實現

/* 測試資料 教科書 P189 G6 的鄰接矩陣 其中 數字 1000000 代表無窮大 6 1000000 1000000 10 100000 30 100 1000000 1000000 5 1000000 1000000 1000000 1000000 1000000

作業系統程序排程實現演算法c語言

#include <stdio.h>#include <stdlib.h>#include <windows.h>   //包含sleep函式#define TRUE 1#define FALSE 0#define OK 1#define

C語言二分查詢演算法

二分查詢演算法是在有序陣列中用到的較為頻繁的一種演算法,在未接觸二分查詢演算法時,最通用的一種做法是,對陣列進行遍歷,跟每個元素進行比較,其時間為O(n).但二分查詢演算法則更優,因為其查詢時間為O(

排序演算法之歸併排序 ( C語言 )

歸併排序 :(Merge Sort)是建立在歸併操作上的一種有效的排序演算法,該演算法是採用分治法(Divide and Conquer)的一個非常典型的應用。將已有序的子序列合併,得到完全有序的序列;即先使每個子序列有序,再使子序列段間有序。若將兩個有序表合併成一個有序表,

學習總結--《演算法筆記》(c語言

快速入門 摘自《演算法筆記》,胡凡主編 1.%md,可以使不足m位的int形變數以m位進行右對齊輸出,其中高位用空格補齊;如果變數本身超過m位,則保持原樣。 #include<stdio.h> int main(){ int a = 123, b = 3456789;

20150908資料結構(C語言演算法時間複雜度問題

1, 演算法複雜度是在《資料結構》這門課程的第一章裡出現的,因為它稍微涉及到一些數學問題,所以很多同學感覺很難,加上這個概念也不是那麼具體,更讓許多同學複習起來無從下手,下面我們就這個問題給各位考生進行分析。 首先了解一下幾個概念。一個是時間複雜度,一個是漸

最短路徑Dijkstar演算法和Floyd演算法詳解(c語言

轉載請註明出處:http://blog.csdn.net/crescent__moon/article/details/16986765 先說說Dijkstra吧,這種演算法只能求單源最短路徑,那麼什麼是單源最短路徑呢?就是隻能求一個點到別的點最短路徑,而不能求所有點到其它

網路安全學習之C語言DES加密解密演算法的程式設計與實現

其實明白了DES演算法的流程程式設計實現是不難的,當然可能會在S盒實現那碰到點問題。下面的DES演算法包括加密和解密兩個功能,主要有生成16個子金鑰和DES演算法的主程式組成。輸出的資訊有16輪子金鑰以及每輪的中間值以及最後的結果。具體的程式碼中都有註釋,就看程式碼吧。關於D

擴充套件歐幾里德演算法求乘法逆元(C語言

#include <stdio.h>   int ExtendedEuclid( int f,int d ,int *result);   int main()   {   int x,y,z;   z = 0;   printf("輸入

1020 月餅(C語言 + 註釋 + 貪心演算法

月餅是中國人在中秋佳節時吃的一種傳統食品,不同地區有許多不同風味的月餅。現給定所有種類月餅的庫存量、總售價、以及市場的最大需求量,請你計算可以獲得的最大收益是多少。 注意:銷售時允許取出一部分庫存。樣例給出的情形是這樣的:假如我們有 3 種月餅,其庫存量分別為 18、15、

C語言)二叉樹遍歷演算法——包含遞迴前、中、後序和層次,非遞迴前、中、後序和層次遍歷共八種

#include <stdlib.h> #include <stdio.h> #include "BiTree.h" #include "LinkStack.h" #include "LinkQueue.h" //初始化二叉樹(含根節點) void InitBiTree(pBiTr

深入淺出數據結構C語言(9)——多重表(廣義表)

不同 滿足 大學 logs 維數 我會 明顯 http 多維   在深入淺出數據結構系列前面的文章中,我們一直在討論的表其實是“線性表”,其形式如下:   由a1,a2,a3,……a(n-1)個元素組成的序列,其中每一個元素ai(0<i<n)都是一個“原子”,“