Skip to content

Instantly share code, notes, and snippets.

@Sinkmanu
Created March 14, 2018 11:26
Show Gist options
  • Save Sinkmanu/777f101afe313a2fbec647d2bda9a25e to your computer and use it in GitHub Desktop.
Save Sinkmanu/777f101afe313a2fbec647d2bda9a25e to your computer and use it in GitHub Desktop.
S-record checksum calculator
#!/usr/bin/env python
# usage: $ ./srec-checksum.py <s-record without checksum>
import sys
cad = sys.argv[1]
i = 2
checksum = 0
while i<len(cad):
checksum = checksum + ord(cad[i:i+2].decode("hex"))
i+=2
if (cad[0:2] == "S1"):
out = "Data record, address 16 bits"
address = cad[4:8]
elif (cad[0:2] == "S2"):
out = "Data record, address 24 bits"
address = cad[4:10]
elif (cad[0:2] == "S3"):
out = "Data record, address 32 bits"
address = cad[4:12]
elif (cad[0:2] == "S9"):
out = "Termination record, address 16 bits"
address = cad[4:8]
elif (cad[0:2] == "S8"):
out = "Termination record, address 24 bits"
address = cad[4:10]
elif (cad[0:2] == "S9"):
out = "Termination record, address 32 bits"
address = cad[4:12]
elif (cad[0:2] == "S0"):
out = "Header record"
address = "0000"
print "[*] Record type: %s\taddress=0x%s"%(out, address)
print "[*] Checksum: %s\n[*] S-Record: %s"%(hex(checksum^0xff)[-2:].upper(), cad + hex(checksum^0xff)[-2:].upper())
@a-x-
Copy link

a-x- commented Feb 13, 2022

There is a bug here.

Must replace ^0xff with ^0xff & 0xff. Check 'FFFF' input

corrected simplified version:

def moto_checksum(data):
    i = 2
    checksum = 0
    while i<len(data):
        checksum = checksum + ord(data[i:i+2].decode("hex"))
        i+=2

    return hex(checksum^0xff&0xff)[-2:].upper()

js version:

function motoChecksum(data) {
    let i = 2
    let checksum = 0
    while (i < data.length) {
        checksum = checksum + parseInt(data.slice(i, i+2), 16)
        i+=2
    }

    return ((checksum^0xff)&0xff).toString(16).toUpperCase().padStart(2, '0')
}

@Machinegon
Copy link

This snippet for python3:

import sys

def moto_checksum(data):
    i = 2
    checksum = 0
    while i<len(data):
        checksum = checksum + int.from_bytes(bytes.fromhex(data[i:i+2]), byteorder="little")
        i+=2

    return hex(checksum^0xff&0xff)[-2:].upper()
    
checksum = moto_checksum(sys.argv[1])
print("Checksum: {0}\n".format(checksum))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment