如何在 Swift 中将 UInt8字节数组转换为字符串

我面临的问题,而转换 UInt8字节数组字符串在迅速。我已经找到了一个简单的解决办法

String.stringWithBytes(buff, encoding: NSUTF8StringEncoding)

但它显示错误 String.type没有一个成员 stringWithBytes。谁能给我一个解决方案?

这是我的代码,我得到了一个 NSData并转换成字节数组,然后我必须转换成字节数组字符串。

let count = data.length / sizeof(UInt8)
var array = [UInt8](count: count, repeatedValue: 0)
data.getBytes(&array, length:count * sizeof(UInt8))
String.stringWithBytes(buff, encoding: NSUTF8StringEncoding)
110960 次浏览

更新 < strong > Swift 3/Xcode 8:

来自 bytes: [UInt8]的字符串:

if let string = String(bytes: bytes, encoding: .utf8) {
print(string)
} else {
print("not a valid UTF-8 sequence")
}

来自 data: Data的字符串:

let data: Data = ...
if let string = String(data: data, encoding: .utf8) {
print(string)
} else {
print("not a valid UTF-8 sequence")
}

更新 < strong > Swift 2/Xcode 7:

来自 bytes: [UInt8]的字符串:

if let string = String(bytes: bytes, encoding: NSUTF8StringEncoding) {
print(string)
} else {
print("not a valid UTF-8 sequence")
}

来自 data: NSData的字符串:

let data: NSData = ...
if let str = String(data: data, encoding: NSUTF8StringEncoding) {
print(str)
} else {
print("not a valid UTF-8 sequence")
}

回答:

String没有 stringWithBytes()方法。 NSString有一个

 NSString(bytes: , length: , encoding: )

方法,但是您可以直接从 NSData创建字符串,而不需要 UInt8数组:

if let str = NSString(data: data, encoding: NSUTF8StringEncoding) as? String {
println(str)
} else {
println("not a valid UTF-8 sequence")
}

截至2015年7月26日,“ MSString (byte: ,length: ,coding:)”似乎无法正常工作

把字节值转换成 ASCII 似乎有问题,如果你碰壁了,你可以按照下面的方法来做(也许我遗漏了一些快速的东西,但是我在我的时间范围内找不到任何解决方案)这将通过两个函数来完成。第一个函数接受 UInt8并将其转换为“ u {}”表示形式,然后由该函数返回。其次,建立另一个函数,该函数接受 UInt8数组作为参数,然后输出一个字符串。

函数将每个字节转换为“ u { some Number }”

func convertToCharacters(#UInt8Bits : UInt8) -> String {

 var characterToReturn : String


switch UInt8Bits{


case 0x00: characterToReturn = "\u{0}"
case 0x01: characterToReturn = "\u{1}"
case 0x02: characterToReturn = "\u{2}"
case 0x03: characterToReturn = "\u{3}"
case 0x04: characterToReturn = "\u{4}"

//. . 按照您的预期添加尽可能多的字符... 不要忘记以16为基数. 。

case 0x09: characterToReturn = "\u{09}"
case 0x0A: characterToReturn = "\u{0A}"


default: characterToReturn = "\u{0}"

/* . . 一直到0xff */

case 0xFE: characterToReturn = "\u{FE}"
case 0xFF: characterToReturn = "\u{FF}"






}

return characterToReturn

}

步骤 # 2... 接下来一个函数接受一个 UInt8数组作为参数,然后返回一个字符串..。

func UInt8ArrayToString(#UInt8Array: [UInt8]) -> String {

var returnString : String = "" for eachUInt8Byte in UInt8Array {

returnString += convertToCharacter(UInt8Bits: eachUInt8Byte)

}

return returnString }

这应该可以在斯威夫特游乐场使用 建立一个数组

Var myArray: [ UInt8] = [0x30,0x3A,0x4B ]

//然后应用上面的函数

Println (UInt8ArrayToString (UInt8Array: myArray))

这个办法行得通。

NSString(bytes: data!, length: data!.count, encoding: NSUTF8StringEncoding)

不是非常优雅或“迅捷”,但这很简单,而且很有效:

let i: UInt8 = 65
let s = String(format: "%c", i)  // A

在我突然想到 Unix 脚本时代的‘ printf’之前,我浪费了几个小时寻找一种简单的方法来做这件事!

这对我很有效:

String(bytes: bytes, encoding: NSUTF8StringEncoding)

马丁 R 在 https://stackoverflow.com/a/29644387/2214832回答苏尼尔库马尔的问题,但没有在主题的问题。 如果您已经有了 UInt8字节数组并且需要将它表示为字符串,那么问题仍然会出现。

我的解决办法是:

extension String {
init(_ bytes: [UInt8]) {
self.init()
for b in bytes {
self.append(UnicodeScalar(b))
}
}
}

使用这个扩展,您现在可以像下面这样用 UInt8字节数组初始化 String:

func testStringUInt8Extension() {
var cs : [UInt8] = []
for char : UInt8 in 0..<255 {
cs.append(char)
}
print("0..255 string looks like \(String(cs)))")
}

这不是理想的解决方案,因为实际上您需要解码类似 UTF-8编码的文本。但是对于 ASCII 数据来说,这就像预期的那样。

