C. K.
C. K.

Reputation: 71

Convert parts of [UInt8] into UInt8

I am writing an app for my bachelor-project in electrical engineering and I am working with a byte array which represents a hexadecimal string. The received byte array looks like this:

| sync | cmd | length | msg | msg | msg | MSB | LSB |

My question is how can I get the all the "msg"s out of the byte array and make them into a number? The "length" byte in [2] describes how many of the "msg"s there will be so I wanna use this to calculate the number of array indexes to make into a number.

var receivedBytes: [UInt8] = []
func serialDidReceiveBytes(_ bytes: [UInt8]) {
    receivedBytes = bytes
print(receivedBytes)
}

[204, 74, 3, 0, 97, 168, 209, 239]

I want this to become:

var: [UInt8] = [0, 97, 168]

Make it hecadecimal like:

[0x00,0x61,0xA8]

Then make this number into 0x61A8 or decimal 25000.

Upvotes: 0

Views: 427

Answers (1)

ielyamani
ielyamani

Reputation: 18591

Given an array :

let bytes: [UInt8] = [204, 74, 3, 0, 97, 168, 209, 239]

let's get the length of the message:

let length = Int(bytes[2])

msg is the variable that will store the result:

var msg = 0

index will point to the indexes of the octets of the whole message, from the LSB (higher index in bytes), to the MSB (lower index in bytes)

var index = bytes.count - 3

power is the power with which we'll be shifting the octets

var power = 1

Then we calculate the message this way :

while index > 2 {
    msg += Int(bytes[index]) * power
    power = power << 8
    index -= 1
}

The result is :

print(msg)  //25000

Or as @JoshCaswell suggests :

var msg: UInt64 = 0
var index = 3
while index < bytes.count - 2 {
    msg <<= 8 //msg = msg << 8
    msg += UInt64(bytes[index])
    index += 1
}

In both solutions, we suppose that the message can fit into an Int or UInt64

Upvotes: 1

Related Questions