ios – Swift计算大文件的MD5校验和

我正在为大型视频文件创建MD5校验和.我目前正在使用代码
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)
    }
}

但这会产生一个内存缓冲区,对于大型视频文件来说并不理想.在Swift中有没有办法计算读取文件流的MD5校验和,因此内存占用量最小?

解决方法

如图所示,您可以按块计算MD5校验和
例如在 Is there a MD5 library that doesn’t require the whole input at the same time?.

以下是使用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
    }
}

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

如果您需要将摘要作为十六进制编码的字符串,请更改
将类型返回到String?并替换

return digest

通过

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

相关文章

当我们远离最新的 iOS 16 更新版本时,我们听到了困扰 Apple...
欧版/美版 特别说一下,美版选错了 可能会永久丧失4G,不过只...
一般在接外包的时候, 通常第三方需要安装你的app进行测...
前言为了让更多的人永远记住12月13日,各大厂都在这一天将应...