快速解决方案

array.reduce("", combine: { $0 + String(format: "%c", $1)})

十六进制表示法:

array.reduce("", combine: { $0 + String(format: "%02x", $1)})

Swift 2 & 3的完整例子:

import Foundation


let bytes : [UInt8] = [72, 73]
let nsdata = NSData(bytes: bytes as [UInt8], length: 2)
let str = String(data: nsdata, encoding: NSUTF8StringEncoding)! // 'HI'

Swift 3

因为“ NSUTF8StringEncoding”,下面的代码给了我一个错误:

String(data: nsdata, encoding: NSUTF8StringEncoding)!

在《快速反应3》中,这招对我很管用:

let xmlStr:String = String(bytes: data!, encoding: String.Encoding.utf8)!

下面是一些更通用的代码,用于从字节数组中提取字符串,其中字符串是用 UTF-8编码的。

/// Class which encapsulates a Swift byte array (an Array object with elements of type UInt8) and an
/// index into the array.
open class ByteArrayAndIndex {


private var _byteArray : [UInt8]
private var _arrayIndex = 0


public init(_ byteArray : [UInt8]) {
_byteArray = byteArray;
}


/// Method to get a UTF-8 encoded string preceded by a 1-byte length.
public func getShortString() -> String {
return getTextData(getUInt8AsInt())
}


/// Method to get a UTF-8 encoded string preceded by a 2-byte length.
public func getMediumString() -> String {
return getTextData(getUInt16AsInt())
}


/// Method to get a UTF-8 encoded string preceded by a 4-byte length. By convention a length of
/// -1 is used to signal a String? value of nil.
public func getLongString() -> String? {
let encodedLength = getInt32()
if encodedLength == -1 {
return nil
}
return getTextData(Int(encodedLength))
}


/// Method to get a single byte from the byte array, returning it as an Int.
public func getUInt8AsInt() -> Int {
return Int(getUInt8())
}


/// Method to get a single byte from the byte array.
public func getUInt8() -> UInt8 {
let returnValue = _byteArray[_arrayIndex]
_arrayIndex += 1
return returnValue
}


/// Method to get a UInt16 from two bytes in the byte array (little-endian), returning it as Int.
public func getUInt16AsInt() -> Int {
return Int(getUInt16())
}


/// Method to get a UInt16 from two bytes in the byte array (little-endian).
public func getUInt16() -> UInt16 {
let returnValue = UInt16(_byteArray[_arrayIndex]) |
UInt16(_byteArray[_arrayIndex + 1]) << 8
_arrayIndex += 2
return returnValue
}


/// Method to get an Int32 from four bytes in the byte array (little-endian).
public func getInt32() -> Int32 {
return Int32(bitPattern: getUInt32())
}


/// Method to get a UInt32 from four bytes in the byte array (little-endian).
public func getUInt32() -> UInt32 {
let returnValue = UInt32(_byteArray[_arrayIndex]) |
UInt32(_byteArray[_arrayIndex + 1]) << 8 |
UInt32(_byteArray[_arrayIndex + 2]) << 16 |
UInt32(_byteArray[_arrayIndex + 3]) << 24
_arrayIndex += 4
return returnValue
}


// Method to decode UTF-8 encoded text data in the byte array.
private func getTextData(_ numberBytes : Int) -> String {
if numberBytes == 0 {
return ""  // Tiny optimization?
}
let startIndex = _arrayIndex
_arrayIndex += numberBytes
return String(bytes: _byteArray[startIndex ..< _arrayIndex], encoding: String.Encoding.utf8)!
}
}

这是从一个较大的类(也参见 https://stackoverflow.com/a/41547936/253938)中提取出来的,我用它来处理序列化数据。

首先需要将 Int8数组转换为 Data,然后再转换为 String。

这是我的解决办法:

    var buffer = [Int8](repeating: 0, count: 100)
let data = Data(bytes: buffer as [Int8], count: buffer.count);
return String( data: data, encoding: .utf8)

Swift 4/Ubuntu 16.04

let serverAns = [UInt8](repeating: 0x50, count: 100)
let readBytes = 8
let truncatedServerAns = serverAns[0..<readBytes]
let tsaData = Data(bytes: truncatedServerAns)
let serverIdStr = String(data: tsaData, encoding: .utf8)
print("serverIdStr=\(String( describing: serverIdStr))")


// Prints:
// serverIdStr=Optional("PPPPPPPP")

对于无法将字节数组转换为字符串的任何人,请尝试这样做

String(data: Data(decrypted), encoding: .utf8)

这是我的示例字符串扩展,我用它来做 AES

extension String {


func decryptAES(key: String, iv: String) -> String {
do {
let encrypted = self
let key = Array(key.utf8)
let iv = Array(iv.utf8)
let aes = try AES(key: key, blockMode: CTR(iv: iv), padding: .noPadding)
let decrypted = try aes.decrypt(Array(hex: encrypted))
return String(data: Data(decrypted), encoding: .utf8) ?? ""
} catch {
return "Error: \(error)"
}
}
}

Swift 5.2.2的更新:

String(decoding: yourByteArray, as: UTF8.self)