4

I'm trying to convert my string into SHA256 hash, but I get the next error:

Cannot invoke initializer for type 'UnsafeMutablePointer<UInt8>' with an argument list of type '(UnsafeMutableRawPointer)'

That's my function:

func SHA256(data: String) -> Data {
    var hash = NSMutableData(length: Int(CC_SHA256_DIGEST_LENGTH))!

    if let newData: Data = data.data(using: .utf8) {
        let bytes = newData.withUnsafeBytes {(bytes: UnsafePointer<CChar>) -> Void in
            CC_SHA256(bytes, CC_LONG(newData.length), UnsafeMutablePointer<UInt8>(hash.mutableBytes))
        }
    }

    return hash as Data
}

so, for this part

UnsafeMutablePointer<UInt8>(hash.mutableBytes)

I get this error:

Cannot invoke initializer for type 'UnsafeMutablePointer<UInt8>' with an argument list of type '(UnsafeMutableRawPointer)'

How can I fix that and what I do wrong?

Doe
  • 431
  • 1
  • 8
  • 16

1 Answers1

2

You'd better use Data also for the result hash.

In Swift 3, withUnsafePointer(_:) and withUnsafeMutablePointer(:_) are generic types and Swift can infer the Pointee types correctly when used with "well-formed" closures, which means you have no need to convert Pointee types manually.

func withUnsafeBytes((UnsafePointer) -> ResultType)

func withUnsafeMutableBytes((UnsafeMutablePointer) -> ResultType)

func SHA256(data: String) -> Data {
    var hash = Data(count: Int(CC_SHA256_DIGEST_LENGTH))

    if let newData: Data = data.data(using: .utf8) {
        _ = hash.withUnsafeMutableBytes {mutableBytes in
            newData.withUnsafeBytes {bytes in
                CC_SHA256(bytes, CC_LONG(newData.count), mutableBytes)
            }
        }
    }

    return hash
}

In Swift 3, the initializers of UnsafePointer and UnsafeMutablePointer, which was used to convert Pointee types till Swift 2, are removed. But in many cases, you can work without type conversions of pointers.

OOPer
  • 47,149
  • 6
  • 107
  • 142
  • I get an error: `NSMutableData has no member hash.withUnsafeMutableBytes` – Doe Oct 01 '16 at 00:26
  • @Doe, please see whole code I have shown, especially the line `var hash = ...`. – OOPer Oct 01 '16 at 00:27
  • why when I print my hash it pribts only `32 bytes`, but not the hash string? – Doe Oct 01 '16 at 00:34
  • @Doe, the content is exactly the same as when using `NSData` or `NSMutableData`. If you want to see the content for debugging purpose, you may need to write something like `print(hash as NSData)`. – OOPer Oct 01 '16 at 00:39
  • I want to get my hash value of that string. For example in web it returns you string, like `e0712cc9db510dd3611bc3...`, but here it gives me `<2c6e991d c60e6e06 c3d562c1 c6f47425 2b50b3b1...>` is it the same thing? – Doe Oct 01 '16 at 00:41
  • @Doe, `Data` (or `NSData`) is just a collection of bytes and `<2c6e...>` is an old plist-format representation of the content. If you need a specific hexadecimal representation, you need to generate it by yourself. Even if you use `NSMutableData`, you cannot get it automatically. For example, check [this](http://stackoverflow.com/a/39075044/6541007). – OOPer Oct 01 '16 at 00:51
  • Thank you for your help! – Doe Oct 01 '16 at 01:17