【问题标题】:Can't convert NSData to NSString in swift无法快速将 NSData 转换为 NSString
【发布时间】:2014-10-14 23:57:26
【问题描述】:

这是我的功能。首先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
}

【问题讨论】:

  • 并非所有数据都可以用字符串表示。哈希 (SHA-256) 可表示的可能性基本上为零。这是因为 SHA-256(一般是散列)的结果是二进制数据。即使在不太可能发生的情况下,它也不是“合理”的文本。

标签: nsstring swift nsdata


【解决方案1】:
let resstr = NSString(data: res, encoding: NSUTF8StringEncoding)

如果数据不代表有效的 UTF-8 序列(很可能),则返回 nil。然后下面的println() 崩溃了。

任意二进制数据的可能字符串表示形式是 十六进制字符串或 Base-64 编码字符串。

Base-64 编码的字符串可以简单地用

获得
let resstr = res.base64EncodedStringWithOptions(nil)

(据我所知)没有将二进制数据转换为十六进制字符串的内置方法。 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
}

【讨论】:

  • 如何将数据转换为 UTF-8?控制台将 res 显示为“74696c22 2d3233cf c5dc040e 70ec9f5b dbcea3cf 53946368 65bb4382 64c782e5”,这正是我所需要的,但你的方法给出了“dGlsIi0yM8/F3AQOcOyfW9vOo89TlGNoZbtDgmTHguUpan =”,这是错误的
  • @ЮрикАлександров: &lt;74696c22 2d3233cf …&gt; 是 NSData 对象的 描述。没有将 NSData 转换为十六进制字符串的内置方法,但是如果您搜索“NSData to hex string”,您会发现很多解决方案,例如stackoverflow.com/questions/1305225/…stackoverflow.com/questions/7520615/…
  • @ЮрикАлександров:为了您的方便,我添加了一些 Swift 代码 :)
  • "那么下面的 println() 就会崩溃。" println() 不会崩溃。 println() 可以打印值为nil 的选项。崩溃发生在前一行,因为编译器推断resstr 具有类型NSString,这将解包可选。如果他明确声明resstr 的类型为NSString!NSString?,它就不会崩溃。
  • @newacct:好吧,我已经单步执行了它,它肯定println(resstr) 崩溃。原因可能是初始化器 init(data: NSData, encoding: UInt) 确实 not 返回一个可选项,请参阅 beta 6 发行说明中的​​“Swift 不支持因返回 null 而失败的对象初始化器”。 - 如果您将分配更改为let resstr : NSString? = NSString(data: res, encoding: NSUTF8StringEncoding),则println(resstr) 打印“nil”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-17
  • 2010-12-21
  • 2012-11-09
相关资源
最近更新 更多