Created
February 8, 2018 02:26
-
-
Save wuchuwuyou/e0e57f40541b1d2f5a9b713642f469a3 to your computer and use it in GitHub Desktop.
获取文件MD5
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define FileHashDefaultChunkSizeForReadingData 1024*8 | |
#include <CommonCrypto/CommonDigest.h> | |
+ (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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment