Swift: байтовый массив до десятичного значения - PullRequest
0 голосов
/ 15 ноября 2018

В моем проекте я общаюсь с устройством Bluetooth, устройство Bluetooth должно отправить мне метку времени в секунду, полученную в байтах:

[2,6,239]

Когда я конвертирую, преобразую в строку:

let payloadString = payload.map {
            String(format: "%02x", $0)
        }

Выход:

["02", "06","ef"]

Когда я конвертировал с веб-сайта 0206ef = 132847 секунд

Как я могу напрямую преобразовать свой aray [2,6,239] в секунду (= 132847 секунд)? А если это сложно, тогда переведите мой массив ["02", "06,"ef"] в секунду (= 132847 секунд)

Ответы [ 2 ]

0 голосов
/ 15 ноября 2018

payloadString строка может быть уменьшена до hexStr и затем преобразована в десятичную

var payload = [2,6,239];
let payloadString = payload.map {
    String(format: "%02x", $0)
}

//let hexStr = payloadString.reduce(""){$0 + $1}
let hexStr = payloadString.joined()
if let value = UInt64(hexStr, radix: 16) {
    print(value)//132847
}
0 голосов
/ 15 ноября 2018

Полезная нагрузка содержит байты двоичного представления значения. Вы преобразовываете его обратно в значение, сдвигая каждый байт в соответствующую позицию:

let payload: [UInt8] = [2, 6, 239]
let value = Int(payload[0]) << 16 + Int(payload[1]) << 8 + Int(payload[2])
print(value) // 132847

Важным моментом является преобразование байтов в целые числа до сдвига , в противном случае возникнет ошибка переполнения. С другой стороны, с умножением:

let value = (Int(payload[0]) * 256 + Int(payload[1])) * 256 + Int(payload[2])

или

let value = payload.reduce(0) { $0 * 256 + Int($1) }

Последний подход работает с произвольным числом байтов - до тех пор, пока результат вписывается в Int. Для 4 ... 8 байтов лучше выбрать UInt64 чтобы избежать ошибок переполнения:

let value = payload.reduce(0) { $0 * 256 + UInt64($1) }
...