天天看點

【CRC】CRC推導(五)CRC8的各種實作

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CRC.CRC8
{
    class CRC8
    {
        /*

            Algorithm          	Poly    Init    RefIn 	RefOut 	XorOut     
            CRC-8	            0x07	0x00	false	false	0x00
            CRC-8/CDMA2000	    0x9B	0xFF	false	false	0x00
            CRC-8/DARC	        0x39	0x00	true	true	0x00
            CRC-8/DVB-S2	    0xD5	0x00	false	false	0x00
            CRC-8/EBU	        0x1D	0xFF	true	true	0x00
            CRC-8/I-CODE	    0x1D	0xFD	false	false	0x00
            CRC-8/ITU	        0x07	0x00	false	false	0x55
            CRC-8/MAXIM	        0x31	0x00	true	true	0x00
            CRC-8/ROHC	        0x07	0xFF	true	true	0x00
            CRC-8/WCDMA	        0x9B	0x00	true	true	0x00
         *  
         */

        #region Table
        readonly byte[] Crc8_poly07_Table8 = new byte[256]
        {

            0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15,
            0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D,
            0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65,
            0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D,
            0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5,
            0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD,
            0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85,
            0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD,
            0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2,
            0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA,
            0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2,
            0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A,
            0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32,
            0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A,
            0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42,
            0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A,
            0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C,
            0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4,
            0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC,
            0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4,
            0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C,
            0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44,
            0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C,
            0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34,
            0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B,
            0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63,
            0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B,
            0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13,
            0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB,
            0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83,
            0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB,
            0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3
        };

        readonly byte[] Crc8_poly9B_Table8 = new byte[256]
        {

            0x00, 0x9B, 0xAD, 0x36, 0xC1, 0x5A, 0x6C, 0xF7,
            0x19, 0x82, 0xB4, 0x2F, 0xD8, 0x43, 0x75, 0xEE,
            0x32, 0xA9, 0x9F, 0x04, 0xF3, 0x68, 0x5E, 0xC5,
            0x2B, 0xB0, 0x86, 0x1D, 0xEA, 0x71, 0x47, 0xDC,
            0x64, 0xFF, 0xC9, 0x52, 0xA5, 0x3E, 0x08, 0x93,
            0x7D, 0xE6, 0xD0, 0x4B, 0xBC, 0x27, 0x11, 0x8A,
            0x56, 0xCD, 0xFB, 0x60, 0x97, 0x0C, 0x3A, 0xA1,
            0x4F, 0xD4, 0xE2, 0x79, 0x8E, 0x15, 0x23, 0xB8,
            0xC8, 0x53, 0x65, 0xFE, 0x09, 0x92, 0xA4, 0x3F,
            0xD1, 0x4A, 0x7C, 0xE7, 0x10, 0x8B, 0xBD, 0x26,
            0xFA, 0x61, 0x57, 0xCC, 0x3B, 0xA0, 0x96, 0x0D,
            0xE3, 0x78, 0x4E, 0xD5, 0x22, 0xB9, 0x8F, 0x14,
            0xAC, 0x37, 0x01, 0x9A, 0x6D, 0xF6, 0xC0, 0x5B,
            0xB5, 0x2E, 0x18, 0x83, 0x74, 0xEF, 0xD9, 0x42,
            0x9E, 0x05, 0x33, 0xA8, 0x5F, 0xC4, 0xF2, 0x69,
            0x87, 0x1C, 0x2A, 0xB1, 0x46, 0xDD, 0xEB, 0x70,
            0x0B, 0x90, 0xA6, 0x3D, 0xCA, 0x51, 0x67, 0xFC,
            0x12, 0x89, 0xBF, 0x24, 0xD3, 0x48, 0x7E, 0xE5,
            0x39, 0xA2, 0x94, 0x0F, 0xF8, 0x63, 0x55, 0xCE,
            0x20, 0xBB, 0x8D, 0x16, 0xE1, 0x7A, 0x4C, 0xD7,
            0x6F, 0xF4, 0xC2, 0x59, 0xAE, 0x35, 0x03, 0x98,
            0x76, 0xED, 0xDB, 0x40, 0xB7, 0x2C, 0x1A, 0x81,
            0x5D, 0xC6, 0xF0, 0x6B, 0x9C, 0x07, 0x31, 0xAA,
            0x44, 0xDF, 0xE9, 0x72, 0x85, 0x1E, 0x28, 0xB3,
            0xC3, 0x58, 0x6E, 0xF5, 0x02, 0x99, 0xAF, 0x34,
            0xDA, 0x41, 0x77, 0xEC, 0x1B, 0x80, 0xB6, 0x2D,
            0xF1, 0x6A, 0x5C, 0xC7, 0x30, 0xAB, 0x9D, 0x06,
            0xE8, 0x73, 0x45, 0xDE, 0x29, 0xB2, 0x84, 0x1F,
            0xA7, 0x3C, 0x0A, 0x91, 0x66, 0xFD, 0xCB, 0x50,
            0xBE, 0x25, 0x13, 0x88, 0x7F, 0xE4, 0xD2, 0x49,
            0x95, 0x0E, 0x38, 0xA3, 0x54, 0xCF, 0xF9, 0x62,
            0x8C, 0x17, 0x21, 0xBA, 0x4D, 0xD6, 0xE0, 0x7B
        };

        readonly byte[] Crc8_poly39_Table8 = new byte[256]
        {

            0x00, 0x39, 0x72, 0x4B, 0xE4, 0xDD, 0x96, 0xAF,
            0xF1, 0xC8, 0x83, 0xBA, 0x15, 0x2C, 0x67, 0x5E,
            0xDB, 0xE2, 0xA9, 0x90, 0x3F, 0x06, 0x4D, 0x74,
            0x2A, 0x13, 0x58, 0x61, 0xCE, 0xF7, 0xBC, 0x85,
            0x8F, 0xB6, 0xFD, 0xC4, 0x6B, 0x52, 0x19, 0x20,
            0x7E, 0x47, 0x0C, 0x35, 0x9A, 0xA3, 0xE8, 0xD1,
            0x54, 0x6D, 0x26, 0x1F, 0xB0, 0x89, 0xC2, 0xFB,
            0xA5, 0x9C, 0xD7, 0xEE, 0x41, 0x78, 0x33, 0x0A,
            0x27, 0x1E, 0x55, 0x6C, 0xC3, 0xFA, 0xB1, 0x88,
            0xD6, 0xEF, 0xA4, 0x9D, 0x32, 0x0B, 0x40, 0x79,
            0xFC, 0xC5, 0x8E, 0xB7, 0x18, 0x21, 0x6A, 0x53,
            0x0D, 0x34, 0x7F, 0x46, 0xE9, 0xD0, 0x9B, 0xA2,
            0xA8, 0x91, 0xDA, 0xE3, 0x4C, 0x75, 0x3E, 0x07,
            0x59, 0x60, 0x2B, 0x12, 0xBD, 0x84, 0xCF, 0xF6,
            0x73, 0x4A, 0x01, 0x38, 0x97, 0xAE, 0xE5, 0xDC,
            0x82, 0xBB, 0xF0, 0xC9, 0x66, 0x5F, 0x14, 0x2D,
            0x4E, 0x77, 0x3C, 0x05, 0xAA, 0x93, 0xD8, 0xE1,
            0xBF, 0x86, 0xCD, 0xF4, 0x5B, 0x62, 0x29, 0x10,
            0x95, 0xAC, 0xE7, 0xDE, 0x71, 0x48, 0x03, 0x3A,
            0x64, 0x5D, 0x16, 0x2F, 0x80, 0xB9, 0xF2, 0xCB,
            0xC1, 0xF8, 0xB3, 0x8A, 0x25, 0x1C, 0x57, 0x6E,
            0x30, 0x09, 0x42, 0x7B, 0xD4, 0xED, 0xA6, 0x9F,
            0x1A, 0x23, 0x68, 0x51, 0xFE, 0xC7, 0x8C, 0xB5,
            0xEB, 0xD2, 0x99, 0xA0, 0x0F, 0x36, 0x7D, 0x44,
            0x69, 0x50, 0x1B, 0x22, 0x8D, 0xB4, 0xFF, 0xC6,
            0x98, 0xA1, 0xEA, 0xD3, 0x7C, 0x45, 0x0E, 0x37,
            0xB2, 0x8B, 0xC0, 0xF9, 0x56, 0x6F, 0x24, 0x1D,
            0x43, 0x7A, 0x31, 0x08, 0xA7, 0x9E, 0xD5, 0xEC,
            0xE6, 0xDF, 0x94, 0xAD, 0x02, 0x3B, 0x70, 0x49,
            0x17, 0x2E, 0x65, 0x5C, 0xF3, 0xCA, 0x81, 0xB8,
            0x3D, 0x04, 0x4F, 0x76, 0xD9, 0xE0, 0xAB, 0x92,
            0xCC, 0xF5, 0xBE, 0x87, 0x28, 0x11, 0x5A, 0x63
        };

        readonly byte[] Crc8_polyD5_Table8 = new byte[256]
        {

            0x00, 0xD5, 0x7F, 0xAA, 0xFE, 0x2B, 0x81, 0x54,
            0x29, 0xFC, 0x56, 0x83, 0xD7, 0x02, 0xA8, 0x7D,
            0x52, 0x87, 0x2D, 0xF8, 0xAC, 0x79, 0xD3, 0x06,
            0x7B, 0xAE, 0x04, 0xD1, 0x85, 0x50, 0xFA, 0x2F,
            0xA4, 0x71, 0xDB, 0x0E, 0x5A, 0x8F, 0x25, 0xF0,
            0x8D, 0x58, 0xF2, 0x27, 0x73, 0xA6, 0x0C, 0xD9,
            0xF6, 0x23, 0x89, 0x5C, 0x08, 0xDD, 0x77, 0xA2,
            0xDF, 0x0A, 0xA0, 0x75, 0x21, 0xF4, 0x5E, 0x8B,
            0x9D, 0x48, 0xE2, 0x37, 0x63, 0xB6, 0x1C, 0xC9,
            0xB4, 0x61, 0xCB, 0x1E, 0x4A, 0x9F, 0x35, 0xE0,
            0xCF, 0x1A, 0xB0, 0x65, 0x31, 0xE4, 0x4E, 0x9B,
            0xE6, 0x33, 0x99, 0x4C, 0x18, 0xCD, 0x67, 0xB2,
            0x39, 0xEC, 0x46, 0x93, 0xC7, 0x12, 0xB8, 0x6D,
            0x10, 0xC5, 0x6F, 0xBA, 0xEE, 0x3B, 0x91, 0x44,
            0x6B, 0xBE, 0x14, 0xC1, 0x95, 0x40, 0xEA, 0x3F,
            0x42, 0x97, 0x3D, 0xE8, 0xBC, 0x69, 0xC3, 0x16,
            0xEF, 0x3A, 0x90, 0x45, 0x11, 0xC4, 0x6E, 0xBB,
            0xC6, 0x13, 0xB9, 0x6C, 0x38, 0xED, 0x47, 0x92,
            0xBD, 0x68, 0xC2, 0x17, 0x43, 0x96, 0x3C, 0xE9,
            0x94, 0x41, 0xEB, 0x3E, 0x6A, 0xBF, 0x15, 0xC0,
            0x4B, 0x9E, 0x34, 0xE1, 0xB5, 0x60, 0xCA, 0x1F,
            0x62, 0xB7, 0x1D, 0xC8, 0x9C, 0x49, 0xE3, 0x36,
            0x19, 0xCC, 0x66, 0xB3, 0xE7, 0x32, 0x98, 0x4D,
            0x30, 0xE5, 0x4F, 0x9A, 0xCE, 0x1B, 0xB1, 0x64,
            0x72, 0xA7, 0x0D, 0xD8, 0x8C, 0x59, 0xF3, 0x26,
            0x5B, 0x8E, 0x24, 0xF1, 0xA5, 0x70, 0xDA, 0x0F,
            0x20, 0xF5, 0x5F, 0x8A, 0xDE, 0x0B, 0xA1, 0x74,
            0x09, 0xDC, 0x76, 0xA3, 0xF7, 0x22, 0x88, 0x5D,
            0xD6, 0x03, 0xA9, 0x7C, 0x28, 0xFD, 0x57, 0x82,
            0xFF, 0x2A, 0x80, 0x55, 0x01, 0xD4, 0x7E, 0xAB,
            0x84, 0x51, 0xFB, 0x2E, 0x7A, 0xAF, 0x05, 0xD0,
            0xAD, 0x78, 0xD2, 0x07, 0x53, 0x86, 0x2C, 0xF9
        };

        readonly byte[] Crc8_poly1D_Table8 = new byte[256]
        {

            0x00, 0x1D, 0x3A, 0x27, 0x74, 0x69, 0x4E, 0x53,
            0xE8, 0xF5, 0xD2, 0xCF, 0x9C, 0x81, 0xA6, 0xBB,
            0xCD, 0xD0, 0xF7, 0xEA, 0xB9, 0xA4, 0x83, 0x9E,
            0x25, 0x38, 0x1F, 0x02, 0x51, 0x4C, 0x6B, 0x76,
            0x87, 0x9A, 0xBD, 0xA0, 0xF3, 0xEE, 0xC9, 0xD4,
            0x6F, 0x72, 0x55, 0x48, 0x1B, 0x06, 0x21, 0x3C,
            0x4A, 0x57, 0x70, 0x6D, 0x3E, 0x23, 0x04, 0x19,
            0xA2, 0xBF, 0x98, 0x85, 0xD6, 0xCB, 0xEC, 0xF1,
            0x13, 0x0E, 0x29, 0x34, 0x67, 0x7A, 0x5D, 0x40,
            0xFB, 0xE6, 0xC1, 0xDC, 0x8F, 0x92, 0xB5, 0xA8,
            0xDE, 0xC3, 0xE4, 0xF9, 0xAA, 0xB7, 0x90, 0x8D,
            0x36, 0x2B, 0x0C, 0x11, 0x42, 0x5F, 0x78, 0x65,
            0x94, 0x89, 0xAE, 0xB3, 0xE0, 0xFD, 0xDA, 0xC7,
            0x7C, 0x61, 0x46, 0x5B, 0x08, 0x15, 0x32, 0x2F,
            0x59, 0x44, 0x63, 0x7E, 0x2D, 0x30, 0x17, 0x0A,
            0xB1, 0xAC, 0x8B, 0x96, 0xC5, 0xD8, 0xFF, 0xE2,
            0x26, 0x3B, 0x1C, 0x01, 0x52, 0x4F, 0x68, 0x75,
            0xCE, 0xD3, 0xF4, 0xE9, 0xBA, 0xA7, 0x80, 0x9D,
            0xEB, 0xF6, 0xD1, 0xCC, 0x9F, 0x82, 0xA5, 0xB8,
            0x03, 0x1E, 0x39, 0x24, 0x77, 0x6A, 0x4D, 0x50,
            0xA1, 0xBC, 0x9B, 0x86, 0xD5, 0xC8, 0xEF, 0xF2,
            0x49, 0x54, 0x73, 0x6E, 0x3D, 0x20, 0x07, 0x1A,
            0x6C, 0x71, 0x56, 0x4B, 0x18, 0x05, 0x22, 0x3F,
            0x84, 0x99, 0xBE, 0xA3, 0xF0, 0xED, 0xCA, 0xD7,
            0x35, 0x28, 0x0F, 0x12, 0x41, 0x5C, 0x7B, 0x66,
            0xDD, 0xC0, 0xE7, 0xFA, 0xA9, 0xB4, 0x93, 0x8E,
            0xF8, 0xE5, 0xC2, 0xDF, 0x8C, 0x91, 0xB6, 0xAB,
            0x10, 0x0D, 0x2A, 0x37, 0x64, 0x79, 0x5E, 0x43,
            0xB2, 0xAF, 0x88, 0x95, 0xC6, 0xDB, 0xFC, 0xE1,
            0x5A, 0x47, 0x60, 0x7D, 0x2E, 0x33, 0x14, 0x09,
            0x7F, 0x62, 0x45, 0x58, 0x0B, 0x16, 0x31, 0x2C,
            0x97, 0x8A, 0xAD, 0xB0, 0xE3, 0xFE, 0xD9, 0xC4
        };

        readonly byte[] Crc8_poly31_Table8 = new byte[256]
        {

            0x00, 0x31, 0x62, 0x53, 0xC4, 0xF5, 0xA6, 0x97,
            0xB9, 0x88, 0xDB, 0xEA, 0x7D, 0x4C, 0x1F, 0x2E,
            0x43, 0x72, 0x21, 0x10, 0x87, 0xB6, 0xE5, 0xD4,
            0xFA, 0xCB, 0x98, 0xA9, 0x3E, 0x0F, 0x5C, 0x6D,
            0x86, 0xB7, 0xE4, 0xD5, 0x42, 0x73, 0x20, 0x11,
            0x3F, 0x0E, 0x5D, 0x6C, 0xFB, 0xCA, 0x99, 0xA8,
            0xC5, 0xF4, 0xA7, 0x96, 0x01, 0x30, 0x63, 0x52,
            0x7C, 0x4D, 0x1E, 0x2F, 0xB8, 0x89, 0xDA, 0xEB,
            0x3D, 0x0C, 0x5F, 0x6E, 0xF9, 0xC8, 0x9B, 0xAA,
            0x84, 0xB5, 0xE6, 0xD7, 0x40, 0x71, 0x22, 0x13,
            0x7E, 0x4F, 0x1C, 0x2D, 0xBA, 0x8B, 0xD8, 0xE9,
            0xC7, 0xF6, 0xA5, 0x94, 0x03, 0x32, 0x61, 0x50,
            0xBB, 0x8A, 0xD9, 0xE8, 0x7F, 0x4E, 0x1D, 0x2C,
            0x02, 0x33, 0x60, 0x51, 0xC6, 0xF7, 0xA4, 0x95,
            0xF8, 0xC9, 0x9A, 0xAB, 0x3C, 0x0D, 0x5E, 0x6F,
            0x41, 0x70, 0x23, 0x12, 0x85, 0xB4, 0xE7, 0xD6,
            0x7A, 0x4B, 0x18, 0x29, 0xBE, 0x8F, 0xDC, 0xED,
            0xC3, 0xF2, 0xA1, 0x90, 0x07, 0x36, 0x65, 0x54,
            0x39, 0x08, 0x5B, 0x6A, 0xFD, 0xCC, 0x9F, 0xAE,
            0x80, 0xB1, 0xE2, 0xD3, 0x44, 0x75, 0x26, 0x17,
            0xFC, 0xCD, 0x9E, 0xAF, 0x38, 0x09, 0x5A, 0x6B,
            0x45, 0x74, 0x27, 0x16, 0x81, 0xB0, 0xE3, 0xD2,
            0xBF, 0x8E, 0xDD, 0xEC, 0x7B, 0x4A, 0x19, 0x28,
            0x06, 0x37, 0x64, 0x55, 0xC2, 0xF3, 0xA0, 0x91,
            0x47, 0x76, 0x25, 0x14, 0x83, 0xB2, 0xE1, 0xD0,
            0xFE, 0xCF, 0x9C, 0xAD, 0x3A, 0x0B, 0x58, 0x69,
            0x04, 0x35, 0x66, 0x57, 0xC0, 0xF1, 0xA2, 0x93,
            0xBD, 0x8C, 0xDF, 0xEE, 0x79, 0x48, 0x1B, 0x2A,
            0xC1, 0xF0, 0xA3, 0x92, 0x05, 0x34, 0x67, 0x56,
            0x78, 0x49, 0x1A, 0x2B, 0xBC, 0x8D, 0xDE, 0xEF,
            0x82, 0xB3, 0xE0, 0xD1, 0x46, 0x77, 0x24, 0x15,
            0x3B, 0x0A, 0x59, 0x68, 0xFF, 0xCE, 0x9D, 0xAC
        };


        readonly byte[] Crc8_poly2F_Table8 = new byte[256]
        {
            0x00, 0x2F, 0x5E, 0x71, 0xBC, 0x93, 0xE2, 0xCD,
            0x57, 0x78, 0x09, 0x26, 0xEB, 0xC4, 0xB5, 0x9A,
            0xAE, 0x81, 0xF0, 0xDF, 0x12, 0x3D, 0x4C, 0x63,
            0xF9, 0xD6, 0xA7, 0x88, 0x45, 0x6A, 0x1B, 0x34,
            0x73, 0x5C, 0x2D, 0x02, 0xCF, 0xE0, 0x91, 0xBE,
            0x24, 0x0B, 0x7A, 0x55, 0x98, 0xB7, 0xC6, 0xE9,
            0xDD, 0xF2, 0x83, 0xAC, 0x61, 0x4E, 0x3F, 0x10,
            0x8A, 0xA5, 0xD4, 0xFB, 0x36, 0x19, 0x68, 0x47,
            0xE6, 0xC9, 0xB8, 0x97, 0x5A, 0x75, 0x04, 0x2B,
            0xB1, 0x9E, 0xEF, 0xC0, 0x0D, 0x22, 0x53, 0x7C,
            0x48, 0x67, 0x16, 0x39, 0xF4, 0xDB, 0xAA, 0x85,
            0x1F, 0x30, 0x41, 0x6E, 0xA3, 0x8C, 0xFD, 0xD2,
            0x95, 0xBA, 0xCB, 0xE4, 0x29, 0x06, 0x77, 0x58,
            0xC2, 0xED, 0x9C, 0xB3, 0x7E, 0x51, 0x20, 0x0F,
            0x3B, 0x14, 0x65, 0x4A, 0x87, 0xA8, 0xD9, 0xF6,
            0x6C, 0x43, 0x32, 0x1D, 0xD0, 0xFF, 0x8E, 0xA1,
            0xE3, 0xCC, 0xBD, 0x92, 0x5F, 0x70, 0x01, 0x2E,
            0xB4, 0x9B, 0xEA, 0xC5, 0x08, 0x27, 0x56, 0x79,
            0x4D, 0x62, 0x13, 0x3C, 0xF1, 0xDE, 0xAF, 0x80,
            0x1A, 0x35, 0x44, 0x6B, 0xA6, 0x89, 0xF8, 0xD7,
            0x90, 0xBF, 0xCE, 0xE1, 0x2C, 0x03, 0x72, 0x5D,
            0xC7, 0xE8, 0x99, 0xB6, 0x7B, 0x54, 0x25, 0x0A,
            0x3E, 0x11, 0x60, 0x4F, 0x82, 0xAD, 0xDC, 0xF3,
            0x69, 0x46, 0x37, 0x18, 0xD5, 0xFA, 0x8B, 0xA4,
            0x05, 0x2A, 0x5B, 0x74, 0xB9, 0x96, 0xE7, 0xC8,
            0x52, 0x7D, 0x0C, 0x23, 0xEE, 0xC1, 0xB0, 0x9F,
            0xAB, 0x84, 0xF5, 0xDA, 0x17, 0x38, 0x49, 0x66,
            0xFC, 0xD3, 0xA2, 0x8D, 0x40, 0x6F, 0x1E, 0x31,
            0x76, 0x59, 0x28, 0x07, 0xCA, 0xE5, 0x94, 0xBB,
            0x21, 0x0E, 0x7F, 0x50, 0x9D, 0xB2, 0xC3, 0xEC,
            0xD8, 0xF7, 0x86, 0xA9, 0x64, 0x4B, 0x3A, 0x15,
            0x8F, 0xA0, 0xD1, 0xFE, 0x33, 0x1C, 0x6D, 0x42
        };

        #endregion

        public struct Scm_CRC8_InputParameters
        {
            /// <summary>
            /// 算法名稱
            /// </summary>
            public string AlgorithmName;

            /// <summary>
            /// 是否大端模式,
            /// 大端模式,高位元組在前,左移計算,多項式無需反轉
            /// 小端模式,低位元組在前,右移計算,多項式需反轉
            /// CRC8寄存器隻有8位,大小端無影響
            /// </summary>
            //public bool LittleEndian; 

            /// <summary>
            /// 多項式
            /// </summary>
            public byte Polynomial;

            /// <summary>
            /// crc寄存器寬度
            /// 隻讀
            /// </summary>
            public int cWidth { get { return sizeof(byte) / sizeof(byte) * 8; } }

            /// <summary>
            /// 資料
            /// </summary>
            public byte[] Datas;
            /// <summary>
            /// 初始crc值
            /// </summary>
            public byte InitCrc;
            /// <summary>
            /// 輸入反轉
            /// </summary>
            public bool RefIn;
            /// <summary>
            /// 輸出反轉
            /// </summary>
            public bool RefOut;

            /// <summary>
            /// 輸出是否異或
            /// </summary>
            //public bool isOutputXor;

            /// <summary>
            /// 輸出異或值
            /// </summary>
            public byte XorOut;
        }


        public byte CRC8_Calculate(Scm_CRC8_InputParameters scm_CRC8_InputParameters)
        {
            byte poly = scm_CRC8_InputParameters.Polynomial;
            byte crc = scm_CRC8_InputParameters.InitCrc;
            int width = scm_CRC8_InputParameters.cWidth;


            for (int i = 0; i < scm_CRC8_InputParameters.Datas.Length; i++)
            {
                byte tempData = scm_CRC8_InputParameters.Datas[i];
                //輸入反轉
                if (scm_CRC8_InputParameters.RefIn)
                    tempData = SpecialFunctions.ReverseBits.ReverseUInt8(tempData);

                    //左移到最高位元組,然後與初始值異或
                    crc ^= (byte)(tempData << (width - 8));


                for (int j = 0; j < 8; j++)
                {
                    //最高位為1,異或多項式
                    if ((crc & (1 << (width - 1))) != 0)
                    {
                        crc <<= 1;
                        crc ^= poly;
                    }
                    else
                        crc <<= 1;
                    
                }

            }

            //輸出反轉
            if (scm_CRC8_InputParameters.RefOut)
                crc = SpecialFunctions.ReverseBits.ReverseUInt8(crc);

            //輸出異或
            //if (scm_CRC8_InputParameters.isOutputXor)
            crc ^= scm_CRC8_InputParameters.XorOut;

            return crc;

        }

        public byte[] GetCRC8_ByteTable(byte poly)
        {
            Scm_CRC8_InputParameters scm_CRC8_InputParameters = new Scm_CRC8_InputParameters()
            { Polynomial = poly, InitCrc = 0x00, RefIn = false, RefOut = false, XorOut = 0x00 };
            byte[] table = new byte[256];
            for (uint i = 0; i < 256; i++)
            {
                scm_CRC8_InputParameters.Datas = new byte[1] { (byte)i };
                table[i]=CRC8_Calculate(scm_CRC8_InputParameters);
            }
            return table;
        }

        /// <summary>
        /// CRC8
        /// 位元組查表法
        /// </summary>
        byte CRC8_CalCrcByByte(Scm_CRC8_InputParameters scm_CRC8_InputParameters)
        {


            byte poly = scm_CRC8_InputParameters.Polynomial;
            byte crc = scm_CRC8_InputParameters.InitCrc;
            int width = scm_CRC8_InputParameters.cWidth;


            for (int i = 0; i < scm_CRC8_InputParameters.Datas.Length; i++)
            {
                byte tempData = scm_CRC8_InputParameters.Datas[i];
                //輸入反轉
                if (scm_CRC8_InputParameters.RefIn)
                    tempData = SpecialFunctions.ReverseBits.ReverseUInt8(tempData);

                //異或的部分最終會消除掉,這裡我們就不将其存到CRC了
                //左移到最高位元組,然後與初始值異或,CRC8無需移位,width=8
                byte index = (byte)((crc >> (width - 8)) ^ tempData);


                switch (poly)
                {
                    case 0x1D:
                        crc = (byte) ( (crc<<8)+Crc8_poly1D_Table8[index] );
                        break;
                    case 0x2F:
                        crc = (byte)((crc << 8) + Crc8_poly2F_Table8[index] );
                        break;
                    case 0x07:
                        crc = (byte)((crc << 8) + Crc8_poly07_Table8[index]);
                        break;
                    case 0x39:
                        crc = (byte)((crc << 8) + Crc8_poly39_Table8[index]);
                        break;
                    case 0x9B:
                        crc = (byte)((crc << 8) + Crc8_poly9B_Table8[index]);
                        break;
                    case 0xD5:
                        crc = (byte)((crc << 8) + Crc8_polyD5_Table8[index]);
                        break;
                    case 0x31:
                        crc = (byte)((crc << 8) + Crc8_poly31_Table8[index]);
                        break;

                    default:
                        crc = 0;
                        break;
                }

            }

            //輸出反轉
            if (scm_CRC8_InputParameters.RefOut)
                crc = SpecialFunctions.ReverseBits.ReverseUInt8(crc);

            //輸出異或
            //if (scm_CRC8_InputParameters.isOutputXor)
            crc ^= scm_CRC8_InputParameters.XorOut;

            return crc;

        }


        private void CalCrc8All(byte[] data)
        {
            //計算網頁位址:https://crccalc.com/

            Scm_CRC8_InputParameters[] scm_CRC8_InputParametersList = new Scm_CRC8_InputParameters[] {
            new Scm_CRC8_InputParameters(){ AlgorithmName ="CRC-8         ",    Polynomial= 0x07,   InitCrc=0x00,    RefIn=false,  RefOut=false, XorOut=0x00 ,Datas=SpecialFunctions.ArrayCopy.CopyArray<byte>(data)},
            new Scm_CRC8_InputParameters(){ AlgorithmName ="CRC-8/CDMA2000",    Polynomial= 0x9B,   InitCrc=0xFF,    RefIn=false,  RefOut=false, XorOut=0x00 ,Datas=SpecialFunctions.ArrayCopy.CopyArray<byte>(data) },
            new Scm_CRC8_InputParameters(){ AlgorithmName ="CRC-8/DARC    ",    Polynomial= 0x39,   InitCrc=0x00,    RefIn=true,   RefOut=true,  XorOut=0x00 ,Datas=SpecialFunctions.ArrayCopy.CopyArray<byte>(data) },
            new Scm_CRC8_InputParameters(){ AlgorithmName ="CRC-8/DVB-S2  ",    Polynomial= 0xD5,   InitCrc=0x00,    RefIn=false,  RefOut=false, XorOut=0x00 ,Datas=SpecialFunctions.ArrayCopy.CopyArray<byte>(data) },
            new Scm_CRC8_InputParameters(){ AlgorithmName ="CRC-8/EBU     ",    Polynomial= 0x1D,   InitCrc=0xFF,    RefIn=true,   RefOut=true,  XorOut=0x00 ,Datas=SpecialFunctions.ArrayCopy.CopyArray<byte>(data) },
            new Scm_CRC8_InputParameters(){ AlgorithmName ="CRC-8/I-CODE  ",    Polynomial= 0x1D,   InitCrc=0xFD,    RefIn=false,  RefOut=false, XorOut=0x00 ,Datas=SpecialFunctions.ArrayCopy.CopyArray<byte>(data) },
            new Scm_CRC8_InputParameters(){ AlgorithmName ="CRC-8/ITU     ",    Polynomial= 0x07,   InitCrc=0x00,    RefIn=false,  RefOut=false, XorOut=0x55 ,Datas=SpecialFunctions.ArrayCopy.CopyArray<byte>(data) },
            new Scm_CRC8_InputParameters(){ AlgorithmName ="CRC-8/MAXIM   ",    Polynomial= 0x31,   InitCrc=0x00,    RefIn=true,   RefOut=true,  XorOut=0x00 ,Datas=SpecialFunctions.ArrayCopy.CopyArray<byte>(data) },
            new Scm_CRC8_InputParameters(){ AlgorithmName ="CRC-8/ROHC    ",    Polynomial= 0x07,   InitCrc=0xFF,    RefIn=true,   RefOut=true,  XorOut=0x00 ,Datas=SpecialFunctions.ArrayCopy.CopyArray<byte>(data) },
            new Scm_CRC8_InputParameters(){ AlgorithmName ="CRC-8/WCDMA   ",    Polynomial= 0x9B,   InitCrc=0x00,    RefIn=true,   RefOut=true,  XorOut=0x00 ,Datas=SpecialFunctions.ArrayCopy.CopyArray<byte>(data) }
            };

            for (int i = 0; i < scm_CRC8_InputParametersList.Length; i++)
            {
                //scm_CRC8_InputParametersList[i].Datas = SpecialFunctions.ArrayCopy.CopyArray<byte>(data);
                byte crc1 = CRC8_Calculate(scm_CRC8_InputParametersList[i]);

                Console.WriteLine("BitsCal {0}, Poly={1:X02}, InitCrc={2:X02}, RefIn={3}, RefOut={4}, XorOut={5:X02}, data={6}, result={7:X02}",
                    scm_CRC8_InputParametersList[i].AlgorithmName,
                    scm_CRC8_InputParametersList[i].Polynomial, scm_CRC8_InputParametersList[i].InitCrc,
                    scm_CRC8_InputParametersList[i].RefIn?"True ":"False", scm_CRC8_InputParametersList[i].RefOut ? "True " : "False",
                    scm_CRC8_InputParametersList[i].XorOut, BitConverter.ToString(scm_CRC8_InputParametersList[i].Datas).Replace("-", ""),
                    crc1);

                byte crc2 = CRC8_CalCrcByByte(scm_CRC8_InputParametersList[i]);

                Console.WriteLine("ByteCal {0}, Poly={1:X02}, InitCrc={2:X02}, RefIn={3:5}, RefOut={4:5}, XorOut={5:X02}, data={6}, result={7:X02}",
                    scm_CRC8_InputParametersList[i].AlgorithmName,
                    scm_CRC8_InputParametersList[i].Polynomial, scm_CRC8_InputParametersList[i].InitCrc,
                    scm_CRC8_InputParametersList[i].RefIn ? "True " : "False", scm_CRC8_InputParametersList[i].RefOut ? "True " : "False",
                    scm_CRC8_InputParametersList[i].XorOut, BitConverter.ToString(scm_CRC8_InputParametersList[i].Datas).Replace("-", ""),
                    crc2);

                if (crc1 != crc2)
                {
                    ConsoleColor temp = Console.ForegroundColor;
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("Not Same");
                    Console.ForegroundColor = temp;
                }
            }
        }

        private void GetTableTest()
        {
            byte[] polyList = new byte[] { 0x07, 0x9B, 0x39, 0xD5, 0x1D, 0x31 };

            for (int pp = 0; pp < polyList.Length; pp++)
            {
                Console.WriteLine("readonly byte[] Crc8_poly"+ polyList[pp].ToString("X2")+"_Table8 = new byte[256]\r\n{");
                byte[] table = GetCRC8_ByteTable(polyList[pp]);
                for (int i = 0; i < table.Length; i++)
                {
                    if (i % 8 == 0)
                    {
                        Console.WriteLine();
                        Console.Write("\t");
                    }

                    if (i < table.Length - 1)
                        Console.Write("0x{0:X02}, ", table[i]);
                    else
                    {
                        Console.Write("0x{0:X02}\r\n", table[i]);
                        Console.WriteLine(@"};");
                        Console.WriteLine();
                    }

                    //if (table[i] != Crc8_poly1D_Table8[i])
                    //{
                    //    Console.ForegroundColor = ConsoleColor.Red;
                    //    Console.Write("error {0}, 0x{1:X02}, ", i, table[i]);
                    //}

                        //Console.ForegroundColor = ConsoleColor.White;

                }
            }
            Console.WriteLine();


        }



        public static void Test(byte[] data, byte crcInitial)
        {
            CRC8 cRC8 = new CRC8();

            cRC8.CalCrc8All(data);

            //cRC8.GetTableTest();

        }

    }

}
           

上一篇 【CRC】CRC推導(四)算法優化    下一篇 【CRC】CRC推導(六)CRC16的各種實作

繼續閱讀