Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't convert NSData to NSString in swift

This is my function. First println print correct hash to console but in the next row program crashes. Can you help me?

func sha256(string: NSString) -> NSString {
    var data : NSData! = string.dataUsingEncoding(NSUTF8StringEncoding)
    var hash = [UInt8](count: Int(CC_SHA256_DIGEST_LENGTH), repeatedValue: 0)
    CC_SHA256(data.bytes, CC_LONG(data.length), &hash)
    let res = NSData(bytes: hash, length: Int(CC_SHA256_DIGEST_LENGTH))
    println(res)
    let resstr = NSString(data: res, encoding: NSUTF8StringEncoding)
    println(resstr)
    return resstr
}
like image 601
Yury Alexandrov Avatar asked Aug 21 '14 11:08

Yury Alexandrov


1 Answers

let resstr = NSString(data: res, encoding: NSUTF8StringEncoding)

returns nil if the data does not represent a valid UTF-8 sequence (which is very likely). Then the following println() crashes.

A possible string representation for arbitrary binary data would be a hex string or a Base-64 encoded string.

A Base-64 encoded string can simply be obtained with

let resstr = res.base64EncodedStringWithOptions(nil)

There is (as far as I know) no built-in method to convert binary data to a hex string. A possible implementation in Swift (inspired by the lots of available Objective-C solutions) is

extension NSData {
    func hexString() -> NSString {
        var str = NSMutableString()
        let bytes = UnsafeBufferPointer<UInt8>(start: UnsafePointer(self.bytes), count:self.length)
        for byte in bytes {
            str.appendFormat("%02hhx", byte)
        }
        return str
    }
}

But you could integrate that into your hash method directly, without using an intermediate NSData object:

func sha256(string: NSString) -> NSString {
    let data = string.dataUsingEncoding(NSUTF8StringEncoding)!
    var hash = [UInt8](count: Int(CC_SHA256_DIGEST_LENGTH), repeatedValue: 0)
    CC_SHA256(data.bytes, CC_LONG(data.length), &hash)
    let resstr = NSMutableString()
    for byte in hash {
        resstr.appendFormat("%02hhx", byte)
    }
    return resstr
}
like image 141
Martin R Avatar answered Oct 18 '22 19:10

Martin R