STM32計算文件MD5值校驗數據

首先介紹一下什麼是MD5:
一、MD5計算將整個文件或者字符串,通過其不可逆的字符串變換計算,產生文件或字符串的MD5散列值。任意兩個文件、字符串不會有相同的散列值(即“很大可能”是不一樣的,理論上要創造出兩個散列值相同的字符串是很困難的)。
二、因此MD5常用於校驗字符串或者文件,以防止文件、字符串被“篡改”。因爲如果文件、字符串的MD5散列值不一樣,說明文件內容也是不一樣的,即經過修改的,如果發現下載的文件和給的MD5值不一樣,需要慎重使用。
三、MD5文件校驗用途非常多,例如:遊戲補丁包的校驗,病毒文件確認,APP提審校驗等;如果要確認某一個文件的完整性和正確性,都會使用MD5進行校驗。
怎麼用STM32計算文件MD5值
就是下面一段代碼,說起來就有點多了直接給代碼吧。全是數學計算。底部有完整工程鏈接

#include "md5.h"
#include "ff.h"  
#include "exfuns.h" 

unsigned int A=0x67452301,B=0xefcdab89,C=0x98badcfe,D=0x10325476,a,b,c,d,flen[2],x[16]; 
u16 i = 0;
u16 j = 0;
u16 k = 0;

u8 Temp_Ex_Flash[1025];//定義暫時存儲1K外部flash內bin文件

void md5(void){                 //MD5主要計算

  a=A,b=B,c=C,d=D;

  FF (a, b, c, d, x[ 0],  7, 0xd76aa478); 
  FF (d, a, b, c, x[ 1], 12, 0xe8c7b756); 
  FF (c, d, a, b, x[ 2], 17, 0x242070db); 
  FF (b, c, d, a, x[ 3], 22, 0xc1bdceee); 
  FF (a, b, c, d, x[ 4],  7, 0xf57c0faf); 
  FF (d, a, b, c, x[ 5], 12, 0x4787c62a); 
  FF (c, d, a, b, x[ 6], 17, 0xa8304613); 
  FF (b, c, d, a, x[ 7], 22, 0xfd469501); 
  FF (a, b, c, d, x[ 8],  7, 0x698098d8); 
  FF (d, a, b, c, x[ 9], 12, 0x8b44f7af); 
  FF (c, d, a, b, x[10], 17, 0xffff5bb1); 
  FF (b, c, d, a, x[11], 22, 0x895cd7be); 
  FF (a, b, c, d, x[12],  7, 0x6b901122); 
  FF (d, a, b, c, x[13], 12, 0xfd987193); 
  FF (c, d, a, b, x[14], 17, 0xa679438e); 
  FF (b, c, d, a, x[15], 22, 0x49b40821); 


  GG (a, b, c, d, x[ 1],  5, 0xf61e2562); 
  GG (d, a, b, c, x[ 6],  9, 0xc040b340); 
  GG (c, d, a, b, x[11], 14, 0x265e5a51); 
  GG (b, c, d, a, x[ 0], 20, 0xe9b6c7aa); 
  GG (a, b, c, d, x[ 5],  5, 0xd62f105d); 
  GG (d, a, b, c, x[10],  9, 0x02441453); 
  GG (c, d, a, b, x[15], 14, 0xd8a1e681); 
  GG (b, c, d, a, x[ 4], 20, 0xe7d3fbc8); 
  GG (a, b, c, d, x[ 9],  5, 0x21e1cde6); 
  GG (d, a, b, c, x[14],  9, 0xc33707d6); 
  GG (c, d, a, b, x[ 3], 14, 0xf4d50d87); 
  GG (b, c, d, a, x[ 8], 20, 0x455a14ed); 
  GG (a, b, c, d, x[13],  5, 0xa9e3e905); 
  GG (d, a, b, c, x[ 2],  9, 0xfcefa3f8); 
  GG (c, d, a, b, x[ 7], 14, 0x676f02d9); 
  GG (b, c, d, a, x[12], 20, 0x8d2a4c8a); 


  HH (a, b, c, d, x[ 5],  4, 0xfffa3942); 
  HH (d, a, b, c, x[ 8], 11, 0x8771f681); 
  HH (c, d, a, b, x[11], 16, 0x6d9d6122); 
  HH (b, c, d, a, x[14], 23, 0xfde5380c); 
  HH (a, b, c, d, x[ 1],  4, 0xa4beea44); 
  HH (d, a, b, c, x[ 4], 11, 0x4bdecfa9); 
  HH (c, d, a, b, x[ 7], 16, 0xf6bb4b60); 
  HH (b, c, d, a, x[10], 23, 0xbebfbc70); 
  HH (a, b, c, d, x[13],  4, 0x289b7ec6); 
  HH (d, a, b, c, x[ 0], 11, 0xeaa127fa); 
  HH (c, d, a, b, x[ 3], 16, 0xd4ef3085); 
  HH (b, c, d, a, x[ 6], 23, 0x04881d05); 
  HH (a, b, c, d, x[ 9],  4, 0xd9d4d039); 
  HH (d, a, b, c, x[12], 11, 0xe6db99e5); 
  HH (c, d, a, b, x[15], 16, 0x1fa27cf8); 
  HH (b, c, d, a, x[ 2], 23, 0xc4ac5665); 


  II (a, b, c, d, x[ 0],  6, 0xf4292244); 
  II (d, a, b, c, x[ 7], 10, 0x432aff97); 
  II (c, d, a, b, x[14], 15, 0xab9423a7); 
  II (b, c, d, a, x[ 5], 21, 0xfc93a039); 
  II (a, b, c, d, x[12],  6, 0x655b59c3); 
  II (d, a, b, c, x[ 3], 10, 0x8f0ccc92); 
  II (c, d, a, b, x[10], 15, 0xffeff47d); 
  II (b, c, d, a, x[ 1], 21, 0x85845dd1); 
  II (a, b, c, d, x[ 8],  6, 0x6fa87e4f); 
  II (d, a, b, c, x[15], 10, 0xfe2ce6e0); 
  II (c, d, a, b, x[ 6], 15, 0xa3014314); 
  II (b, c, d, a, x[13], 21, 0x4e0811a1); 
  II (a, b, c, d, x[ 4],  6, 0xf7537e82); 
  II (d, a, b, c, x[11], 10, 0xbd3af235); 
  II (c, d, a, b, x[ 2], 15, 0x2ad7d2bb); 
  II (b, c, d, a, x[ 9], 21, 0xeb86d391); 

  A += a;
  B += b;
  C += c;
  D += d;

}

