--
首先,要在C語言計算MD5,有一些公開的library可以幫助我們快速計算一些雜湊運算,當然MD5也是被包含在內的。
這邊介紹使用OpenSSL,基本上這個package在各版本的linux上的package list內都找的到。
筆者本次是使用Ubuntu 15.04版本,所以像我就是使用 sudo apt-get install openssl 快速透過package manager安裝。
基本上使用方法很簡單,步驟就是
- MD2_Init(MD2_CTX *c) :初始化 MD2_CTX 結構.
- MD2_Update(MD2_CTX *c, const unsigned char *data, unsigned long len) :更新hash値,若是資料量大於你設計的buffer,可以多次呼叫此函式來更新MD5的hash値
- MD2_Final(unsigned char *md, MD2_CTX *c):將MD5的計算結果儲存於md並且把MD2_CTX釋放掉。
接下來就是使用文字編輯器寫一個簡單的範例吧!
假如我想要計算『Hello Ni hao ma?』這個字串的MD5,我們透過線上MD5計算機可以得到:
接下來看我的範例程式輸出的MD5碼會是如何吧!程式碼如下
#include <stdio.h>
#include <string.h>
#include <openssl/md5.h>
#define KGRN "\033[0;32;32m"
#define RESET "\033[0m"
void printf_md5(unsigned char *in)
{
int i;
for(i = 0 ; i < MD5_DIGEST_LENGTH ; i++) {
if ( in[i] < 0x10)
printf("0%1x", in[i]);
else
printf("%2x", in[i]);
}
printf("\n"RESET);
}
int main(void)
{
const char *path = "Hello Ni hao ma?";
unsigned char digest[MD5_DIGEST_LENGTH];
MD5_CTX context;
MD5_Init(&context);
MD5_Update(&context, path, strlen(path));
MD5_Final(digest, &context);
printf(KGRN"path '%s' md5:", path);
printf_md5(digest);
return 0;
}
將上述程式碼存成.c檔後,編譯時要記得對library做link唷!例如
gcc md5.c -o md5 -lcrypto
這裡比較需要注意到的是雖然該檔案是放在openssl底下,但是稍微看一下openssl/md5.h裡面,發現要link的是libcrypto.so唷
執行結果:
輸出的md5碼與計算機的相同!
--
2015/08/06補充:
下面分享一段程式,編譯完成之後可以直接將檔案路徑當成參數代入,就會將該檔案讀取併計算各字的md5囉!
程式碼如下:
#include <stdio.h>
#include <string.h>
#include <openssl/md5.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#ifdef DEBUG
#ifndef MYDEBUG
#define MYDEBUG
#define debug(x) x
#define KRED "\033[0;32;31m"
#define KRED_L "\033[1;31m"
#define KGRN "\033[0;32;32m"
#define KGRN_L "\033[1;32m"
#define KBLU "\033[0;32;34m"
#define KBLU_L "\033[1;34m"
#define KGRY "\033[1;30m"
#define KGRY_L "\033[0;37m"
#define KCYN "\033[0;36m"
#define KCYN_L "\033[1;36m"
#define KMAG "\033[0;35m"
#define KMAG_L "\033[1;35m"
#define KBRN "\033[0;33m"
#define KYEL "\033[1;33m"
#define WHITE "\033[1;37m"
#define RESET "\033[0m"
#endif
#else
#define debug(x)
#endif
static void printf_md5(unsigned char *in)
{
int i;
for(i = 0 ; i < MD5_DIGEST_LENGTH ; i++) {
if ( in[i] < 0x10)
printf("0%1x", in[i]);
else
printf("%2x", in[i]);
}
printf("\n"RESET);
}
int main(int argc, char *argv[])
{
int fd, sum, i;
char buf[1024];
unsigned char digest[MD5_DIGEST_LENGTH];
if (argc <= 1) {
debug( printf("Please input the filepath that you want to calculate.\n"); );
return -1;
}
// c
for(i = 1; i < argc; i++) {
fd = open(argv[i], O_RDONLY, S_IRUSR);
if (fd < 0 ) {
debug( printf("Opening file:%s error.\n", argv[i]); );
continue;
} else {
sum = 0;
int len, n;
memset(digest, 0, sizeof(buf));
memset(buf, 0 , sizeof(buf));
len = lseek( fd, 0, SEEK_END);
lseek(fd, 0, SEEK_SET);
MD5_CTX context;
MD5_Init(&context);
while (sum < len) {
n = read( fd, buf, sizeof(buf));
MD5_Update(&context, buf, n);
sum += n;
}
MD5_Final(digest, &context);
debug(printf(KGRN"file:%s md5:", argv[i]););
printf_md5(digest);
close(fd);
}
}
return 0;
}
--
編譯方法
gcc md5checker.c -o md5checker -lcrypto -DDEBUG
執行方法
--
感謝分享
回覆刪除