md5校验

md5校验

xcrypto.h

#ifndef XCRYTO__H_H
#define XCRYTO__H_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>


#define F1(x, y, z)		(z ^ (x & (y ^ z)))
#define F2(x, y, z)		F1(z, x, y)
#define F3(x, y, z)		(x ^ y ^ z)
#define F4(x, y, z)		(y ^ (x | ~z))
#define MD5STEP(f, w, x, y, z, data, s)		( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x)


class xcrypto
{
public:
	typedef struct md5_context
	{
		unsigned int 	buf[4];
		unsigned int 	bits[2];
		unsigned char 	in[64];
	} MD5_CTX;
	
public:
	xcrypto();
	~xcrypto();
	
public:
	static std::string get_md5(std::string input);
	static std::string get_file_md5(std::string file_path,int* ret_file_len);
	
protected:
	static void byte_reverse(unsigned char* buf,unsigned longs);

	
	static void md5_init(struct md5_context* ctx);
	static void md5_update(struct md5_context* ctx,unsigned char* buf,unsigned len);
	static void md5_final(unsigned char digest[16],struct md5_context* ctx);
	//The core of the MD5 algorithm
	static void md5_transform(unsigned int buf[4], unsigned int in[16]);
};




#endif

xcrypto.cpp

#include "xcrypto.h"

//十六进制转字符串
static int hex_to_str(unsigned char* b_data,char* s_data,int data_len)
{
	const char arrchar[256][4] = {
		"00","01","02","03","04","05","06","07","08","09","0A","0B","0C","0D","0E","0F",
		"10","11","12","13","14","15","16","17","18","19","1A","1B","1C","1D","1E","1F",
		"20","21","22","23","24","25","26","27","28","29","2A","2B","2C","2D","2E","2F",
		"30","31","32","33","34","35","36","37","38","39","3A","3B","3C","3D","3E","3F",
		"40","41","42","43","44","45","46","47","48","49","4A","4B","4C","4D","4E","4F",
		"50","51","52","53","54","55","56","57","58","59","5A","5B","5C","5D","5E","5F",
		"60","61","62","63","64","65","66","67","68","69","6A","6B","6C","6D","6E","6F",
		"70","71","72","73","74","75","76","77","78","79","7A","7B","7C","7D","7E","7F",
		"80","81","82","83","84","85","86","87","88","89","8A","8B","8C","8D","8E","8F",
		"90","91","92","93","94","95","96","97","98","99","9A","9B","9C","9D","9E","9F",
		"A0","A1","A2","A3","A4","A5","A6","A7","A8","A9","AA","AB","AC","AD","AE","AF",
		"B0","B1","B2","B3","B4","B5","B6","B7","B8","B9","BA","BB","BC","BD","BE","BF",
		"C0","C1","C2","C3","C4","C5","C6","C7","C8","C9","CA","CB","CC","CD","CE","CF",
		"D0","D1","D2","D3","D4","D5","D6","D7","D8","D9","DA","DB","DC","DD","DE","DF",
		"E0","E1","E2","E3","E4","E5","E6","E7","E8","E9","EA","EB","EC","ED","DE","EF",
		"F0","F1","F2","F3","F4","F5","F6","F7","F8","F9","FA","FB","FC","FD","FE","FF"
	};	
	
	for(int i = 0; i <data_len; i++)
	{
		memcpy(s_data+(i<<1),arrchar[b_data[i]],2);
	}
	return (data_len << 1);
}

std::string xcrypto::get_md5(std::string input)
{
	struct md5_context md5c;
	unsigned char md5nature[16] = {0};
	md5_init(&md5c);
	md5_update(&md5c,(unsigned char*)input.data(),(unsigned int)input.length());
	md5_final(md5nature,&md5c);
	char cal_md5[36] = {0};
	hex_to_str(md5nature,cal_md5,16);
	cal_md5[32] = '\0';
	for(unsigned int i = 0; i < strlen(cal_md5); i++) cal_md5[i] = tolower(cal_md5[i]);
	return std::string(cal_md5);
}


std::string xcrypto::get_file_md5(std::string file_path,int* ret_file_len)
{
	FILE *fd_file = fopen(file_path.c_str(),"rb");
	if(!fd_file)
	{
		if(ret_file_len)
		{
			*ret_file_len = 0;
		}
		return "";
	}
	
	struct md5_context md5c;
	unsigned char md5nature[16] = {0};
	md5_init(&md5c);
	
	//获取文件长度
	if(ret_file_len)
	{
		//定位到文件末尾
		fseek(fd_file,0L,SEEK_END);
		//得到文件大小
		*ret_file_len = ftell(fd_file);
		//定位到文件开头
		fseek(fd_file,0L,SEEK_SET);
	}
	
	int read_len = 0;
	char read_buff[1024] = {0};
	do
	{
		read_len = fread(read_buff,1,1024,fd_file);
		if(read_len > 0) 
		{
			md5_update(&md5c,(unsigned char*)read_buff,(unsigned int)read_len);
		}
	} while(read_len >= 1024);
	fclose(fd_file);
	fd_file = NULL;
	md5_final(md5nature,&md5c);
	char cal_md5[36] = {0};
	hex_to_str(md5nature,cal_md5,16);
	cal_md5[32] = '\0';
	for(unsigned int i = 0; i < strlen(cal_md5); i++) cal_md5[i] = tolower(cal_md5[i]);
	return std::string(cal_md5);		
}