unsigned int sample_index = 0; //從TEST_data採集64位個字節
unsigned int data_index = 0;   //bin文件字符索引,固件bin文件大小不要超過65K
unsigned int read_times = 0;
unsigned int BIN_location = 0;

void data_reset()
{
	sample_index = 0;
	data_index = 0;
	read_times = 0;
	BIN_location = 0;
	A=0x67452301;
	B=0xefcdab89;
	C=0x98badcfe;
	D=0x10325476;
	a=0;
	b=0;
	c=0;
	d=0;
	memset(flen,0x00,sizeof(flen));
	memset(x,0x00,sizeof(x));
}

void read_group_tempbuf(unsigned long fileSize)
{
	memset(x,0,64);	
	sample_index = 0;
	for(j = 0;j < 16;j++)//fread(&x,4,16,fp) 以4字節爲一組,共16組往x寫入數據
	{
		for(k = 0;k < 4;k++)
		{
			if((read_times >= fileSize/1024)&&(data_index >= fileSize%1024)) break;//當對最後一部分小於1K的bin文件處理
			
			((char*)x)[sample_index] = Temp_Ex_Flash[data_index];
			data_index++;
			sample_index++;
		}
	}
}



void get_bin_md5(unsigned long fileSize,char *result)
{
	unsigned short i = 0;
	UINT br;
	FIL file;
	
	data_reset();
	
	f_open(&file,"/car.bin",FA_READ);
	for(read_times = 0;read_times < fileSize/1024;read_times++)//對整K進行md5計算
	{
		f_read (&file, &Temp_Ex_Flash,1024, &br);   
		BIN_location += 1024;
		
		for(i = 0;i < 16;i++)//剛好對讀出的1Kbin文件進行md5計算 
		{
			read_group_tempbuf(fileSize);
			md5();	
		}
		data_index = 0;//最大隻到1023
	}
	memset(Temp_Ex_Flash,0,1025);
	f_read (&file, &Temp_Ex_Flash,fileSize%1024, &br); 
	
	
	read_group_tempbuf(fileSize);
	for(i = 0;i < (fileSize%1024)/64;i++)
	{
		md5();
		read_group_tempbuf(fileSize);
	}
	((char*)x)[fileSize%64]=128;//文件結束補1,0操作 10000000
	
	flen[1]=fileSize/0x20000000;   //轉換二進制文件大小(byte->bit)
	flen[0]=(fileSize%0x20000000)*8;
	
	if(fileSize%64>55) md5(),memset(x,0,64);
	memcpy(x+14,flen,8);
	md5();
	sprintf(result,"%08x%08x%08x%08x",PP(A),PP(B),PP(C),PP(D));
	
}

完整工程鏈接

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章