C語言計算檔案MD5
計算MD5這種很標準的東西,一般直接使用別人寫好的了就行,本文主要針對寫好的介面測試一下如何使用的問題。
下面是MD5的實現
md5.h
#ifndef MD5_H
#define MD5_H
typedef struct
{
unsigned int count[2];
unsigned int state[4];
unsigned char buffer[64];
}MD5_CTX;
#define F(x,y,z) ((x & y) | (~x & z))
#define G(x,y,z) ((x & z) | (y & ~z))
#define H(x,y,z) (x^y^z)
#define I(x,y,z) (y ^ (x | ~z))
#define ROTATE_LEFT(x,n) ((x << n) | (x >> (32-n)))
#define FF(a,b,c,d,x,s,ac) \
{ \
a += F(b,c,d) + x + ac; \
a = ROTATE_LEFT(a,s); \
a += b; \
}
#define GG(a,b,c,d,x,s,ac) \
{ \
a += G(b,c,d) + x + ac; \
a = ROTATE_LEFT(a,s); \
a += b; \
}
#define HH(a,b,c,d,x,s,ac) \
{ \
a += H(b,c,d) + x + ac; \
a = ROTATE_LEFT(a,s); \
a += b; \
}
#define II(a,b,c,d,x,s,ac) \
{ \
a += I(b,c,d) + x + ac; \
a = ROTATE_LEFT(a,s); \
a += b; \
}
void MD5Init(MD5_CTX *context);
void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int inputlen);
void MD5Final(MD5_CTX *context,unsigned char digest[16]);
void MD5Transform(unsigned int state[4],unsigned char block[64]);
void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len);
void MD5Decode(unsigned int *output,unsigned char *input,unsigned int len);
#endif
md5.c
#include <string.h>
#include "md5.h"
unsigned char PADDING[]={0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
void MD5Init(MD5_CTX *context)
{
context->count[0] = 0;
context->count[1] = 0;
context->state[0] = 0x67452301;
context->state[1] = 0xEFCDAB89;
context->state[2] = 0x98BADCFE;
context->state[3] = 0x10325476;
}
void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int inputlen)
{
unsigned int i = 0,index = 0,partlen = 0;
index = (context->count[0] >> 3) & 0x3F;
partlen = 64 - index;
context->count[0] += inputlen << 3;
if(context->count[0] < (inputlen << 3))
context->count[1]++;
context->count[1] += inputlen >> 29;
if(inputlen >= partlen)
{
memcpy(&context->buffer[index],input,partlen);
MD5Transform(context->state,context->buffer);
for(i = partlen;i+64 <= inputlen;i+=64)
MD5Transform(context->state,&input[i]);
index = 0;
}
else
{
i = 0;
}
memcpy(&context->buffer[index],&input[i],inputlen-i);
}
void MD5Final(MD5_CTX *context,unsigned char digest[16])
{
unsigned int index = 0,padlen = 0;
unsigned char bits[8];
index = (context->count[0] >> 3) & 0x3F;
padlen = (index < 56)?(56-index):(120-index);
MD5Encode(bits,context->count,8);
MD5Update(context,PADDING,padlen);
MD5Update(context,bits,8);
MD5Encode(digest,context->state,16);
}
void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len)
{
unsigned int i = 0,j = 0;
while(j < len)
{
output[j] = input[i] & 0xFF;
output[j+1] = (input[i] >> 8) & 0xFF;
output[j+2] = (input[i] >> 16) & 0xFF;
output[j+3] = (input[i] >> 24) & 0xFF;
i++;
j+=4;
}
}
void MD5Decode(unsigned int *output,unsigned char *input,unsigned int len)
{
unsigned int i = 0,j = 0;
while(j < len)
{
output[i] = (input[j]) |
(input[j+1] << 8) |
(input[j+2] << 16) |
(input[j+3] << 24);
i++;
j+=4;
}
}
void MD5Transform(unsigned int state[4],unsigned char block[64])
{
unsigned int a = state[0];
unsigned int b = state[1];
unsigned int c = state[2];
unsigned int d = state[3];
unsigned int x[64];
MD5Decode(x,block,64);
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, 0x2441453);
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, 0x4881d05);
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);
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
}
下面是測試程式, 主要依次呼叫MD5Init, MD5Update,MD5Final三個函式就行了
/************************************************************
Copyright (C), 2017, Leon, All Rights Reserved.
FileName: test_md5.c
Description: MD5函式測試
Author: Leon
Version: 1.0
Date:
Function:
History:
<author> <time> <version> <description>
Leon
************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include "md5.h"
/* md5函式測試 */
int main(int argc, char *argv[])
{
struct stat st;
unsigned char digest[16] = {0};
MD5_CTX context;
int i = 0;
if(argc < 2)
return;
MD5Init(&context);
if(-1 == stat(argv[1], &st))
{
/* 檔案不存在則計算引數字串的MD5 */
MD5Update(&context, argv[1], strlen(argv[1]));
}
else
{
/* 計算檔案MD5 */
FILE *fp = fopen(argv[1], "r");
char *data = NULL;
int ret = 0;
if(!fp)
{
perror("fopen");
exit(-1);
}
data = malloc(st.st_size);
if(!data)
{
perror("malloc");
exit(-1);
}
ret = fread(data, 1, st.st_size, fp);
if(ret != st.st_size)
{
perror("fread");
exit(-1);
}
MD5Update(&context, data, st.st_size);
fclose(fp);
free(data);
}
MD5Final(&context, digest);
/* 列印MD5值 */
printf("md5: ");
for(i = 0; i < 16; i++)
{
printf("%02x", digest[i]);
}
printf("\n");
return 0;
}
執行結果與openssl結果對比是一致的:
測試結果:
root@ubuntu:online_upgrade# ./a.out 123.txt
md5: 86109d400f0ed29e840b47ed72777c84
root@ubuntu:online_upgrade# openssl md5 123.txt
MD5(123.txt)= 86109d400f0ed29e840b47ed72777c84
相關推薦
C語言計算檔案MD5
計算MD5這種很標準的東西,一般直接使用別人寫好的了就行,本文主要針對寫好的介面測試一下如何使用的問題。 下面是MD5的實現 md5.h #ifndef MD5_H #define MD5_H typedef struct
C++計算檔案MD5值
MD5ChecksumDefines.h //Magic initialization constants #define MD5_INIT_STATE_0 0x67452301 #define MD5_INIT_STATE_1 0xefcdab89 #define MD5
C語言計算程序中某一個函數或算法的執行時間
lock nis 程序 while tar 計算 stdio.h locks turn 計算程序中某一個函數或算法的執行時間 #include <stdio.h> #include <time.h> #include <stdlib.h>
C語言計算:t=1-1/(2*2)-1/(3*3)-...-1/(m*m)
#include <stdio.h> #include <stdlib.h> #include <math.h> int main() { int m,i; int n;  
如何用C語言計算表示式的值,棧的經典應用
宣告:這個程式可以計算+,-,*,/,負數,小數 負數用括號括起來例如(-1) 負數的計算過程:(-1) 轉變為 (0-1) 哈哈~ 分成六個點: 1.我的檔案結構 2.順序堆疊的標頭檔案 3.標頭
C語言(四 檔案操作、遞迴)
檔案讀寫 我們用**fopen()**來新建一個檔案或開啟一個已有的檔案. 函式原型為File *fopen(const char *filename , const char *mode) filename是檔名,mode代表訪問方式。 mode
BMP轉成C語言陣列檔案工具(用image2lcd代替bmp2h exe)
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
C語言計算sinx
#include<stdio.h> #include<math.h> int jc(int n); int main() { int m=1,f=1,i=1; double sinx=0.0,x,z; double ans; scanf("%lf",&x); z
用C語言計算矩陣邊緣元素之和
1 題目描述 1.1 題目描述 輸入一個整數矩陣,計算位於矩陣邊緣的元素之和。所謂矩陣邊緣的元 素,就是第一行和最後一行的元素以及第一列和最後一列的元素。 1.2 輸入要求 1.第一行為整數k,表示有k組資料。 2.每組資料由多行組成,表示一個矩陣。 3.第
用C語言計算1~20的階乘之和
昨天(2018/12/7)在做C語言的課後練習題的時候,有一道題要求我們計算1~20的階乘之和。程式碼很快就寫出來了,考慮到結果的值會比較大,而在Windows作業系統下,int 型別和 long 型別居然都是4個位元組(C#中long型別是八個位元組,找同學試了下,Linux下C語言的long型別好像也
C語言之檔案操作
一、開啟檔案 1、函式 fopen(path, type) 2、引數介紹 引數 型別 說明 備註 path 字串 檔案路徑 如”./h
java c c++語言 計算階乘
import java.util.Scanner; public class C201_07_06計算階乘 { public static void main(String[] args) { Scanner scan = new Scanner(Sy
C語言 對檔案的輸入輸出
1.檔案標誌: D:\CC\temp\file1.dat(dat代表是資料檔案)分為三段,檔案路徑,檔名,檔案型別 2.檔案緩衝區: ANSI C標準採用緩衝檔案系統處理資料檔案 3.檔案型別指標: 緩衝檔案系統中關鍵的概念是檔案型別指標,每一個被使用的檔案都是
C語言中檔案流操作的基本函式總結
#include <stdio.h> int main() { FILE* fp = fopen("data.txt","r"); if(fp == NULL) { printf("open error\n"); return -1;
C語言計算個人所得稅問題程式碼及解析
問題描述 編寫一個計算個人所得稅的程式,要求輸入收入金額後,能夠輸出應繳的個人所得稅。 個人所得稅徵收辦法如下: ◎ 起徵點為3500元; ◎ 不超過1500元的部分,徵收3%; ◎ 超過1500〜4500元的部分,徵收10%; ◎ 超過4500〜9000元的部分,徵收20%; ◎
用C語言計算水分子的個數
題目: 一個水分子的質量約為,1夸脫水大約有950g,編寫一個程式,要求輸入水的夸脫數,然後顯示這麼多水中含有多少水分子。 問題分析: 從題目中可以得到1夸脫水中水分子的含量 = 1夸脫水 * 950 / 3.0e-23, 程式碼: #include &l
【C++】從extern關鍵字開始談C語言多檔案程式設計
extern 關鍵字 我們知道,C語言程式碼是由上到下依次執行的,不管是變數還是函式,原則上都要先定義再使用,否則就會報錯。但在實際開發中,經常會在函式或變數定義之前就使用它們,這個時候就需要提前宣告。 所謂宣告(Declaration),就是告訴編譯器我要使用這個變數或函
C語言常用檔案讀寫函式記錄
由於在vs下開發,經常使用MFC的類庫,檔案讀寫也是CFile的類級派生類,現在此記錄C語言檔案操作常用api,以備不時之需。 (1)fopen,fclose – 檔案開啟關閉函式; FILE* pFile = fopen("test.txt","w"); 第一個引數是
C語言計算多邊形
2018年11月07日 20:09:34 YeLlei 閱讀數:4 個人分類: 個人學習
C語言計算一元二次方程的根(完全版)
題目(Description): 求一元二次方程ax2+bx+c=0的根。a、b、c為任意實數。 輸入(Input): 任意三個係數a、b、c。 輸出(Output): x1 x2實根(保留2位小數),且要求x1>=x2。 說明: (1)如果a為0且b為0,則輸出 “Not an eq