iOS SDK自帶 md5校驗(yàn)文件完整性(內(nèi)含MAC下命令行)

MAC下MD5校驗(yàn)文件完整性

先上代碼:

在.m文件中導(dǎo)入頭文件:#import <CommonCrypto/CommonDigest.h>

直接在.m文件中實(shí)現(xiàn)下列兩個(gè)方法:

校驗(yàn)字符串:

+(NSString*)md5:(NSString*) str

{

const char *cStr = [str UTF8String];

unsigned char result[CC_MD5_DIGEST_LENGTH];

CC_MD5( cStr, strlen(cStr), result );

NSMutableString *hash = [NSMutableString string];

for(int i=0;i<CC_MD5_DIGEST_LENGTH;i++)

{

[hash appendFormat:@"%02X",result[i]];

}

return [hash lowercaseString];

}

校驗(yàn)文件:

#define CHUNK_SIZE 1024

+(NSString *)file_md5:(NSString*) path

{

NSFileHandle* handle = [NSFileHandle fileHandleForReadingAtPath:path];

if(handle == nil)

return nil;

CC_MD5_CTX md5_ctx;

CC_MD5_Init(&md5_ctx);

NSData* filedata;

do {

filedata = [handle readDataOfLength:CHUNK_SIZE];

CC_MD5_Update(&md5_ctx, [filedata bytes], [filedata length]);

}

while([filedata length]);

unsigned char result[CC_MD5_DIGEST_LENGTH];

CC_MD5_Final(result, &md5_ctx);

[handle closeFile];

NSMutableString *hash = [NSMutableString string];

for(int i=0;i<CC_MD5_DIGEST_LENGTH;i++)

{

[hash appendFormat:@"%02x",result[i]];

}

return [hash lowercaseString];

}

下面介紹原理:

思考一個(gè)問題

用戶需要上傳和下載一個(gè)重要的資料文件啥么,應(yīng)該如何判斷用戶本次是否上傳成功和下載成功了呢矾飞?是否僅僅通過代碼來判斷當(dāng)前次的請求發(fā)送結(jié)束或者收到數(shù)據(jù)結(jié)束就可以了嗎剑梳?

答案是否定的骤素。文件的上傳與下載極易出錯(cuò)饱亮,尤其涉及使用斷點(diǎn)續(xù)傳方式上傳或下載的文件。

因此非常有必要在客戶端與服務(wù)器之間通過一種驗(yàn)證機(jī)制來確保文件上傳下載后的完整性斗幼。那怎么樣才能保證資源的完整性盯串,處理辦法就是用MD5驗(yàn)證文件的完整性娇唯!

當(dāng)客戶端上傳一個(gè)文件的時(shí)候,在請求body里面添加該文件的MD5值來告訴服務(wù)器寂玲,服務(wù)器接受文件完畢以后通過校驗(yàn)收到的文件的MD5值與請求body里面的MD5值來最終確定本次上傳是否成功塔插。

當(dāng)客戶端下載一個(gè)文件的時(shí)候,在響應(yīng)頭里面收到了服務(wù)器附帶的該文件的MD5值拓哟,文件下載結(jié)束以后想许,通過獲取下載后文件的MD5值與本次請求服務(wù)器返回的響應(yīng)頭中的MD5值做一個(gè)比較,來最終判斷本次下載是否成功断序。

你可能覺得不就是下載一個(gè)文件嗎流纹?需要這么麻煩嗎?

那我們還是一起看看一些其他人都是怎么做的吧违诗。

附上mysql的文件下載安裝頁面部分截圖

這里強(qiáng)調(diào)一下漱凝,使用MD5來校驗(yàn)完整性還是非常有必要的,例如該文件比較大较雕,一個(gè)請求并不能快速請求到整個(gè)文件碉哑。文件的下載過程是持續(xù)的挚币,大部分瀏覽在下載支持?jǐn)帱c(diǎn)續(xù)傳請求方式的文件的時(shí)候亮蒋,默認(rèn)都是啟用了斷點(diǎn)續(xù)傳的方式來下載。

既然使用斷點(diǎn)續(xù)傳妆毕,那么不用想慎玖,每一次請求都需要就設(shè)置Content-Range這個(gè)頭部,設(shè)置range字節(jié)開始傳輸?shù)奈恢茫J(rèn)是按字節(jié)算的)笛粘,回應(yīng)使用206狀態(tài)值趁怔,表示現(xiàn)在開始部分傳輸,回復(fù)Content-Length頭部薪前,表示傳輸?shù)牟糠秩笈米止?jié)記,然后就與普通傳輸沒有區(qū)別了示括。這里Content-Range這個(gè)頭部每次都不一樣铺浇,它是通過瀏覽器在每次收一部分?jǐn)?shù)據(jù)后不斷在更新的,文件下載后又涉及一個(gè)I/O操作垛膝,更新緩存進(jìn)度信息操作鳍侣,這樣即使用戶任何時(shí)候關(guān)閉了瀏覽器,下載打開瀏覽器吼拥,文件還是從最近一次操作的最后進(jìn)度開始的倚聚。既然這么復(fù)雜,那么這個(gè)過程其實(shí)就極易出錯(cuò)凿可。因此惑折,很難確保下載后太惠,通過拼接二進(jìn)制數(shù)據(jù)產(chǎn)生的文件就一定是完整的。因此驗(yàn)證文件完整性必不可少婴梧。

細(xì)心的朋友們以后在下載任何文件的時(shí)候蔓倍,都可以關(guān)注一下是否有MD5有關(guān)的信息。其實(shí)游戲里面的補(bǔ)丁敞咧,下載后是一定需要校驗(yàn)的棘捣。設(shè)想一下,用戶下載了一個(gè)不完整的補(bǔ)丁文件休建,去跟一個(gè)舊版本的游戲做補(bǔ)丁合成乍恐,生產(chǎn)的最終的新版本文件,一定是錯(cuò)誤的测砂。那么游戲使用者基本上再也打不開這個(gè)游戲軟件了茵烈,只能刪除重新一個(gè)完整的新版本安裝包。(用戶內(nèi)心一定是千萬只草泥馬奔騰而過????~)砌些。其實(shí)在完整的補(bǔ)丁文件與舊版本做合并新版本的過程中也是容易出錯(cuò)的呜投,任何的差池都會導(dǎo)致最終合并后的最版本有可能是錯(cuò)誤的,那么合并后再次進(jìn)行一次校驗(yàn)(需要服務(wù)器提供新版本完整包的MD5)也是非常有必要的存璃。如果整個(gè)過程都沒有問題仑荐,那么恭喜本次下載補(bǔ)丁,合并補(bǔ)丁的過程是非常OK的纵东,用戶僅僅下載了很小的補(bǔ)丁就實(shí)現(xiàn)了整個(gè)應(yīng)用程序的完整安裝粘招。

那么你肯定想問,文件的MD5值究竟是什么偎球,它能表征寫什么信息呢洒扎?還是先度娘一下吧

MD5校驗(yàn)和通過對接收的傳輸數(shù)據(jù)執(zhí)行散列運(yùn)算來檢查數(shù)據(jù)的正確性。

一個(gè)散列函數(shù)衰絮,比如 MD5袍冷,是一個(gè)將任意長度的數(shù)據(jù)字符串轉(zhuǎn)化成短的固定長度的值的單向操作。任意兩個(gè)字符串不應(yīng)有相同的散列值(即猫牡,有“很大可能”是不一樣的胡诗,并且要人為地創(chuàng)造出來兩個(gè)散列值相同的字符串應(yīng)該是困難的)。

