2

I have a process that computes and checks the checksum in AIS messages, the checksum is the xor of all the bytes in the message expressed in hexadecimal format. At the moment I am turning both the calculated and included checksums into strings and comparing them, which seems a bit compute heavy. Is there a better way to compare the single byte calculation with its 2 byte hexadecimal representation? bytdata is the AIS message in a []byte{}.

j := i + 1
for ; j < leng ; j++ {
    checkSum ^= (int)(bytdata[j])
}

checkBytes := fmt.Sprintf("%02X", checkSum)
if checkBytes == string(bytdata[(j+1):(j+3)]) {
    // valid checksum......
    etc
}
0

3 Answers 3

2

AIS checksum is one byte encoded as two ASCII hex character. you can parse these two and compare them directly instead of fmt.Sprintf:

import (
    "encoding/hex"
)

j := i + 1
checkSum := 0
for ; j < leng; j++ {
    checkSum ^= int(bytdata[j])
}

bytes := bytdata[j+1 : j+3]
msgCs, err := hex.DecodeString(string(bytes))
if err != nil || len(msgCs) != 1 {
    return
}

if byte(checkSum) == msgCs[0] {}
Sign up to request clarification or add additional context in comments.

1 Comment

2

It follows from the code in the question: fmt.Sprintf("%02X", checkSum) that the checksum is written in uppercase. Here is the fastest way to check the checksum without any string conversions:

const hexDigits = "0123456789ABCDEF"

// ...

var checkSum byte = 0
for ; j < leng; j++ {
    checkSum ^= bytdata[j]
}

if hexDigits[checkSum >>  4] == bytdata[j + 1] &&
   hexDigits[checkSum & 0xF] == bytdata[j + 2] {
    // valid checksum......
}

Comments

-1

Thanks for the suggestions, this also avoids any string conversions and doesn't use the hex lookup table.

    dcode := make([]byte, 1)
...
            checkSum = 0
            for j = i+1 ; j < leng ; j++ {
                checkSum ^= (int)(bytdata[j])
            }
            _, err := hex.Decode(dcode, bytdata[(j+1):(j+3)])
            if err == nil && (int)(dcode[0]) == checkSum {
                // valid checksum, will it fit in one packet
...

1 Comment

if err == nil && (int)(hsum[0]) == checkSum -> if err == nil && (int)(dcode[0]) == checkSum ?

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.