--
首先,要在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
執行方法
--
感謝分享
回覆刪除