Ondrej Ondrej - 1 month ago 132
Swift Question

MD5 of Data in Swift 3

I am trying to get MD5 hash of my data (image downloaded from the interweb). Unfortunately I have upgraded the framework to swift 3 and the method I have been using doesn't work now.

I have converted most of it but I am unable to get bytes out of the data:

import Foundation
import CommonCrypto


struct MD5 {

static func get(data: Data) -> String {
var digest = [UInt8](repeating: 0, count: Int(CC_MD5_DIGEST_LENGTH))
CC_MD5(data.bytes, CC_LONG(data.count), &digest)

var digestHex = ""
for index in 0..<Int(CC_MD5_DIGEST_LENGTH) {
digestHex += String(format: "%02x", digest[index])
}

return digestHex
}

}


the CommonCrypto is already imported as a custom module. Problem is I am getting
'bytes' is unavailable: use withUnsafeBytes instead
on
CC_MD5(data.bytes,...


So the question really is, how do I get the bytes out of the data and will this solution work?

Answer
    CC_MD5(data.bytes, CC_LONG(data.count), &digest)

As noted, bytes is unavailable because it's dangerous. It's a raw pointer into memory than can vanish. The recommended solution is to use withUnsafeBytes which promises that the target cannot vanish during the scope of the pointer. From memory, it would look something like this:

data.withUnsafeBytes { bytes in
    CC_MD5(bytes, CC_LONG(data.count), &digest)
}

The point is that the bytes pointer can't escape into scopes where data is no longer valid.

For an example of this with CCHmac, which is pretty similar to MD5, see RNCryptor.

Comments