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

时间:2015-04-15 07:22:41

标签: arrays swift

我在将UInt8 Byte数组转换为swift中的字符串时遇到问题。我已经搜索并找到了一个简单的解决方案

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)

13 个答案:

答案 0 :(得分:62)

更新 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")
}

更新 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")
}

答案 1 :(得分:9)

这对我有用:

String(bytes: bytes, encoding: NSUTF8StringEncoding)

答案 2 :(得分:8)

Swifty解决方案

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

十六进制表示:

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

答案 3 :(得分:5)

此解决方案有效。

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

答案 4 :(得分:4)

<{3}}中的Martin R回答了Sunil Kumar关于他的问题,但没有回答主题问题。 如果您已经拥有UInt8字节数组并且需要将其显示为字符串,则仍会出现此问题。

这是我的解决方案:

TextView t2 = (TextView) findViewById(R.id.text);
t2.setMovementMethod(LinkMovementMethod.getInstance());

使用此扩展,您现在可以使用UInt8字节数组初始化String:

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

这不是理想的解决方案,因为实际上您需要解码类似UTF-8编码的文本。但对于ASCII数据,这可以按预期工作。

答案 5 :(得分:4)

Swift 3

以下因为&#34; NSUTF8StringEncoding&#34;而给我一个错误:

String(data: nsdata, encoding: NSUTF8StringEncoding)! 

这在swift 3中对我有用:

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

答案 6 :(得分:4)

Swift 5.2.2的更新:

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

答案 7 :(得分:2)

不是很优雅或者很快,但这很简单并且有效:

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

在我突然想到&#39; printf&#39;之前,我浪费了几个小时寻找一种简单的方法。从我的Unix脚本日开始!

答案 8 :(得分:2)

这是一些更通用的代码,用于从字节数组中提取字符串,其中字符串已经以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),我用它来处理序列化数据。

答案 9 :(得分:2)

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

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)"
        }
    }
}

答案 10 :(得分:1)

“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))

答案 11 :(得分:0)

首先需要将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)

答案 12 :(得分:0)

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")