window/linux下獲取文件MD5

MD5消息摘要算法(英語: MD5 Message-Digest Algorithm), 主要用於確保信息傳輸過程的一致性校驗。
 
首先介紹兩個工具:
window: WinMD5Free
Linux: md5sum
這兩個工具的做用是驗證本身寫的程序獲取MD5是否正確。
 
先上一段錯誤代碼:
 1 string getFileMd5(const string& file)
 2 {
 3     MD5 md5;
 4     ifstream f(file.c_str(), ios_base::binrary);
 5     char buffer[64 * 1024];
 6     while (!f.eof())
 7     {
 8         f.read(buffer, sizeof(buffer));
 9         size_t length = strlen(buffer);
10         md5.update(buffer, length);
11     }
12     return md5.md5();
13 }

 

邏輯上,看似沒有問題的一段代碼。
實際驗證的狀況:
window下獲取的MD5與第三方獲取的值一致;
linux下獲取的MD5與第三方獲取的值不一致。
也就是說計算MD5時的輸入不一致,致使的結果不一致。
 
問題分析:
上面的代碼最有可能出問題的地方在用strlen獲取buffer的大小。strlen以‘\0’標誌肯定函數讀取終止。從文件中讀取的二進制數據中間是可能存在‘\0’的狀況,打印每次strlen返回的結果,能夠驗證這個狀況。
 
問題的緣由已經找到,那麼如何解決這個問題呢?
若是你熟悉C++ IO操做,io庫已經考慮過這個問題。獲取每次讀取的大小,使用fstream.gcount()返回正確讀取大小。
 
正確的代碼
 1 string getFileMd5(const string& file)
 2 {
 3     MD5 md5;
 4     ifstream f(file.c_str(), ios_base::binrary);
 5     char buffer[64 * 1024];
 6     while (!f.eof())
 7     {
 8         f.read(buffer, sizeof(buffer));
 9         md5.update(buffer, f.gcount());
10     }
11     return md5.md5();
12 }

 

工做中遇到這樣的問題,經歷過屢次嘗試才發現這個問題,在此處記錄下。
相關文章
相關標籤/搜索