' CRC-8 — computes 8-bit cyclic redundancy check
#COMPILE EXE
#DIM ALL

FUNCTION ReverseByte(b AS LONG) AS LONG
    LOCAL r AS LONG
    IF (b AND 1) <> 0 THEN r = r + 128
    IF (b AND 2) <> 0 THEN r = r + 64
    IF (b AND 4) <> 0 THEN r = r + 32
    IF (b AND 8) <> 0 THEN r = r + 16
    IF (b AND 16) <> 0 THEN r = r + 8
    IF (b AND 32) <> 0 THEN r = r + 4
    IF (b AND 64) <> 0 THEN r = r + 2
    IF (b AND 128) <> 0 THEN r = r + 1
    FUNCTION = r
END FUNCTION

FUNCTION Crc8One(BYVAL c AS LONG, BYVAL b AS LONG, BYVAL p AS LONG) AS LONG
    LOCAL j AS LONG
    c = c XOR b
    FOR j = 0 TO 7
        IF (c AND 128) <> 0 THEN
            c = (c * 2) XOR p
        ELSE
            c = c * 2
        END IF
        c = c AND 255
    NEXT j
    FUNCTION = c
END FUNCTION

FUNCTION PBMAIN() AS LONG
    LOCAL s AS STRING
    LOCAL i AS LONG
    LOCAL crc AS LONG
    LOCAL h AS STRING
    LOCAL b AS LONG
    LOCAL r AS LONG
    LOCAL j AS LONG

    PRINT "CRC-8 CALCULATOR"
    PRINT ""

    s = "Hello World"
    crc = 0
    FOR i = 1 TO LEN(s)
        b = ASC(MID$(s, i, 1))
        b = ReverseByte(b)
        crc = Crc8One(crc, b, 7)
    NEXT i
    crc = ReverseByte(crc)
    h = HEX$(crc)
    IF LEN(h) = 1 THEN h = "0" + h
    PRINT "CRC-8 of 'Hello World' = 0x" + h

    s = "123456789"
    crc = 0
    FOR i = 1 TO LEN(s)
        b = ASC(MID$(s, i, 1))
        b = ReverseByte(b)
        crc = Crc8One(crc, b, 7)
    NEXT i
    crc = ReverseByte(crc)
    h = HEX$(crc)
    IF LEN(h) = 1 THEN h = "0" + h
    PRINT "CRC-8 of '123456789' = 0x" + h

    PRINT ""
    PRINT "CRC-8 variants:"
    s = "123456789"

    crc = 0
    FOR i = 1 TO LEN(s)
        b = ASC(MID$(s, i, 1))
        b = ReverseByte(b)
        crc = Crc8One(crc, b, 7)
    NEXT i
    crc = ReverseByte(crc)
    h = HEX$(crc)
    IF LEN(h) = 1 THEN h = "0" + h
    PRINT "CRC-8 standard: 0x" + h

    crc = 0
    FOR i = 1 TO LEN(s)
        b = ASC(MID$(s, i, 1))
        crc = Crc8One(crc, b, 9)
    NEXT i
    h = HEX$(crc)
    IF LEN(h) = 1 THEN h = "0" + h
    PRINT "CRC-8/ITU: 0x" + h

    crc = 0
    FOR i = 1 TO LEN(s)
        b = ASC(MID$(s, i, 1))
        crc = Crc8One(crc, b, 13)
    NEXT i
    h = HEX$(crc)
    IF LEN(h) = 1 THEN h = "0" + h
    PRINT "CRC-8/ROHC: 0x" + h

    PRINT ""
    PRINT "CRC-8 lookup table for poly 0x07"
    FOR i = 0 TO 255
        r = i
        FOR j = 0 TO 7
            IF (r AND 128) <> 0 THEN
                r = (r * 2) XOR 7
            ELSE
                r = r * 2
            END IF
            r = r AND 255
        NEXT j
        h = HEX$(r)
        IF LEN(h) = 1 THEN h = "0" + h
        PRINT "0x" + h + " "
        IF (i + 1) MOD 16 = 0 THEN PRINT ""
    NEXT i

    PRINT ""
    PRINT "Done."
    FUNCTION = 0
END FUNCTION
