在Swift 5中获取字符串md5

问题描述 投票:7回答:2

在Swift 4中我们可以使用

var md5: String? {
    guard let data = self.data(using: .utf8) else { return nil }
    let hash = data.withUnsafeBytes { (bytes: UnsafePointer<Data>) -> [UInt8] in
        var hash: [UInt8] = [UInt8](repeating: 0, count: Int(CC_MD5_DIGEST_LENGTH))
        CC_MD5(bytes, CC_LONG(data.count), &hash)
        return hash
    }
    return hash.map { String(format: "%02x", $0) }.joined()
}

但在Swift 5中,withUnsafeBytes使用UnsafeRawBufferPointer而不是UnsafePointer。如何更改md5功能?

ios swift md5 swift5
2个回答
9
投票

Swift 5版本:使用UnsafeRawBufferPointer作为闭包参数的类型,并使用bytes.baseAddress将地址传递给Common Crypto函数:

extension String {
    var md5: String {
        let data = Data(self.utf8)
        let hash = data.withUnsafeBytes { (bytes: UnsafeRawBufferPointer) -> [UInt8] in
            var hash = [UInt8](repeating: 0, count: Int(CC_MD5_DIGEST_LENGTH))
            CC_MD5(bytes.baseAddress, CC_LONG(data.count), &hash)
            return hash
        }
        return hash.map { String(format: "%02x", $0) }.joined()
    }
}

(注意,将字符串转换为UTF-8数据不能失败,不需要返回可选项。)


0
投票

爱斯基摩人solutine

以下是一个基于Eskimo提出的解决方案的变种,该解决方案来自Apple在Swift Forum post withUnsafeBytes Data API confusion

extension String {
    func md5() -> String {
        let data = Data(utf8)
        var hash = [UInt8](repeating: 0, count: Int(CC_MD5_DIGEST_LENGTH))

        data.withUnsafeBytes { buffer in
            _ = CC_MD5(buffer.baseAddress, CC_LONG(buffer.count), &hash)
        }

        return hash.map { String(format: "%02hhx", $0) }.joined()
    }
}

请注意,它实际上与Martin R的解决方案相同,但更短的线(没有return hash)。

解决方案使用NSData

这是使用桥接到NSData的更短的解决方案。

extension String {
    func md5() -> String {
        let data = Data(utf8) as NSData
        var hash = [UInt8](repeating: 0, count: Int(CC_MD5_DIGEST_LENGTH))
        CC_MD5(data.bytes, CC_LONG(data.length), &hash)
        return hash.map { String(format: "%02hhx", $0) }.joined()
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.