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

Swift 3:将字符串编码为UTF-16LE,swift,utf-8,utf-16le,Swift,Utf 8,Utf 16le,我需要将字符串编码为UTF-16LE(稍后再转换为sha1),但我遇到了一些问题。这就是我曾经尝试过的: let utf16array = Array("password".utf16) print(utf16array) // [112, 97, 115, 115, 119, 111, 114, 100] 但这正是我所期待的: // [112, 0, 97, 0, 115, 0, 115, 0, 119, 0, 111, 0, 114, 0, 100, 0] 使用utf8array时的情

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

let utf16array = Array("password".utf16)
print(utf16array)
// [112, 97, 115, 115, 119, 111, 114, 100]
但这正是我所期待的:

// [112, 0, 97, 0, 115, 0, 115, 0, 119, 0, 111, 0, 114, 0, 100, 0] 
使用utf8array时的情况也一样:

let utf8array = "password".utf8.map({ $0 as UInt8 })
// [112, 97, 115, 115, 119, 111, 114, 100]
所以,这就是我为“修复”它所做的:

但我肯定这不是正确的方法。有什么建议吗?

这里使用的是适合目的的解决方案

但为了好玩,另一种方法是使用OP的
字符串
:UTF-16编码方法(
utf16
字符串
属性)。使用
UInt8
init(截断位模式:UInt16)
初始值设定项,结合
zip
,然后使用
flatMap
,后者将压缩的元组展平为一个数组:

let pw = "password€"

let bytes = zip(pw.utf16.map{ UInt8(truncatingBitPattern: $0) },
                pw.utf16.map{ UInt8(truncatingBitPattern: $0 >> 8) })
            .flatMap{ [$0, $1] }

print(bytes)
// [112, 0, 97, 0, 115, 0, 115, 0, 119, 0, 111, 0, 114, 0, 100, 0, 172, 32]
在这里,使用是适合目的的解决方案

但为了好玩,另一种方法是使用OP的
字符串
:UTF-16编码方法(
utf16
字符串
属性)。使用
UInt8
init(截断位模式:UInt16)
初始值设定项,结合
zip
,然后使用
flatMap
,后者将压缩的元组展平为一个数组:

let pw = "password€"

let bytes = zip(pw.utf16.map{ UInt8(truncatingBitPattern: $0) },
                pw.utf16.map{ UInt8(truncatingBitPattern: $0 >> 8) })
            .flatMap{ [$0, $1] }

print(bytes)
// [112, 0, 97, 0, 115, 0, 115, 0, 119, 0, 111, 0, 114, 0, 100, 0, 172, 32]

您可以使用

let password = "password€"
let data = password.data(using: .utf16LittleEndian)!
print(data as NSData)
// <70006100 73007300 77006f00 72006400 ac20>
但如果需要它作为字节数组,那么

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]
会有用的

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


如果您想知道如何将
[UInt16]
数组转换为
[UInt8]
array,这是通过一些指针杂耍来实现的 (只有一份副本):


您可以使用

let password = "password€"
let data = password.data(using: .utf16LittleEndian)!
print(data as NSData)
// <70006100 73007300 77006f00 72006400 ac20>
但如果需要它作为字节数组,那么

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]
会有用的

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


如果您想知道如何将
[UInt16]
数组转换为
[UInt8]
array,这是通过一些指针杂耍来实现的 (只有一份副本):

使用访问器怎么样

var bytes = str.cStringUsingEncoding(NSUTF16LittleEndianStringEncoding)
使用访问器怎么样

var bytes = str.cStringUsingEncoding(NSUTF16LittleEndianStringEncoding)

UTF-16数组的内容都是16位整数,因此您期望的0字节已经包含在每个值中。您已经通过插入这些额外的零(每个都是16位)更改了数据。UTF-16数组的内容都是16位整数,因此您期望的0字节已经包含在每个值中。你已经通过插入那些额外的零(每个都是16位)改变了数据。你太棒了!这正是我想要的。工作得很有魅力。谢谢你,你太棒了!这正是我想要的。工作得很有魅力。非常感谢。