In general, when we use HTTP or socket upload or download files, often after the completion of the line MD5 worth checking (especially when the breakpoint continued to use the more
more), verifying the MD5 value is to prevent packet loss or tampering in the process of transmission, before using MD5 we should first understand some common sense of MD5. MD5 Baidu Encyclopedia
In simple terms:
1), MD5 is a hash algorithm to calculate the file or the summary of the string, the MD5 algorithm brief description can be: MD5 to the 512-bit grouping to process the input information, and each group is divided into 16 32-bit sub-groups, after a series of processing, the output of the algorithm is composed of four 32-bit groups, When you cascade these four 32-bit groupings, a 128-bit hash value is generated. 128/8 = 16, which means that the MD5 gets a set of 16-byte-length octal binaries.
2), generally in use when you need to convert it to a hexadecimal output, and the output is lowercase.
With this basic knowledge, the calculation of MD5 is not so difficult, and recently in large file MD5 calculation on the internet to find a lot of iOS MD5 code, one of the majority of them can not be used, especially the use of
nsfilehandle* handle = [Nsfilehandle Filehandleforreadingatpath:_filepath]; This method, the most pit, should be read for it forever is the fixed location of the file, rather than calculate the entire file MD5 summary, so you always get into an awkward situation. For example: (
nsdata* fileData = [handle readdataoflength:1024*8]; Always read from the beginning, 1024*8 length of the file, if you use this method, you must set the location of the file read before each read to the specified location, you should use Nsfilehandle-(void) Seektofileoffset: ( unsigned long long) offset;
)
Next, I'm looking for a piece of code that can be used: pro-Test each platform with the same computed MD5 value. (in the course of use, you may meet
Filehashdefaultchunksizeforreadingdata undefined case, then you should display the mix definition in the header file:
#define Filehashdefaultchunksizeforreadingdata 1024*8
)
The code is as follows:
?
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 8 5 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 11 9 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;
}
|