Быстрое преобразование байтового массива в целые числа

Здравствуйте, я новичок в swift и хотел бы преобразовать байтовый массив в несколько целых чисел. Я написал рабочий код на Java, но я не совсем уверен, как использовать его для быстрого

byte[] codeData = Base64.decode(codeDataBase64, 0);
    ByteArrayInputStream bais = new ByteArrayInputStream(codeData);
    DataInputStream dis = new DataInputStream(bais);

    byte version = dis.readByte();
    if (version == 1) {
        int anID = dis.readInt();
        int anotherID = dis.readInt();
        byte[] TK = new byte[512];
        int readTK = dis.read(TK);
        if (readTK == TK.length) {
            Log.e("photoConnect success", "anID=" + anID + ", anotherID=" + anotherID + ", TK.length=" + TK.length);

Вот что я имею в Swift до сих пор:

func base64ToByteArray(base64String: String) -> [UInt8]? {
    if let nsdata = NSData(base64Encoded: base64String) {
        var bytes = [UInt8](repeating: 0, count: nsdata.length)
        nsdata.getBytes(&bytes, length: nsdata.length)
        return bytes
    }
    return nil // Invalid input
}

Эта функция переносит его в массив байтов, но я не уверен, какой класс Swift использовать для имитации поведения DataInputStream в Java.

1 ответ

Решение

Хорошо, у меня есть рабочее решение. Большое спасибо Martin R за показ поста, который он связал выше ( идиоматический метод анализа потоков данных swift(3))

Я в основном взял класс из поста, связанного с Martin R, и изменил его, чтобы использовать объект NSData вместо объекта Data: class DataStream {let data: NSData var index = 0 var atEnd: Bool {return index> = self.data.length }

init(data:NSData) {
    self.data = data
}

func next() -> UInt8? {
    guard !self.atEnd else { return nil }
    let byte = self.data.subdata(with: NSRange(location: self.index, length: 1))[0]
    self.index += 1
    return byte
}

func next(_ count:Int) -> NSData? {
    guard self.index + count <= self.data.length else { return nil }
    let subdata = self.data.subdata(with: NSRange(location: self.index, length: count))
    self.index += count
    return subdata as NSData?
}

func upTo(_ marker:UInt8) -> NSData? {
    if let end = (self.index..<self.data.length).index( where: { self.data.base64EncodedData()[$0] == marker } ) {
        let upTo = self.next(end - self.index)
        self.skip() // consume the marker
        return upTo
    }
    else {
        return nil
    }
}

func skip(_ count:Int = 1) {
    self.index += count
}

func skipThrough(_ marker:UInt8) {
    if let end = (self.index..<self.data.length).index( where: { self.data.base64EncodedData()[$0] == marker } ) {
        self.index = end + 1
    }
    else {
        self.index = self.data.length
    }
}

}

Используя этот класс DataStream вместе с парой методов NSData, я смог имитировать поведение java-метода DataInputStream.ReadInt():

var someID : Int = 0
        //get the part of the data that represents someID
        guard let someIDData = dataStream.next(4 /*size of someID in the data*/) else { fatalError("Error getting someID bytes")}
        //convert the data bytes to an Int
        someIDData.getBytes(&someID, length: someIDData.length)

Если у кого-то есть лучший способ сделать это, я хотел бы услышать! Я новичок в Swift, так что это может быть не лучшим способом. Это работает с Swift 3.1.

Другие вопросы по тегам