Lefebure.com / Articles / NovAtel 32-Bit CRC in Java


What is NovAtel CRC?
When ASCII messages are transmitted from a NovAtel GNSS receiver, the message is followed by 8 hex characters representing a 32-bit CRC of the message. This allows you to verify that data was not changed or corrupted while being transmitted. The official NovAtel 32-Bit CRC documentation include sample source code in C. I needed to do this same CRC calculation in Java (Android). Java doesn't have unsigned types, so some modifications were needed to adapt the code, particularly the bitwise operations.


Example Java code:
    String line = "#HEADINGA,COM1,0,66.5,FINESTEERING,1844,505873.200,00040020,22a9,13306;
                   SOL_COMPUTED,NARROW_INT,12.801044464,160.432525635,-0.015716553,0.0,0.018702479,0.029530477,
                   \"G097\",18,16,16,16,00,01,00,33*c9cd21f6";


    if (line.lastIndexOf("*") + 9 == line.length()) {
        String CRC = line.substring(line.lastIndexOf("*") + 1); //Get just the CRC
        String lineData = line.substring(0, line.lastIndexOf("*")); //Remove everything after the *
        if (lineData.lastIndexOf("#") > -1) { // There is a #
            lineData = lineData.substring(lineData.lastIndexOf("#") + 1); //Remove everything before the #
            if (lineData.length() > 8) { // There are still at least 9 characters
                if (Calculate32bitCRC(lineData).equals(CRC)) {
                    if (lineData.startsWith("HEADINGA")) {
                        ParseHEADINGA(lineData);
                    }
                }
            }
        }
    }


    private int CRC32Value(int i) {
        int Value = i;
        for (int x = 8; x > 0; x--) {
            if ((Value & 1) == 1) {
                Value = (Value >>> 1) ^ 0xEDB88320;
            } else {
                Value >>>= 1;
            }
        }
        return Value;
    }
    private String Calculate32bitCRC(String line) {
        int Temp1;
        int Temp2;
        int CRC = 0;
        for (int x = 0; x < line.length(); x++) {
            Temp1 = (CRC >>> 8) & 0x00FFFFFF;
            Temp2 = CRC32Value((CRC ^ line.charAt(x)) & 0xFF);
            CRC = Temp1 ^ Temp2;
        }
        return String.format("%08x", CRC);
    }



Last updated: January 30, 2021

© 2021 Lefebure.com