NMEA Checksum Calculator

Validate and compute NMEA 0183 sentence checksums. Paste one or multiple sentences — get XOR result, match/mismatch status, and corrected sentences with one click.

NMEA Sentences

Common NMEA sentence types

Sentence IDDescriptionFields
GPRMCRecommended minimum navigation data12
GPGGAGlobal positioning fix data15
GPGLLGeographic position — latitude/longitude7
GPVTGTrack made good and ground speed9
GPZDATime and date (UTC, day, month, year)6
GPGSVSatellites in view (elevation, azimuth, SNR)4+4n

How it works

NMEA 0183 uses a simple XOR checksum over the sentence payload. The payload is everything between $ (exclusive) and * (exclusive). The result is formatted as two uppercase hex digits and appended after the *.

For $GPRMC,092751.000,A,5321.6802,N,00630.3371,W,0.06,31.66,280511,,,A*43:

payload = "GPRMC,092751.000,A,5321.6802,N,00630.3371,W,0.06,31.66,280511,,,A"
checksum = 'G' ^ 'P' ^ 'R' ^ 'M' ^ 'C' ^ ',' ^ ... = 0x43

The $ and * themselves are never included. Everything in between is — commas, decimal points, all of it.

C implementation

This is the entire algorithm. No library needed:

uint8_t nmea_checksum(const char *sentence) {
    uint8_t cksum = 0;
    /* skip leading $ if present */
    if (*sentence == '$') sentence++;
    while (*sentence && *sentence != '*') {
        cksum ^= (uint8_t)*sentence++;
    }
    return cksum;
}

To validate an incoming sentence:

bool nmea_valid(const char *sentence) {
    const char *star = strchr(sentence, '*');
    if (!star || strlen(star) < 3) return false;
    uint8_t expected = (uint8_t)strtol(star + 1, NULL, 16);
    return nmea_checksum(sentence) == expected;
}

Parsing rules

  • Sentences start with $, end with *HH where HH is the two-hex-digit checksum, followed by \r\n.
  • Some talkers (proprietary sentences) use $P as prefix — checksum algorithm is identical.
  • The checksum field is optional in NMEA 0183 v1.5 but mandatory in v2.0+. In practice, all modern GPS modules include it.
  • The maximum sentence length is 82 characters including $ and \r\n.

Common mistakes

Including $ or * in the XOR. The checksum covers only the data between them. This is the most common off-by-one.

Case sensitivity. The hex checksum must be uppercase (*4B not *4b). Most parsers accept lowercase anyway, but the spec says uppercase.

CRLF vs LF. NMEA 0183 specifies \r\n. If your UART strips the \r, that’s fine — the checksum is computed before the line terminator.

Multi-sentence batches. If your parser buffers incoming data and processes line-by-line, ensure the \r doesn’t end up in the sentence string before you compute the checksum.

PUBX sentences. u-blox uses $PUBX for proprietary messages. Same checksum algorithm, but the parser must not confuse PUBX with standard talker+sentence-ID format.

Firmware considerations

For interrupt-driven UART with a DMA ring buffer, compute the checksum incrementally as bytes arrive — don’t wait for the full sentence. Start XORing from the first byte after $, stop when you see *, then compare the next two hex bytes to your running XOR. This avoids storing the entire sentence and works within tight RAM budgets on Cortex-M0 targets.