在Swift 5中获取字符串md5

Val*_*din 9 md5 ios swift swift5

在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()
}
Run Code Online (Sandbox Code Playgroud)

但是在Swift 5中withUnsafeBytes使用UnsafeRawBufferPointer代替UnsafePointer。如何改变md5功能?

Mar*_*n R 14

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

import Foundation
import CommonCrypto

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()
    }
}
Run Code Online (Sandbox Code Playgroud)

(请注意,将字符串转换为UTF-8数据不会失败,无需返回可选值。)


Aqu*_*qua 11

在 iOS 13 及以上版本中有一个框架CryptoKit。尝试使用这个:

extension Data {       
    var md5: String {
        Insecure.MD5
            .hash(data: self)
            .map {String(format: "%02x", $0)}
            .joined()
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @ValentinShamardin CryptoKit 不是第三方库。这是自 iOS 13 起可用的苹果框架 (5认同)

Ado*_*els 9

在 iOS 13 及更高版本中有一个框架CryptoKit,它是围绕CommonCrypto框架和 MD5 哈希函数的包装器。

import CryptoKit

let d = "Hello"
let r = Insecure.MD5.hash(data: d.data(using: .utf8)!)
print(r)

/*Output: MD5 digest: 8b1a9953c4611296a827abf8c47804d7*/
Run Code Online (Sandbox Code Playgroud)


Mar*_*rný 6

爱斯基摩人的解决方案

以下是基于 Apple 的 Eskimo 在 Swift 论坛帖子with UnsafeBytes Data API 混淆中提出的解决方案的变体:

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()
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,它实际上与 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()
    }
}
Run Code Online (Sandbox Code Playgroud)