CFStringRef FileMD5HashCreateWithPath(CFStringRef filePath,
size_t chunkSizeForReadingData) {
//声明校验结果变量 读取文件流变量
CFStringRef result =NULL;
CFReadStreamRef readStream=NULL;
//获得文件路径
URLCFURLRef fileURL =CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
(CFStringRef)filePath,kCFURLPOSIXPathStyle,(Boolean)false);
if (!fileURL){
CFRelease(fileURL);
}
//创建并打开文件流
streamreadStream =CFReadStreamCreateWithFile(kCFAllocatorDefault,(CFURLRef)fileURL);
if(!readStream)gotodone;
bool didSucceed =(bool)CFReadStreamOpen(readStream);
if (!readStream) {
CFReadStreamClose(readStream);
CFRelease(readStream);
}
//创建哈希对象
CC_MD5_CTX hashObject;
CC_MD5_Init(&hashObject);
//确保读取文件流的大小
if(!chunkSizeForReadingData) {
chunkSizeForReadingData=FileHashDefaultChunkSizeForReadingData;
}
//文件流存入哈希对象
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,(constvoid*)buffer,(CC_LONG)readBytesCount);
}
//判读读入到哈希对象是否成功
succeededdidSucceed = !hasMoreData;
//Compute the hash
digest unsigned char digest[CC_MD5_DIGEST_LENGTH];
CC_MD5_Final(digest,&hashObject);
//读入失败终止操作
if(!didSucceed){
};
//Compute the string result
char hash[2*sizeof(digest) +1];
for (size_t i = 0 ; i < sizeof(digest); ++ i) {
sprintf(hash+ (2* i),3,"%02x", (int)(digest[i]));
}
result=CFStringCreateWithCString(kCFAllocatorDefault,(constchar*)hash,
kCFStringEncodingUTF8);
returnresult;
}
+(NSString*)fileMD5:(NSString*)path
{
return(__bridge_transfer NSString *)FileMD5HashCreateWithPath((__bridge CFStringRef)path, FileHashDefaultChunkSizeForReadingData);
}