一個(gè) MD5校驗(yàn)和通過對接收的傳輸數(shù)據(jù)執(zhí)行散列運(yùn)算來檢查數(shù)據(jù)的正確性镊掖。計(jì)算出的散列值拿來和隨數(shù)據(jù)傳輸?shù)纳⒘兄当容^乃戈。如果兩個(gè)值相同,說明傳輸?shù)臄?shù)據(jù)完整無誤亩进、沒有被竄改過(前提是散列值沒有被竄改)症虑,從而可以放心使用。

MD5校驗(yàn)可以應(yīng)用在多個(gè)領(lǐng)域归薛,比如說機(jī)密資料的檢驗(yàn)谍憔,下載文件的檢驗(yàn)匪蝙,明文密碼的加密等。MD5校驗(yàn)原理舉例:如客戶往我們數(shù)據(jù)中心同步一個(gè)文件习贫,該文件使用MD5校驗(yàn)逛球,那么客戶在發(fā)送文件的同時(shí)會再發(fā)一個(gè)存有校驗(yàn)碼的文件,我們拿到該文件后做MD5運(yùn)算苫昌,得到的計(jì)算結(jié)果與客戶發(fā)送的校驗(yàn)碼相比較颤绕,如果一致則認(rèn)為客戶發(fā)送的文件沒有出錯(cuò),否則認(rèn)為文件出錯(cuò)需要重新發(fā)送祟身。

簡單總結(jié)一下:其實(shí)就是任何一個(gè)字符串或文件奥务,無論是可執(zhí)行程序、圖像文件袜硫、臨時(shí)文件或者其他任何類型的文件氯葬,也不管它體積多大,都有且只有一個(gè)獨(dú)一無二的MD5信息碼婉陷,并且如果這個(gè)文件被修改過帚称,它的MD5碼也將隨之改變。

Message-Digest泛指字節(jié)串(Message)的Hash變換秽澳,就是把一個(gè)任意長度的字節(jié)串變換成一定長的大整數(shù)闯睹。注意這里說的是“字節(jié)串”而不是“字符串”,因?yàn)檫@種變換只與字節(jié)的值有關(guān)肝集,與字符集或編碼方式無關(guān)瞻坝。

知道了原理蛛壳,那就話不多說杏瞻,趕快操練起來吧!

md5sum命令是Linux平臺下面用來檢測文件完整性的給力工具,維基百科是這樣來解釋 md5sum的:

md5sum是一種計(jì)算機(jī)程序衙荐,用于計(jì)算與校驗(yàn)128位MD5哈希值捞挥,此處MD5散列值(或校驗(yàn)和)作一個(gè)文件的數(shù)字指紋使用。理論上看忧吟,正如其他散列算法一樣砌函,一個(gè)MD5哈希值可對應(yīng)無限個(gè)文件,但從現(xiàn)實(shí)的角度看溜族,兩個(gè)不同的文件幾乎不可能有相同的MD5哈希值讹俊,除非其創(chuàng)建便是刻意為之。一般來說煌抒,任何對一個(gè)文件的非惡意變更都會導(dǎo)致其MD5哈希值改變仍劈,因此md5sum一般用于檢查文件完整性,尤其常用于檢測在文件傳輸寡壮、磁盤錯(cuò)誤或其他無惡意涉入的情況下文件的正確性贩疙。

示例:

以linux下shell為環(huán)境示例讹弯,以下文件皆于同一目錄下。

計(jì)算校驗(yàn)值并輸出至hash.md5

$ md5sum filetohashA.txt filetohashB.txt filetohashC.txt > hash.md5

所得文件这溅,文件內(nèi)包括了哈希值和對應(yīng)的文件名组民。

$ cat hash.md5

595f44fec1e92a71d3e9e77456ba80d1? filetohashA.txt

71f920fa275127a7b60fa4d4d41432a3? filetohashB.txt

43c191bf6d6c3f263a8cd0efd4a058ab? filetohashC.txt

