学习IOS--获取文件的MD5值

一般我们在使用http或者socket上传或者下载文件的时候,经常会在完成之后经行一次MD5值得校验(尤其是在断点续传的时候用的更

多),校验MD5值是为了防止在传输的过程当中丢包或者数据包被篡改,在使用MD5之前呢我们应该先了解MD5的一些常识。MD5 百度百科

简单的来说:

1)、MD5是使用哈希算法计算文件或字符串的摘要,对MD5算法简要的叙述可以为:MD5以512位分组来处理输入的信息,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列值。128/
8 = 16,也就是说MD5得到的是一组16字节长度的八进制。

2)、一般在使用的时候需要将它转换成十六进制输出,并且同时输出为小写。

在有了这些基础知识之后,计算MD5就没有那么大的难度了,最近在做大文件MD5计算的时候在网上搜到了一大堆ios
MD5的代码,其中有一大部分都不能用,尤其是 使用

NSFileHandle*  handle =
[NSFileHandle fileHandleForReadingAtPath:_filePath];
这种方法的,就最坑了,应为它永远读取的是文件的固定的位置,而并不是计算整个文件的MD5摘要,所以永远让你陷入尴尬的境地。例如:(

NSData* fileData = [handle readDataOfLength: 1024*8];
//永远读取的是从开始位置开始,1024*8长度的文件,
如果使用这种方法的话,必须在每次读取之前将文件读取的位置设置为指定的位置,应该使用NSFileHandle的 -
(void)seekToFileOffset:(unsigned long long)offset;

下面贴上我找的能用的一段代码:亲测各个平台同一个计算出来的MD5值相同。(在使用的时候,可能会见

FileHashDefaultChunkSizeForReadingData 未定义的情况,那么你应该显示的在头文件里加入混定义:

#define FileHashDefaultChunkSizeForReadingData 1024*8 

代码如下:

?





1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

+(NSString*)getFileMD5WithPath:(NSString*)path

{

    return
(__bridge_transfer NSString
*)FileMD5HashCreateWithPath((__bridge CFStringRef)path, FileHashDefaultChunkSizeForReadingData);

}

 

CFStringRef FileMD5HashCreateWithPath(CFStringRef filePath,size_t chunkSizeForReadingData) {

    // Declare needed variables

    CFStringRef result = NULL;

    CFReadStreamRef readStream = NULL;

    // Get the file URL

    CFURLRef fileURL =

    CFURLCreateWithFileSystemPath(kCFAllocatorDefault,

                                  (CFStringRef)filePath,

                                  kCFURLPOSIXPathStyle,

                                  (Boolean)false);

    if
(!fileURL) goto
done;

    // Create and open the read stream

    readStream = CFReadStreamCreateWithFile(kCFAllocatorDefault,

                                            (CFURLRef)fileURL);

    if
(!readStream) goto
done;

    bool
didSucceed = (bool)CFReadStreamOpen(readStream);

    if
(!didSucceed) goto
done;

    // Initialize the hash object

    CC_MD5_CTX hashObject;

    CC_MD5_Init(&hashObject);

    // Make sure chunkSizeForReadingData is valid

    if
(!chunkSizeForReadingData) {

        chunkSizeForReadingData = FileHashDefaultChunkSizeForReadingData;

    }   

    // Feed the data to the hash object

    bool
hasMoreData = true;

    while
(hasMoreData) {

        uint8_t buffer[chunkSizeForReadingData];

        CFIndex readBytesCount = CFReadStreamRead(readStream,(UInt8 *)buffer,(CFIndex)sizeof(buffer));

        if
(readBytesCount == -1) break;

        if
(readBytesCount == 0) {

            hasMoreData = false;

            continue;

        }

        CC_MD5_Update(&hashObject,(const
void *)buffer,(CC_LONG)readBytesCount);

    }   

    // Check if the read operation succeeded

    didSucceed = !hasMoreData;

    // Compute the hash digest

    unsigned char
digest[CC_MD5_DIGEST_LENGTH];

    CC_MD5_Final(digest, &hashObject);

    // Abort if the read operation failed

    if
(!didSucceed) goto
done;

    // Compute the string result

    char
hash[2 * sizeof(digest) + 1];

    for
(size_t i = 0; i < sizeof(digest); ++i) {

        snprintf(hash + (2 * i), 3, "%02x", (int)(digest[i]));

    }

    result = CFStringCreateWithCString(kCFAllocatorDefault,(const
char *)hash,kCFStringEncodingUTF8);

    

done:

    if
(readStream) {

        CFReadStreamClose(readStream);

        CFRelease(readStream);

    }

    if
(fileURL) {

        CFRelease(fileURL);

    }

    return
result;

}

  

时间: 2024-10-03 21:53:29

学习IOS--获取文件的MD5值的相关文章

iOS开发之获取文件的md5值

我们经常有下载文件上的需求 为了安全我们经常需要对文件进行md5校验 那我就来给大家分享一个很方便的获取文件md5值得方法. 首先需要引用系统库文件 #include <CommonCrypto/CommonDigest.h> /** 获取文件的md5值*/ + (NSString *)getFileMD5StrFromPath:(NSString *)path { NSFileManager *fileManager = [NSFileManager defaultManager]; if(

Python写自动化之获取文件的MD5值

使用Python 获取文件的MD5 值是一件很简单的事情,Python 提供了md5 和 hashlib 两个模块,都可以获取到文件的md5值. 代码如下: #获取文件的MD5值,适用于小文件 def getFileMD5(self,filepath): if self.isFile(filepath): f = open(filepath,'rb') md5obj = hashlib.md5() md5obj.update(f.read()) hash = md5obj.hexdigest()

Android获取文件的MD5值

package my.bag; import java.io.File; import java.io.FileInputStream; import java.math.BigInteger; import java.security.MessageDigest; import java.util.HashMap; import java.util.Map; import android.app.Activity; import android.os.Bundle; import androi

获取文件的MD5值,比较两个文件是否完全相同

代码: public class MD5Test { public static void main(String[] args) { String s1 = MD5Test.MD5Operation(new File("E:/a.csv")); String s2 = MD5Test.MD5Operation(new File("E:/data/a.csv")); System.out.println(s1.equals(s2)); } public final

在浏览器端获取文件的MD5值

http://www.jianshu.com/p/940a9226fbbd 前几天接到一个奇怪的需求,要在web页面中计算文件的md5值,还好这个项目是只需兼容现代浏览器的,不然要坑死了. 其实对文件进行md5,对于后端来说是及其简单的.比如使用Node.js,只要下面几行代码就可以了: var fs= require('fs'); var crypto = require('crypto'); function md5File(path, callback) { fs.readFile(pat

获取文件的MD5值

package com.example.assetsdemo; import java.io.File; import java.io.FileInputStream; import java.math.BigInteger; import java.security.MessageDigest; import java.util.HashMap; import java.util.Map; public class FileDigest { /** * 获取单个文件的MD5值! * * @pa

java获取文件的md5值

import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class Test {

linux shell 命令获取字符串/文件的MD5值

获取字符串的MD5值: 字符串"hello"的MD5: $ echo -n 'hello'|md5sum|cut -d ' ' -f1 得到的MD5值: 5d41402abc4b2a76b9719d911017c592 命令解释: md5sum: 显示或检查 MD5(128-bit) 校验和,若没有文件选项,或者文件处为"-",则从标准输入读取. echo -n : 不打印换行符. cut:  cut用来从标准输入或文本文件中剪切列或域.剪切文本可以将之粘贴到一个文

计算文件的MD5值(Java &amp; Rust)

Java public class TestFileMD5 { public final static String[] hexDigits = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b",