Я сталкиваются с проблемами во время преобразования тип uint8` байтовый массив для строки в Swift. Я искал и нашел простое решение
String.stringWithBytes(buff, encoding: NSUTF8StringEncoding)
но это показывает строку ошибки.типа
не является членом 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)
Обновление для Свифт 3/Xcode версии 8:
Строку из байтов: [тип uint8]`:
if let string = String(bytes: bytes, encoding: .utf8) {
print(string)
} else {
print("not a valid UTF-8 sequence")
}
Строки из данные
:
let data: Data = ...
if let string = String(data: data, encoding: .utf8) {
print(string)
} else {
print("not a valid UTF-8 sequence")
}
Обновление для Свифт 2/Xcode версии 7:
Строку из байтов: [тип uint8]`:
if let string = String(bytes: bytes, encoding: NSUTF8StringEncoding) {
print(string)
} else {
print("not a valid UTF-8 sequence")
}
Строку из данных: формат NSData`:
let data: NSData = ...
if let str = String(data: data, encoding: NSUTF8StringEncoding) {
print(str)
} else {
print("not a valid UTF-8 sequence")
}
Предыдущий ответ:
Строка
нет 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")
}
Для тех, кто не может преобразовать массив байтов в строку, попробуйте это
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 ответил Сунил Кумар на свою проблему, но не по теме вопрос. Проблема все еще появляется, если у вас уже есть массив байтов тип 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 это работает, как ожидалось.
Свифт 3
следующие дает мне ошибку, потому что и"NSUTF8StringEncoding и":
String(data: nsdata, encoding: NSUTF8StringEncoding)!
это работало для меня в Swift 3:
let xmlStr:String = String(bytes: data!, encoding: String.Encoding.utf8)!
Полный пример для 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'
Не очень элегантный или 'Торопыжка', но это просто и это работает:
let i: UInt8 = 65
let s = String(format: "%c", i) // A
Я потратил часы, пытаясь найти простой способ сделать это, прежде чем я вдруг вспомнил о 'е' из моего в Unix скриптов дней!
Вот некоторые более обобщенного кода для извлечения строк из байтового массива, где эти строки были закодированы в 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 ), который я использую для обработки сериализованных данных.
"в MSString я(в байтах: , длина: , кодирование: )&; не представляется работа по состоянию на 26 июля 2015 года
Преобразование байтовых значений в ASCII представляется проблематичным, если вы попали в стену вы можете сделать это следующим образом (и, возможно, я упускаю что-то со Свифтом, но я не мог'т найти любые решения в мое срок.) Это будет сделано с двумя функциями. Первая функция принимает тип uint8 и преобразует их в " и\у{}" и представление, которое возвращается функцией. Во-вторых, другая функция настройки, которая принимает массив в качестве параметра тип uint8, а затем выводит строку.
Шаг #1. Функция преобразования каждого байта, чтобы " quot и; и\U{someNumber};
Функ convertToCharacters (UInt8Bits#: тип uint8) -> строка {
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}"
}
возвращение characterToReturn
}
Шаг #2 ...следующая функция, которая принимает массив тип uint8, а затем параметр возвращает строку...
Функ UInt8ArrayToString(#UInt8Array: [тип uint8]) -> строка {
returnString ВАР : строка = " и"
в
для eachUInt8Byte в UInt8Array {`
returnString += convertToCharacter(UInt8Bits: eachUInt8Byte)
}
возвращение returnString
}
Это должно работать в быстром площадка Сделать массив
ВАР с myarray : [тип uint8] = [0x30, 0x3A, 0x4B]
//Затем применить вышеуказанные функции
метод println(UInt8ArrayToString(UInt8Array: с myarray))
Вам нужно преобразовать массив Int8 данным, во-первых, затем преобразовать в строку.
Это мое решение:
var buffer = [Int8](repeating: 0, count: 100)
let data = Data(bytes: buffer as [Int8], count: buffer.count);
return String( data: data, encoding: .utf8)
Свифт 4 / Убунту 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")