Mac OS可以用md5命令

先看下使用說明

usage: md5 [-pqrtx] [-s string] [files ...]

操練起來:

~ md5 -s woaini

MD5 ("woaini") = 023299564b0db47d5f3e476a254d0c21

MD5命令不能將路徑設(shè)置為文件夾路徑,只能是某一個(gè)具體文件悲靴。

~ MD5 /Users/nuomi/Desktop/OmniPlan-3.3.3.dmg

MD5 (/Users/nuomi/Desktop/OmniPlan-3.3.3.dmg) = c0a01ff9c0a4f0691a46616ab71e3380

還是非常簡單的臭胜。

那么在實(shí)際的移動應(yīng)用開發(fā)中,文件上傳癞尚、下載都是必不可少的功能~

在此附上一個(gè)我總結(jié)的一個(gè)iOS上使用OC寫的獲取文件MD5值得一個(gè)小工具庇楞。

建議大家在重要文件的上傳、下載時(shí)否纬,一定要與后臺同學(xué)協(xié)商吕晌,添加這個(gè)校驗(yàn)過程來保證文件傳輸過程的完整性。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末临燃,一起剝皮案震驚了整個(gè)濱河市睛驳,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌膜廊,老刑警劉巖乏沸,帶你破解...
    沈念sama閱讀 219,589評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異爪瓜,居然都是意外死亡蹬跃,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評論 3 396
  • 文/潘曉璐 我一進(jìn)店門铆铆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蝶缀,“玉大人,你說我怎么就攤上這事薄货∥潭迹” “怎么了?”我有些...
    開封第一講書人閱讀 165,933評論 0 356
  • 文/不壞的土叔 我叫張陵谅猾,是天一觀的道長柄慰。 經(jīng)常有香客問我,道長税娜,這世上最難降的妖魔是什么坐搔? 我笑而不...
    開封第一講書人閱讀 58,976評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮敬矩,結(jié)果婚禮上概行,老公的妹妹穿的比我還像新娘。我一直安慰自己谤绳,他們只是感情好占锯,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,999評論 6 393
  • 文/花漫 我一把揭開白布袒哥。 她就那樣靜靜地躺著,像睡著了一般消略。 火紅的嫁衣襯著肌膚如雪堡称。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,775評論 1 307
  • 那天艺演,我揣著相機(jī)與錄音却紧,去河邊找鬼。 笑死胎撤,一個(gè)胖子當(dāng)著我的面吹牛晓殊,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播伤提,決...
    沈念sama閱讀 40,474評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼巫俺,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了肿男?” 一聲冷哼從身側(cè)響起介汹,我...
    開封第一講書人閱讀 39,359評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎舶沛,沒想到半個(gè)月后嘹承,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,854評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡如庭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,007評論 3 338
  • 正文 我和宋清朗相戀三年叹卷,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片坪它。...
    茶點(diǎn)故事閱讀 40,146評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡骤竹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出哟楷,到底是詐尸還是另有隱情瘤载,我是刑警寧澤,帶...
    沈念sama閱讀 35,826評論 5 346
  • 正文 年R本政府宣布卖擅,位于F島的核電站,受9級特大地震影響墨技,放射性物質(zhì)發(fā)生泄漏惩阶。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,484評論 3 331
  • 文/蒙蒙 一扣汪、第九天 我趴在偏房一處隱蔽的房頂上張望断楷。 院中可真熱鬧,春花似錦崭别、人聲如沸冬筒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,029評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽舞痰。三九已至土榴,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間响牛,已是汗流浹背玷禽。 一陣腳步聲響...
    開封第一講書人閱讀 33,153評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留呀打,地道東北人矢赁。 一個(gè)月前我還...
    沈念sama閱讀 48,420評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像贬丛,于是被迫代替她去往敵國和親撩银。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,107評論 2 356

推薦閱讀更多精彩內(nèi)容