Swift 2.1 [UInt8] --utf8--> 字符串?
Swift 2.1 [UInt8] --utf8--> String?
我知道 Stack Overflow 和其他地方都存在这样的问题。但它似乎也进化了很多。
给定 UInt8
列表(基本上是 swift 字节数组),easiest/idiomatic 将其转换为 swift String
的方法是什么?
我对不使用NSData/NSString的方法特别感兴趣,因为如果圣诞老人将Swift带到Linux的世界,那无疑是没有NS的图书馆,我想知道如何在 Swift.
内完成
Xcode 8 • Swift 3
extension Collection where Iterator.Element == UInt8 {
var bytes: [UInt8] { return Array(self) }
var data: Data { return Data(self) }
var string: String? { return String(data: data, encoding: .utf8) }
}
extension String {
var data: Data { return Data(utf8) }
}
用法:
let sentence = "Hello World"
let utf8View = sentence.utf8
let bytes = utf8View.bytes // [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]
let data1 = sentence.data
print(data1 as NSData) // <48656c6c 6f20576f 726c64>
let data2 = utf8View.data
let data3 = bytes.data
let string1 = utf8View.string // "Hello World"
let string2 = bytes.string // "Hello World"
let string3 = data1.string // "Hello World"
let buffUInt8: Array<UInt8> = [97, 98, 115, 100, 114, 102, 103, 104, 0]
// you need Int8 array
let buffInt8 = buffUInt8.map{ Int8(bitPattern: [=10=])}
let str = String.fromCString(buffInt8) // "absdrfgh"
或者您可以使用
String.fromCStringRepairingIllFormedUTF8(cs: UnsafePointer<CChar>) -> (String?, hadError: Bool)
我实际上最终需要为 UInt8
的流执行此操作并且很好奇 utf8 解码有多难。肯定不是单行,而是通过下面直接实现在一起:
import UIKit
let bytes:[UInt8] = [0xE2, 0x82, 0xEC, 0x00]
var g = bytes.generate()
extension String {
init(var utf8stream:IndexingGenerator<[UInt8]>) {
var result = ""
var codepoint:UInt32 = 0
while let byte = utf8stream.next() where byte != 0x00 {
codepoint = UInt32(byte)
var extraBytes = 0
if byte & 0b11100000 == 0b11000000 {
extraBytes = 1
codepoint &= 0b00011111
}
else if byte & 0b11110000 == 0b11100000 {
extraBytes = 2
codepoint &= 0b00001111
}
else if byte & 0b11111000 == 0b11110000 {
extraBytes = 3
codepoint &= 0b00000111
}
else if byte & 0b11111100 == 0b11111000 {
extraBytes = 4
codepoint &= 0b00000011
}
else if byte & 0b11111110 == 0b11111100 {
extraBytes = 5
codepoint &= 0b00000001
}
for _ in 0..<extraBytes {
if let additionalByte = utf8stream.next() {
codepoint <<= 6
codepoint |= UInt32(additionalByte & 0b00111111)
}
}
result.append(UnicodeScalar(codepoint))
}
self = result
}
}
String(utf8stream: g)
我知道 Stack Overflow 和其他地方都存在这样的问题。但它似乎也进化了很多。
给定 UInt8
列表(基本上是 swift 字节数组),easiest/idiomatic 将其转换为 swift String
的方法是什么?
我对不使用NSData/NSString的方法特别感兴趣,因为如果圣诞老人将Swift带到Linux的世界,那无疑是没有NS的图书馆,我想知道如何在 Swift.
内完成Xcode 8 • Swift 3
extension Collection where Iterator.Element == UInt8 {
var bytes: [UInt8] { return Array(self) }
var data: Data { return Data(self) }
var string: String? { return String(data: data, encoding: .utf8) }
}
extension String {
var data: Data { return Data(utf8) }
}
用法:
let sentence = "Hello World"
let utf8View = sentence.utf8
let bytes = utf8View.bytes // [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]
let data1 = sentence.data
print(data1 as NSData) // <48656c6c 6f20576f 726c64>
let data2 = utf8View.data
let data3 = bytes.data
let string1 = utf8View.string // "Hello World"
let string2 = bytes.string // "Hello World"
let string3 = data1.string // "Hello World"
let buffUInt8: Array<UInt8> = [97, 98, 115, 100, 114, 102, 103, 104, 0]
// you need Int8 array
let buffInt8 = buffUInt8.map{ Int8(bitPattern: [=10=])}
let str = String.fromCString(buffInt8) // "absdrfgh"
或者您可以使用
String.fromCStringRepairingIllFormedUTF8(cs: UnsafePointer<CChar>) -> (String?, hadError: Bool)
我实际上最终需要为 UInt8
的流执行此操作并且很好奇 utf8 解码有多难。肯定不是单行,而是通过下面直接实现在一起:
import UIKit
let bytes:[UInt8] = [0xE2, 0x82, 0xEC, 0x00]
var g = bytes.generate()
extension String {
init(var utf8stream:IndexingGenerator<[UInt8]>) {
var result = ""
var codepoint:UInt32 = 0
while let byte = utf8stream.next() where byte != 0x00 {
codepoint = UInt32(byte)
var extraBytes = 0
if byte & 0b11100000 == 0b11000000 {
extraBytes = 1
codepoint &= 0b00011111
}
else if byte & 0b11110000 == 0b11100000 {
extraBytes = 2
codepoint &= 0b00001111
}
else if byte & 0b11111000 == 0b11110000 {
extraBytes = 3
codepoint &= 0b00000111
}
else if byte & 0b11111100 == 0b11111000 {
extraBytes = 4
codepoint &= 0b00000011
}
else if byte & 0b11111110 == 0b11111100 {
extraBytes = 5
codepoint &= 0b00000001
}
for _ in 0..<extraBytes {
if let additionalByte = utf8stream.next() {
codepoint <<= 6
codepoint |= UInt32(additionalByte & 0b00111111)
}
}
result.append(UnicodeScalar(codepoint))
}
self = result
}
}
String(utf8stream: g)