Swift 3:将字符串编码为UTF-16LE

hdo*_*ria 0 utf-8 utf-16le swift

我需要将字符串编码为UTF-16LE(稍后转换为sha1),但我遇到了一些问题.这是我试过的:

let utf16array = Array("password".utf16)
print(utf16array)
// [112, 97, 115, 115, 119, 111, 114, 100]
Run Code Online (Sandbox Code Playgroud)

但这正是我所期待的:

// [112, 0, 97, 0, 115, 0, 115, 0, 119, 0, 111, 0, 114, 0, 100, 0] 
Run Code Online (Sandbox Code Playgroud)

使用utf8array也一样:

let utf8array = "password".utf8.map({ $0 as UInt8 })
// [112, 97, 115, 115, 119, 111, 114, 100]
Run Code Online (Sandbox Code Playgroud)

所以,这就是我所做的"修复"它:

var bytesArray:[UInt16] = []
for byte in utf16array {
    bytesArray.append(byte)
    bytesArray.append(0)
}
print(bytesArray)
// [112, 0, 97, 0, 115, 0, 115, 0, 119, 0, 111, 0, 114, 0, 100, 0]
Run Code Online (Sandbox Code Playgroud)

但我确信这不是正确的方法.有什么建议?

Mar*_*n R 5

你可以用UTF-16LE数据表示

let password = "password€"
let data = password.data(using: .utf16LittleEndian)!
print(data as NSData)
// <70006100 73007300 77006f00 72006400 ac20>
Run Code Online (Sandbox Code Playgroud)

这已经足以计算SHA1摘要(如何使用Swift将密码字符串转换为sha1?):

var digest = [UInt8](repeating: 0, count:Int(CC_SHA1_DIGEST_LENGTH))
data.withUnsafeBytes { 
    _ = CC_SHA1($0, CC_LONG(data.count), &digest)
}
let hexEncodedDigest = digest.map { String(format: "%02hhx", $0) }.joined()
print(hexEncodedDigest)
// 177f0d080dfe533e102dd67d6321204813cf1b0c
Run Code Online (Sandbox Code Playgroud)

但是如果你需要它作为字节数组那么

let bytesArray = data.map { $0 }
print(bytesArray)
// [112, 0, 97, 0, 115, 0, 115, 0, 119, 0, 111, 0, 114, 0, 100, 0, 172, 32]
Run Code Online (Sandbox Code Playgroud)

会工作.

(我已经附加了非ASCII字符用于演示, € = U+20AC变成172, 32.)


如果你很好奇如何将[UInt16]数组转换为数组 [UInt8],这就是你可以用一些指针杂耍(只是一个副本)来做到这一点:

let utf16array = Array("password€".utf16)
print(utf16array)
// [112, 97, 115, 115, 119, 111, 114, 100, 8364]

let bytes = Array(utf16array.withUnsafeBufferPointer {
    $0.baseAddress!.withMemoryRebound(to: UInt8.self, capacity: 2 * utf16array.count) {
        UnsafeBufferPointer(start: $0, count: 2 * utf16array.count)
    }
})
print(bytes)
// [112, 0, 97, 0, 115, 0, 115, 0, 119, 0, 111, 0, 114, 0, 100, 0, 172, 32]
Run Code Online (Sandbox Code Playgroud)