快速计算大文件的MD5校验和

我正在为大型video文件创buildMD5校验和。 我目前正在使用的代码:

extension NSData { func MD5() -> NSString { let digestLength = Int(CC_MD5_DIGEST_LENGTH) let md5Buffer = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: digestLength) CC_MD5(bytes, CC_LONG(length), md5Buffer) let output = NSMutableString(capacity: Int(CC_MD5_DIGEST_LENGTH * 2)) for i in 0..<digestLength { output.appendFormat("%02x", md5Buffer[i]) } return NSString(format: output) } } 

但是这会创build一个内存缓冲区,而对于大型video文件来说并不理想。 有什么方法在Swift中计算读取文件stream的MD5校验和,所以内存占用将是最小的?

您可以计算块的MD5校验和,例如, 是否有一个MD5库不需要在同一时间的整个input? 。

这是一个使用Swift的可能的实现:

 func md5File(url: URL) -> Data? { let bufferSize = 1024 * 1024 do { // Open file for reading: let file = try FileHandle(forReadingFrom: url) defer { file.closeFile() } // Create and initialize MD5 context: var context = CC_MD5_CTX() CC_MD5_Init(&context) // Read up to `bufferSize` bytes, until EOF is reached, and update MD5 context: while autoreleasepool(invoking: { let data = file.readData(ofLength: bufferSize) if data.count > 0 { data.withUnsafeBytes { _ = CC_MD5_Update(&context, $0, numericCast(data.count)) } return true // Continue } else { return false // End of file } }) { } // Compute the MD5 digest: var digest = Data(count: Int(CC_MD5_DIGEST_LENGTH)) digest.withUnsafeMutableBytes { _ = CC_MD5_Final($0, &context) } return digest } catch { print("Cannot open file:", error.localizedDescription) return nil } } 

autorelease池是需要释放由file.readData()返回的内存,没有它的整个(可能是巨大的)文件将被加载到内存中。 感谢Abhi Beckert注意并提供实施。

如果您需要摘要作为hex编码的string,然后将返回types更改为String? 并更换

 return digest 

通过

 let hexDigest = digest.map { String(format: "%02hhx", $0) }.joined() return hexDigest