The only answer I found was in this, and I'm not satisfied with it.
I am adding a standard MD5 converter as a String extension:
/* ###################################################################################################################################### */
/**
From here: https://stackoverflow.com/q/24123518/879365
I am not making this public, because it requires the common crypto in the bridging header.
*/
fileprivate extension String {
/* ################################################################## */
/**
- returns: the String, as an MD5 hash.
*/
var md5: String {
let str = self.cString(using: String.Encoding.utf8)
let strLen = CUnsignedInt(self.lengthOfBytes(using: String.Encoding.utf8))
let digestLen = Int(CC_MD5_DIGEST_LENGTH)
let result = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: digestLen)
CC_MD5(str!, strLen, result)
let hash = NSMutableString()
for i in 0..<digestLen {
hash.appendFormat("%02x", result[i])
}
result.deallocate()
return hash as String
}
}
It requires that I add the following to my bridging header:
#import <CommonCrypto/CommonCrypto.h>
Since I'd like to add this to a suite of reusable tools, I'd like to see if there was a way to detect, at compile time, whether or not the common crypto library was being used.
Is there a way for me to set this up as a conditional compile?
It's not a big deal if not; just means that I'll need to set this up as a separate source file.
It might be worth noting that you can call CC_MD5
without a bridging header, if you use dlsym
to access it.
import Foundation
typealias CC_MD5_Type = @convention(c) (UnsafeRawPointer, UInt32, UnsafeMutableRawPointer) -> UnsafeMutableRawPointer
let RTLD_DEFAULT = UnsafeMutableRawPointer(bitPattern: -2)
let CC_MD5 = unsafeBitCast(dlsym(RTLD_DEFAULT, "CC_MD5")!, to: CC_MD5_Type.self)
var md5 = Data(count: 16)
md5.withUnsafeMutableBytes {
_ = CC_MD5("abc", 3, $0)
}
assert(md5 == Data(bytes: [0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0, 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72]))