How can I convert a String to an MD5 hash in iOS using Swift?
There are two steps:
1. Create md5 data from a string
2. Covert the md5 data to a hex string
Swift 2.0:
func md5(string string: String) -> String {
var digest = [UInt8](count: Int(CC_MD5_DIGEST_LENGTH), repeatedValue: 0)
if let data = string.dataUsingEncoding(NSUTF8StringEncoding) {
CC_MD5(data.bytes, CC_LONG(data.length), &digest)
}
var digestHex = ""
for index in 0.. digestHex += String(format: "%02x", digest[index])
}
return digestHex
}
//Test:
let digest = md5(string:"Hello")
print("digest: \(digest)")
Output:
digest: 8b1a9953c4611296a827abf8c47804d7
Swift 3.0:
func MD5(string: String) -> Data {
let messageData = string.data(using:.utf8)!
var digestData = Data(count: Int(CC_MD5_DIGEST_LENGTH))
_ = digestData.withUnsafeMutableBytes {digestBytes in
messageData.withUnsafeBytes {messageBytes in
CC_MD5(messageBytes, CC_LONG(messageData.count), digestBytes)
}
}
return digestData
}
//Test:
let md5Data = MD5(string:"Hello")
let md5Hex = md5Data.map { String(format: "%02hhx", $0) }.joined()
print("md5Hex: \(md5Hex)")
let md5Base64 = md5Data.base64EncodedString()
print("md5Base64: \(md5Base64)")
Output:
md5Hex: 8b1a9953c4611296a827abf8c47804d7
md5Base64: ixqZU8RhEpaoJ6v4xHgE1w==
Swift 5.0:
import Foundation
import var CommonCrypto.CC_MD5_DIGEST_LENGTH
import func CommonCrypto.CC_MD5
import typealias CommonCrypto.CC_LONG
func MD5(string: String) -> Data {
let length = Int(CC_MD5_DIGEST_LENGTH)
let messageData = string.data(using:.utf8)!
var digestData = Data(count: length)
_ = digestData.withUnsafeMutableBytes { digestBytes -> UInt8 in
messageData.withUnsafeBytes { messageBytes -> UInt8 in
if let messageBytesBaseAddress = messageBytes.baseAddress, let digestBytesBlindMemory = digestBytes.bindMemory(to: UInt8.self).baseAddress {
let messageLength = CC_LONG(messageData.count)
CC_MD5(messageBytesBaseAddress, messageLength, digestBytesBlindMemory)
}
return 0
}
}
return digestData
}
//Test:
let md5Data = MD5(string:"Hello")
let md5Hex = md5Data.map { String(format: "%02hhx", $0) }.joined()
print("md5Hex: \(md5Hex)")
let md5Base64 = md5Data.base64EncodedString()
print("md5Base64: \(md5Base64)")
Output:
md5Hex: 8b1a9953c4611296a827abf8c47804d7
md5Base64: ixqZU8RhEpaoJ6v4xHgE1w==
Notes:#import
must be added to a Bridging-Header file
For how to create a Bridging-Header see this SO answer.
In general MD5 should not be used for new work, SHA256 is a current best practice.
Example from deprecated documentation section:
MD2, MD4, MD5, SHA1, SHA224, SHA256, SHA384, SHA512 (Swift 3+)
These functions will hash either String or Data input with one of eight cryptographic hash algorithms.
The name parameter specifies the hash function name as a String
Supported functions are MD2, MD4, MD5, SHA1, SHA224, SHA256, SHA384 and SHA512
a
This example requires Common Crypto
It is necessary to have a bridging header to the project:#import
Add the Security.framework to the project.
This function takes a hash name and String to be hashed and returns a Data:
name: A name of a hash function as a String
string: The String to be hashed
returns: the hashed result as Data
func hash(name:String, string:String) -> Data? {
let data = string.data(using:.utf8)!
return hash(name:name, data:data)
}
Examples:
let clearString = "clearData0123456"
let clearData = clearString.data(using:.utf8)!
print("clearString: \(clearString)")
print("clearData: \(clearData as NSData)")
let hashSHA256 = hash(name:"SHA256", string:clearString)
print("hashSHA256: \(hashSHA256! as NSData)")
let hashMD5 = hash(name:"MD5", data:clearData)
print("hashMD5: \(hashMD5! as NSData)")
Output:
clearString: clearData0123456
clearData: <636c6561 72446174 61303132 33343536>
hashSHA256:
hashMD5: <4df665f7 b94aea69 695b0e7b baf9e9d6>
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 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()
}
}
(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.
How to get MD5 hash from string in SWIFT and make bridge-header
You need to add a bridging header and add the #import
statement to it.
The easiest way to add a bridging header is to add an Objective-C file to the project, you will be aked ig you want to add a bridging header, reply yes. After that you can delete the Objective-C file file that was added.
Example code:
func md5(#string: String) -> NSData {
var digest = NSMutableData(length: Int(CC_MD5_DIGEST_LENGTH))!
if let data :NSData = string.dataUsingEncoding(NSUTF8StringEncoding) {
CC_MD5(data.bytes, CC_LONG(data.length),
UnsafeMutablePointer(digest.mutableBytes))
}
return digest
}
//Test:
let digest = md5(string:"Here is the test string")
println("digest: \(digest)")
Output:
digest: 8f833933 03a151ea 33bf6e3e bbc28594
Here is a more Swift 2.0 version returning an array of UInt8
:
func md5(string string: String) -> [UInt8] {
var digest = [UInt8](count: Int(CC_MD5_DIGEST_LENGTH), repeatedValue: 0)
if let data = string.dataUsingEncoding(NSUTF8StringEncoding) {
CC_MD5(data.bytes, CC_LONG(data.length), &digest)
}
return digest
}
Get Base64 encoded SHA12 MD5 digest in Swift
I rewrote your code a little. Try this
func sha512Base64(string: String) -> String? {
guard let data = string.data(using: String.Encoding.utf8) else {
return nil
}
var digest = Data(count: Int(CC_SHA512_DIGEST_LENGTH))
_ = digest.withUnsafeMutableBytes { digestBytes -> UInt8 in
data.withUnsafeBytes { messageBytes -> UInt8 in
if let mb = messageBytes.baseAddress, let db = digestBytes.bindMemory(to: UInt8.self).baseAddress {
let length = CC_LONG(data.count)
CC_SHA512(mb, length, db)
}
return 0
}
}
return digest.base64EncodedString()
}
I like this answer https://stackoverflow.com/a/52120827
with his approach you can use it like
"123".hashed(.sha512, output: .base64)
Related Topics
Iphone: How to Get Current Milliseconds
Comparing Nsdates Without Time Component
Foreign Key Relationship Mapping with Restkit
iOS - Uiimageview - How to Handle Uiimage Image Orientation
How to Detect If a Video File Was Recorded in Portrait Orientation, or Landscape in iOS
How to Change Color of Single Word in Uitextview and Uitextfield
Long Press Gesture on Uicollectionviewcell
How to Add Background Image on iPhone Navigation Bar
How to Run/Test My Flutter App on a Real Device
iOS Uinavigationbar Button Remains Faded After Segue Back
How to Hide Keyboard in Swift on Pressing Return Key
Uploading Image with Afnetworking 2.0
Iad Is Shutting Down. Should I Remove the Iad Framework from All My Applications
Difference Between Protocol and Delegates
Navigationlink Works Only for Once
Detecting Collisions in Sprite Kit