iOS 超大文件MD5加密,超大文件hmac加密

1、在文件超过1G的时候,不能一次性放入内存之中,但是我们还是需要将这个文件进行md5加密,或者hmac系列的加密

这个时候我们需要用到一个系统的api——update系列的方法

 

注意:参数path为大文件所在的路径。
//首先声明一个宏定义
#define FileHashDefaultChunkSizeForReadingData 1024*8
//md5
+(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;
}

 

//HMAC
+(NSString*)getFileHMACWithPath:(NSString*)path withKey:(NSString *)key{ return (__bridge_transfer NSString *)FileHMACCreateWithPath((__bridge CFStringRef)path, FileHashDefaultChunkSizeForReadingData,key); } CFStringRef FileHMACCreateWithPath(CFStringRef filePath,size_t chunkSizeForReadingData,NSString* key) { // 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 const char *cKey = [key cStringUsingEncoding:NSASCIIStringEncoding]; CCHmacContext ctx; CCHmacInit(&ctx, kCCHmacAlgSHA256, cKey, strlen(cKey)); // 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; } CCHmacUpdate(&ctx, (const void *)buffer,(CC_LONG)readBytesCount); } // Check if the read operation succeeded didSucceed = !hasMoreData; // Compute the hash digest unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH]; CCHmacFinal(&ctx, cHMAC); // Abort if the read operation failed if (!didSucceed) goto done; // Compute the string result char hmac[2 * sizeof(cHMAC) + 1]; for (size_t i = 0; i < sizeof(cHMAC); ++i) { snprintf(hmac + (2 * i), 3, "%02x", (int)(cHMAC[i])); } result = CFStringCreateWithCString(kCFAllocatorDefault,(const char *)hmac,kCFStringEncodingUTF8); done: if (readStream) { CFReadStreamClose(readStream); CFRelease(readStream); } if (fileURL) { CFRelease(fileURL); } return result; }

 

posted @ 2019-09-03 10:44  预估计  阅读(1109)  评论(0编辑  收藏  举报