Get string md5 in Swift 5
Swift 5 version: Use UnsafeRawBufferPointer
as type of the closure argument, and bytes.baseAddress
to pass address to the Common Crypto function:
import Foundationimport CommonCryptoextension 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() }}
(Note that the conversion of a string to UTF-8 data cannot fail, there is no need to return an optional.)
CC_MD5 has been deprecated with the iOS 13. Instead, you can use CC_SHA256.
In iOS 13 and above there is a framework CryptoKit
which is a wrapper around CommonCrypto
framework and around the MD5 hash function.
import CryptoKitlet d = "Hello"let r = Insecure.MD5.hash(data: d.data(using: .utf8)!)print(r)/*Output: MD5 digest: 8b1a9953c4611296a827abf8c47804d7*/
Eskimo's solution
Below is a variant based on a solution proposed by Eskimo from Apple in 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() }}
Note it is effectively the same as Martin R's solution, but a line shorter (no return hash
).
Solution using NSData
This is an even shorter solution using bridging to 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() }}