繁体   English   中英

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM