Skip to content

Instantly share code, notes, and snippets.

@eaydin
Last active May 21, 2021 21:21
Show Gist options
  • Save eaydin/768a200c5d68b9bc66e7 to your computer and use it in GitHub Desktop.
Save eaydin/768a200c5d68b9bc66e7 to your computer and use it in GitHub Desktop.
CRC8 Maxim/Dallas for Python
############################################
# This is for CRC-8 Maxim/Dallas Algorithm
# Improved with less variable and functions
# Supports both Python3.x and Python2.x
# Has append and check functions
# When standalone, can read from either arguments or stdin
# Writes to stdout cleaner
# http://gist.github.com/eaydin
############################################
import binascii
import sys
if sys.version_info[0] == 3:
import codecs
def calc(incoming):
# convert to bytearray
if sys.version_info[0] == 3:
hex_data = codecs.decode(incoming, "hex_codec")
else:
hex_data = incoming.decode("hex")
msg = bytearray(hex_data)
check = 0
for i in msg:
check = AddToCRC(i, check)
return hex(check)
def AddToCRC(b, crc):
if (b < 0):
b += 256
for i in range(8):
odd = ((b^crc) & 1) == 1
crc >>= 1
b >>= 1
if (odd):
crc ^= 0x8C # this means crc ^= 140
return crc
def check(incoming):
"""Returns True if CRC Outcome Is 0xx or 0x0"""
result = calc(incoming)
if result == "0x0" or result == "0x00":
return True
else:
return False
def append(incoming):
"""Returns the Incoming message after appending it's CRC CheckSum"""
result = calc(incoming).split('x')[1].zfill(2)
return incoming + result
if __name__ == '__main__':
if not sys.stdin.isatty():
# there's something in stdin
msg = sys.stdin.read().strip()
if msg == "":
print("No data input. Either provide by stdin or arguments")
sys.exit(1)
elif len(sys.argv) > 1:
msg = sys.argv[1]
else:
print("No data input. Either provide by stdin or arguments")
sys.exit(1)
try:
sys.stdout.write(calc(msg))
sys.exit(0)
except Exception as err:
print("An Error Occured: {0}".format(err))
sys.exit(1)
@sefakeles
Copy link

#include "stdafx.h"

typedef unsigned char byte;

byte table[] = {
    0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65,
    157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220,
    35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98,
    190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255,
    70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7,
    219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154,
    101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36,
    248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185,
    140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205,
    17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80,
    175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238,
    50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115,
    202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139,
    87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22,
    233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168,
    116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53
};

byte calculateChecksum(byte *data, int byteCount)
{
    byte checksum = 0;

    for (int i = 0; i < byteCount; i++)
    {
        checksum = table[data[i] ^ checksum];
    }

    return checksum;
}

int _tmain(int argc, _TCHAR* argv[])
{
    byte data[] = { 0xAA };
    byte chk = 0;

    chk = calculateChecksum(data, 1);

    return 0;
}

@clarkli86
Copy link

import crcmod
crc8_func = crcmod.predefined.mkPredefinedCrcFun("crc-8")
crc8_func(b'Hello')

@pklapperich
Copy link

clarkli86, maxim's 8-bit crc calculation is not the same as crcmod's "crc-8"

@pklapperich
Copy link

pklapperich commented Aug 25, 2016

Looks like crcmod does support Maxim's crc8, though:
http://crcmod.sourceforge.net/crcmod.predefined.html

import crcmod.predefined
crc8 = crcmod.predefined.mkPredefinedCrcFun('crc-8-maxim')
print hex(crc8('\x70\x2b\xbb\xea\x00\x00\x00'))
0xF0

@anotherboz
Copy link

anotherboz commented May 21, 2021

May I suggest :

stream = b'\x02\x1c\xb8\x01\x00\x00\x00'
crc = 0
for c in stream:
    for i in range(0, 8):
        b = (crc & 1) ^ ((( int(c) & (1 << i))) >> i)
        crc = (crc ^ (b * 0x118)) >> 1
print(hex(crc))

Might be usefull for MicroPython
Implemented from : https://www.maximintegrated.com/en/design/technical-documents/app-notes/2/27.html

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