Computing cryptographic hashes in Swift has gotten easier in recent times. Prior to Xcode 10, it used to be difficult to import the CommonCrypto
library which did the computation. Xcode 10 added a module for that library, making it easier to do the import. But the API still looks like a C API. Using the library directly requires you to write something like this:
import CommonCrypto
import Foundation
// Compute the digest of this string:
let messageString = "The quick brown fox jumps over the lazy dog"
// Convert the string to a byte array.
let messageData = Data(messageString.utf8)
// Compute the hash using CommonCrypto.
var digestData = Data(count: Int(CC_SHA224_DIGEST_LENGTH))
digestData.withUnsafeMutableBytes { (digestBuffer: UnsafeMutableRawBufferPointer) -> Void in
messageData.withUnsafeBytes { (messageBuffer: UnsafeRawBufferPointer) -> Void in
_ = CC_SHA224(messageBuffer.baseAddress,
CC_LONG(messageBuffer.count),
digestBuffer.baseAddress?.assumingMemoryBound(to: UInt8.self))
}
}
// Convert the digestData byte buffer into a hex string.
let digestString = digestData.map { String(format: "%02hhx", $0) }.joined()
// prints 730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525
print(digestString)
That's a fair amount of boilerplate. The meat of that code — the withUnsafeMutableBytes
and withUnsafeBytes
calls — changed between Swift versions. I had to rewrite that code a few times to eliminate new compiler warnings and deprecations.
Rather than deal with that in production code, I wrote a small Swift library called HashAlgorithm
to simplify the process.
Using it is pretty simple. Instead of the code above, you just do this:
import Foundation
import HashAlgorithm
// Compute the digest of this string:
let messageString = "The quick brown fox jumps over the lazy dog"
let digest = HashAlgorithm.SHA224.digest(messageString)
// prints 730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525
print(digest)
The digest(_:)
function returns a Digest
value that wraps a Data
value. Its description
property converts the data into a hex-string.
It supports all of the (non-deprecated) cryptographic hash algorithms currently provided by CommonCrypto
: SHA1, SHA224, SHA256, SHA384, and SHA512.