[英]How to convert UInt8 byte array to string in Swift
我在快速将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)
Swift 3/Xcode 8更新:
来自bytes: [UInt8]
字符串bytes: [UInt8]
:
if let string = String(bytes: bytes, encoding: .utf8) {
print(string)
} else {
print("not a valid UTF-8 sequence")
}
来自data: Data
字符串data: Data
:
let data: Data = ...
if let string = String(data: data, encoding: .utf8) {
print(string)
} else {
print("not a valid UTF-8 sequence")
}
Swift 2/Xcode 7更新:
来自bytes: [UInt8]
字符串bytes: [UInt8]
:
if let string = String(bytes: bytes, encoding: NSUTF8StringEncoding) {
print(string)
} else {
print("not a valid UTF-8 sequence")
}
来自data: NSData
字符串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")
}
快捷的解决方案
array.reduce("", combine: { $0 + String(format: "%c", $1)})
十六进制表示:
array.reduce("", combine: { $0 + String(format: "%02x", $1)})
这对我有用:
String(bytes: bytes, encoding: NSUTF8StringEncoding)
Swift 5.2.2 更新:
String(decoding: yourByteArray, as: UTF8.self)
此解决方案有效。
NSString(bytes: data!, length: data!.count, encoding: NSUTF8StringEncoding)
斯威夫特 3
由于“NSUTF8StringEncoding”,以下给了我一个错误:
String(data: nsdata, encoding: NSUTF8StringEncoding)!
这在 swift 3 中对我有用:
let xmlStr:String = String(bytes: data!, encoding: String.Encoding.utf8)!
对于无法将字节数组转换为字符串的任何人,请尝试此操作
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)"
}
}
}
https://stackoverflow.com/a/29644387/2214832 中的Martin R 回答了 Sunil Kumar 的问题,但没有回答主题问题。 如果您已经有 UInt8 字节数组并且需要将其显示为字符串,则问题仍然存在。
这是我的解决方案:
extension String {
init(_ bytes: [UInt8]) {
self.init()
for b in bytes {
self.append(UnicodeScalar(b))
}
}
}
使用此扩展,您现在可以使用 UInt8 字节数组初始化字符串,如下所示:
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 数据,这按预期工作。
这是一些更通用的代码,用于从字节数组中提取字符串,其中字符串已以 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 )。
不是很优雅或“Swifty”,但这很简单并且有效:
let i: UInt8 = 65
let s = String(format: "%c", i) // A
在我突然想到 Unix 脚本时代的“printf”之前,我浪费了几个小时寻找一种简单的方法来做到这一点!
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'
“MSString(bytes: , length: , encoding: )”截至 2015 年 7 月 26 日似乎不起作用
将字节值转换为 ASCII 似乎有问题,如果你碰壁了,你可以按如下方式进行(也许我在 swift 中遗漏了一些东西,但我在我的时间范围内找不到任何解决方案。)这将完成两个功能。 第一个函数接受一个 UInt8 并将其转换为“\\u{}”表示,然后由函数返回。 其次,设置另一个函数,它接受一个 UInt8 数组作为参数,然后输出一个字符串。
第1步。 函数将每个字节转换为“\\u{someNumber}”
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
}
这应该适用于 Swift Playground 制作一个数组
var myArray : [UInt8] = [0x30, 0x3A, 0x4B]
//然后应用上面的函数
println(UInt8ArrayToString(UInt8Array: myArray))
斯威夫特 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")
您需要先将 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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.