void xcrypto::byte_reverse(unsigned char* buf,unsigned longs)
{
	unsigned int t;
	do
	{
		t = (unsigned int) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
		((unsigned) buf[1] << 8 | buf[0]);
		*(unsigned int *) buf = t;
		buf += 4;
	} while(--longs);
}

void xcrypto::md5_init(struct md5_context* ctx)
{
	ctx->buf[0] = 0x67452301;
	ctx->buf[1] = 0xefcdab89;
	ctx->buf[2] = 0x98badcfe;
	ctx->buf[3] = 0x10325476;
	ctx->bits[0] = 0;
	ctx->bits[1] = 0;
}


//Update context to reflect the concatentaion of another buffer full of bytes
void xcrypto::md5_update(struct md5_context* ctx,unsigned char* buf,unsigned len)
{
	unsigned int t = ctx->bits[0];
	if((ctx->bits[0] = t + ((unsigned int) len << 3)) < t) 
	{
		ctx->bits[1]++;	//Carry from to high
	}
	
	ctx->bits[1] += len >>29;
	t = (t >> 3) & 0x03f;   //Bytes already int sshInfo->data
	if(t)
	{
		unsigned char *p = (unsigned char*) ctx->in + t;
		t = 64 - t;
		if(len < t) 
		{
			memcpy(p, buf, len);
			return;
		}
		memcpy(p,buf,t);
		byte_reverse(ctx->in,16);
		md5_transform(ctx->buf,(unsigned int*)ctx->in);
		buf += t;
		len -= t;
	}
	//Process data in 64 bytes chunks
	while( len >= 64) 
	{
		memcpy(ctx->in,buf,64);
		byte_reverse(ctx->in,16);
		md5_transform(ctx->buf,(unsigned int*)ctx->in);
		buf += 64;
		len -= 64;
	}
	//Handle any remaining bytes of data
	memcpy(ctx->in,buf,len);
	
}

//Final wrapup - pad to 64-byte boundary with the bit pattern 1 0*(64-bit count of bits processed, MSB-first)
void xcrypto::md5_final(unsigned char digest[16],struct md5_context* ctx)
{
	unsigned count = (ctx->bits[0] >> 3) & 0x03f;  //Compute number of bytes mod 64
	unsigned char *p = ctx->in + count;
	*p++ = 0x80;  //Set the first char of padding to 0x80. This is safe since there is always at least one byte free
	count = 64-1-count; //Bytes of padding needed to make  64 bytes
	if(count < 8)  //Pad out to 56 mod 64
	{
		memset(p,0,count);
		byte_reverse(ctx->in,16);
		md5_transform(ctx->buf,(unsigned int*)ctx->in);  //Two lots of padding: Pad the first block to 64 bytes
		memset(ctx->in,0,56);	//Now fill the next block with 56 bytes
	}
	else
	{
		memset(p,0,count -8);
	}
	
	byte_reverse(ctx->in,14);
	((unsigned int*) ctx->in)[14] = ctx->bits[0];	//Append length in bits and transform
	((unsigned int*) ctx->in)[15] = ctx->bits[1];
	md5_transform(ctx->buf, (unsigned int*) ctx->in);
	byte_reverse((unsigned char*) ctx->buf,4);
	memcpy(digest,ctx->buf,16);
	memset(ctx,0,(size_t)sizeof(md5_context));	//In case It's sensitive
}


void xcrypto::md5_transform(unsigned int buf[4], unsigned int in[16])
{
	register unsigned int a,b,c,d;
	a = buf[0];
	b = buf[1];
	c = buf[2];
	d = buf[3];
	MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
	MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
	MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
	MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
	MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
	MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
	MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
	MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
	MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
	MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
	MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
	MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
	MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
	MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
	MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
	MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
	
	MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
	MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
	MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
	MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
	MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
	MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
	MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
	MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
	MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
	MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
	MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
	MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
	MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
	MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
	MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
	MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
	
	MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
	MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
	MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
	MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
	MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
	MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
	MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
	MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
	MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
	MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
	MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
	MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
	MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
	MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
	MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
	MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
	
	MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
	MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
	MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
	MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);	
	MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
	MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
	MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
	MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);	
	MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
	MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
	MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
	MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
	MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
	MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
	MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
	MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
	
	buf[0] += a;
	buf[1] += b;
	buf[2] += c;
	buf[3] += d;
}

test_xcrypto.cpp

#include "xcrypto.h"
#include <stdio.h>

int main(int argc, char** argv)
{
	if(argc == 2)
	{
		int file_size = 0;
		std::string file_path(argv[1]);
		std::string md5_str = xcrypto::get_file_md5(file_path,&file_size);
		printf("file=%s md5=%s\n",file_path.c_str(),md5_str.c_str());
	}
	else
	{
		printf("argc number is error\n");
	}
	return 0;
}

运行

[banting@localhost test]$ g++ -g -std=c++11 xcrypto.cpp test_xcrypto.cpp -o test_xcrypto
[banting@localhost test]$ ./test_xcrypto FTTH_MCU-0.0.0.1.bin
file=FTTH_MCU-0.0.0.1.bin md5=a6aac6545a960f757d6a0c0d705abd32
[banting@localhost test]$ md5sum FTTH_MCU-0.0.0.1.bin
a6aac6545a960f757d6a0c0d705abd32  FTTH_MCU-0.0.0.1.bin
[banting@localhost test]$ 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值