2

In my project, I communicate with a bluetooth device, the bluetooth device must send me a timestamp second, I received in byte:

[2,6,239]

When I convert converted to a string:

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

Output:

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

When I converted from the website 0206ef = 132847 seconds

How can I directly convert my aray [2,6,239] in second (= 132847 seconds)? And if it's complicated then translate my array ["02", "06,"ef"] in second (= 132847 seconds)

2 Answers 2

2

The payload contains the bytes of the binary representation of the value. You convert it back to the value by shifting each byte into its corresponding position:

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

The important point is to convert the bytes to integers before shifting, otherwise an overflow error would occur. Alternatively, with multiplication:

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

or

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

The last approach works with an arbitrary number of bytes – as long as the result fits into an Int. For 4...8 bytes you better choose UInt64 to avoid overflow errors:

let value = payload.reduce(0) { $0 * 256 + UInt64($1) }
Sign up to request clarification or add additional context in comments.

12 Comments

I do not understand why the shift is not always the same, you write once << 16, then, << 8, then for the last nothing why? Same with the multiplication why the last you do not multiply it?
It is possible that the device does not send me 3 byte but 4 so how should I do?
If the device sends me 4byte instead of 3 [2,3,6,222] the code remains the same?
@MickaelBelhassen: I added a version with works with a variable number of bytes.
The latest version is generic? for more bytes?
|
1

payloadString string can be reduced to hexStr and then converted to decimal

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
}

4 Comments

If the device sends me 4byte instead of 3 [2,3,6,222] the code remains the same?
yes code will remain same for 4byte or more. For [2,3,6,222] output will be 33752798 with same above code.
Note that payloadString.reduce(""){$0 + $1} can be simplified to payloadString.joined()
Correctly pointed, that's a better easier way. Updated answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.