web-dev-qa-db-ja.com

swift)でNSDataをNSStringに変換できません

これが私の機能です。最初のprintlnは正しいハッシュをコンソールに出力しますが、次の行でプログラムがクラッシュします。手伝って頂けますか?

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
}
9
Yury Alexandrov
_let resstr = NSString(data: res, encoding: NSUTF8StringEncoding)
_

データが有効なUTF-8シーケンスを表していない場合はnilを返します(これは非常に可能性が高いです)。次に、次のprintln()がクラッシュします。

任意のバイナリデータの可能な文字列表現は、16進文字列またはBase-64でエンコードされた文字列です。

Base-64でエンコードされた文字列は、次のコマンドで簡単に取得できます。

_let resstr = res.base64EncodedStringWithOptions(nil)
_

(私が知る限り)バイナリデータを16進文字列に変換する組み込みメソッドはありません。 Swift(利用可能な多くのObjective-Cソリューションに触発された)で可能な実装は次のとおりです。

_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
    }
}
_

しかし、中間のNSDataオブジェクトを使用せずに、それをハッシュメソッドに直接統合することができます。

_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
}
_
41
Martin R