精华内容
下载资源
问答
  • 基于simulink的CRC8校验算法模型,某电池厂商的CSU模拟信号
  • Java在与硬件通信协议中,我们需要利用帧头,长度,功能码,数据体等信息计算出CRC8校验码,就需要使用到Java封装的CRC8校验算法工具类,小编只是在项目中用到CRC校验算法(循环冗余校验算法),作为笔记保存起来,供...

    Java在与硬件通信协议中,我们需要利用帧头,长度,功能码,数据体等信息计算出CRC8校验码,就需要使用到Java封装的CRC8校验算法工具类,小编只是在项目中用到CRC校验算法(循环冗余校验算法),作为笔记保存起来,供日后使用!

    1:先导入HexUtil工具类,代码如下:public class HexUtil {

    private static final char[] DIGITS_LOWER = {'0', '1', '2', '3', '4', '5',

    '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    private static final char[] DIGITS_UPPER = {'0', '1', '2', '3', '4', '5',

    '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};

    public static char[] encodeHex(byte[] data) {

    return encodeHex(data, true);

    }

    public static char[] encodeHex(byte[] data, boolean toLowerCase) {

    return encodeHex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);

    }

    protected static char[] encodeHex(byte[] data, char[] toDigits) {

    if (data == null)

    return null;

    int l = data.length;

    char[] out = new char[l <

    for (int i = 0, j = 0; i 

    out[j++] = toDigits[(0xF0 & data[i]) >>> 4];

    out[j++] = toDigits[0x0F & data[i]];

    }

    return out;

    }

    public static String encodeHexStr(byte[] data) {

    return encodeHexStr(data, true);

    }

    public static String encodeHexStr(byte[] data, boolean toLowerCase) {

    return encodeHexStr(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);

    }

    protected static String encodeHexStr(byte[] data, char[] toDigits) {

    return new String(encodeHex(data, toDigits));

    }

    public static String formatHexString(byte[] data) {

    return formatHexString(data, false);

    }

    public static String formatHexString(byte[] data, boolean addSpace) {

    if (data == null || data.length 

    return null;

    StringBuilder sb = new StringBuilder();

    for (int i = 0; i 

    String hex = Integer.toHexString(data[i] & 0xFF);

    if (hex.length() == 1) {

    hex = '0' + hex;

    }

    sb.append(hex);

    if (addSpace)

    sb.append(" ");

    }

    return sb.toString().trim();

    }

    public static byte[] decodeHex(char[] data) {

    int len = data.length;

    if ((len & 0x01) != 0) {

    throw new RuntimeException("Odd number of characters.");

    }

    byte[] out = new byte[len >> 1];

    // two characters form the hex value.

    for (int i = 0, j = 0; j 

    int f = toDigit(data[j], j) <

    j++;

    f = f | toDigit(data[j], j);

    j++;

    out[i] = (byte) (f & 0xFF);

    }

    return out;

    }

    protected static int toDigit(char ch, int index) {

    int digit = Character.digit(ch, 16);

    if (digit == -1) {

    throw new RuntimeException("Illegal hexadecimal character " + ch

    + " at index " + index);

    }

    return digit;

    }

    public static byte[] hexStringToBytes(String hexString) {

    if (hexString == null || hexString.equals("")) {

    return null;

    }

    hexString = hexString.toUpperCase();

    int length = hexString.length() / 2;

    char[] hexChars = hexString.toCharArray();

    byte[] d = new byte[length];

    for (int i = 0; i 

    int pos = i * 2;

    d[i] = (byte) (charToByte(hexChars[pos]) <

    }

    return d;

    }

    public static byte charToByte(char c) {

    return (byte) "0123456789ABCDEF".indexOf(c);

    }

    public static String extractData(byte[] data, int position) {

    return HexUtil.formatHexString(new byte[]{data[position]});

    }

    //使用1字节就可以表示b

    public static String numToHex8(int b) {

    return String.format("%02x", b);//2表示需要两个16进行数

    }

    //需要使用2字节表示b

    public static String numToHex16(int b) {

    return String.format("%04x", b);

    }

    //需要使用4字节表示b

    public static String numToHex32(int b) {

    return String.format("%08x", b);

    }

    public static String getBitString(byte by){

    StringBuffer sb = new StringBuffer();

    sb.append((by>>7)&0x1)

    .append((by>>6)&0x1)

    .append((by>>5)&0x1)

    .append((by>>4)&0x1)

    .append((by>>3)&0x1)

    .append((by>>2)&0x1)

    .append((by>>1)&0x1)

    .append((by>>0)&0x1);

    return sb.toString();

    }

    public static int[] getBit(byte by){

    /*StringBuffer sb = new StringBuffer();

    sb.append((by>>7)&0x1)

    .append((by>>6)&0x1)

    .append((by>>5)&0x1)

    .append((by>>4)&0x1)

    .append((by>>3)&0x1)

    .append((by>>2)&0x1)

    .append((by>>1)&0x1)

    .append((by>>0)&0x1);*/

    int[] bits= {

    (by>>7)&0x1,

    (by>>6)&0x1,

    (by>>5)&0x1,

    (by>>4)&0x1,

    (by>>3)&0x1,

    (by>>2)&0x1,

    (by>>1)&0x1,

    (by>>0)&0x1

    };

    return bits;

    }

    }

    2:在Main方法中测试CRC8算法,代码如下:public class TestDemo {

    public static void main(String[] args) {

    System.out.println(crc8("55AA021B00"));

    //输出结果为:75

    }

    public static String crc8(String hexCommond) {

    int crc8 = FindCRC(HexUtil.hexStringToBytes(hexCommond));

    return HexUtil.numToHex8(crc8).toUpperCase();

    }

    //获取CRC校验字节

    public static int FindCRC(byte[] data) {

    int CRC = 0;

    int genPoly = 0x8C;

    for (int i = 0; i 

    CRC ^= data[i];

    CRC &= 0xff;//保证CRC余码输出为1字节。

    for (int j = 0; j 

    if ((CRC & 0x01) != 0) {

    CRC = (CRC >> 1) ^ genPoly;

    CRC &= 0xff;//保证CRC余码输出为1字节。

    } else {

    CRC >>= 1;

    CRC &= 0xff;//保证CRC余码输出为1字节。

    }

    }

    }

    CRC &= 0xff;//保证CRC余码输出为1字节。

    return CRC;

    }

    }

    上述的CRC8算法根据计算出来的帧头,长度,功能码,数据体计算出来的结果为:75,与在线的crc(循环冗余校验算法)结果一致,如图所示:

    5f7f319b96f1a3f507f947bc5b1c3a78.png

    来源网站:太平洋学习网,转载请注明出处:http://www.tpyyes.com/a/java/1053.html

    展开全文
  • 使用simulink模型实现CRC8算法的Demo,也能实现其他CRC校验算法,对有simulink搭建CRC算法的朋友很有参考意义
  • CRC查表法——表的由来及Java实现CRC8校验算法
                         

    转载请标明出处: http://blog.csdn.net/xx326664162/article/details/51718857  文章出自:薛瑄的博客

    你也可以查看我的其他同类文章,也会让你有一定的收货!

    大概思路

    我先说一下查表法,表的计算方法,以CRC4为例:

    • 生成多项式:B = 10011B

    • 测试数据:A = 0011 1110B

    1、查表法实际上是利用XOR的交换律和结合律:(A XOR B)XOR C=A XOR (B XOR C)

    2、将测试数据A 每4bit分为一组,0011 0000B 和 1110B

    • 先计算出0011 0000B的CRC4值
    • 然后XOR下个4bit 1110B,再计算CRC4的值。

    分组举例:
    C1=00110000B,C2=1110B,C3=0011B.
    A = C1 XOR C2
    则 A XOR B =  (C1 XOR C2) XOR B =(C1 XOR B )XOR C2 

    可能你会产生几个问题:

    1、为什么要每4bit分为一组?

    注意: 由于每次处理多bit(假设是N),那么数据长度必须是N的倍数。

    • 以半字节为例,由于每次处理4bit,所以数据长度必须为4的倍数。
    • 如果非4的倍数,需要特殊处理(驱动表法和直接计算法混用)。

    例如,数据长度是74bit,前面72bit可以按照查表法,后面2bit则只能是直接计算法。

    每4bit一组,完全是为了方便计算

    2、就算分组,还不一样是要计算,那和直接计算有什么区别?

    可以事先计算出,0000B - 1111B所有数据,对应CRC的值,保存在程序中。这样将数据划分后,计算时遇到数据,直接查表得到对应CRC的值,省去了计算的过程。

    计算表:

    • 生成多项式:B = 10011B
    • 测试数据:A = 0011 1110B

    1、A对B的CRC 过程可以表示为:A XOR B1 XOR B

       ——————————————
    A  0 0 1 1 1 1 1 0 
           1 0 0 1 1 0  B1
           ——————————
             1 1 0 0 0
             1 0 0 1 1  B
             ————————
               1 0 1 1

    2、

    • 将测试数据A每4bit分组C1=00110000B,C2=1110B。A = C1 XOR C2

    • A XOR B1 XOR B = (C1 XOR C2)XOR B1 XOR B = (C1 XOR B1 XOR B XOR )C2

         ——————————————
      C1 0 0 1 1 0 0 0 0 
             1 0 0 1 1 0  B1
             ——————————
               1 0 1 1 0
               1 0 0 1 1  B
               ————————
                 0 1 0 1
      C2         1 1 1 0
                 ——————           
                 1 0 1 1
      这样就可以把数据CRC的计算,分为每4bit一组来计算CRC的值,因为4bit可表示16中情况,所以可以分别列出这些4bit数据对应的CRC值,以后直接拿来用,于是有了下表。

    3、多项式crc4的表格

                                                                                                         
    索引数据表值
    000000000
    100010011
    200100110
    300110101
    401001100
    501011111
    601101010
    701111001
    810001011
    910011000
    1010101101
    1110111110
    1211000111
    1311010100
    1411100001
    1511110010

    用查表法计算之前的例子:
       ——————————————
    A  0 0 1 1 1 1 1 0 
               0 1 0 1 表中查找数据0011对应的表值为0101
               ——————           
               1 0 1 1

    Java实现CRC8校验——查表法

    http://blog.csdn.net/trbbadboy/article/details/16859937
    http://www.javacui.com/Theory/218.html

    /**  * CRC8相关计算   * encode: utf-8  *   * @author trb  * @date 2013-11-21  */  public class CRC8 {      static byte[] crc8_tab = { (byte) 0, (byte) 94, (byte) 188, (byte) 226, (byte) 97, (byte) 63, (byte) 221, (byte) 131, (byte) 194, (byte) 156, (byte) 126, (byte) 32, (byte) 163, (byte) 253, (byte) 31, (byte) 65, (byte) 157, (byte) 195, (byte) 33, (byte) 127, (byte) 252, (byte) 162, (byte) 64, (byte) 30, (byte) 95, (byte) 1, (byte) 227, (byte) 189, (byte) 62, (byte) 96, (byte) 130, (byte) 220, (byte) 35, (byte) 125, (byte) 159, (byte) 193, (byte) 66, (byte) 28, (byte) 254, (byte) 160, (byte) 225, (byte) 191, (byte) 93, (byte) 3, (byte) 128, (byte) 222, (byte) 60, (byte) 98, (byte) 190, (byte) 224, (byte) 2, (byte) 92, (byte) 223, (byte) 129, (byte) 99, (byte) 61, (byte) 124, (byte) 34, (byte) 192, (byte) 158, (byte) 29, (byte) 67, (byte) 161, (byte) 255, (byte) 70, (byte) 24,              (byte) 250, (byte) 164, (byte) 39, (byte) 121, (byte) 155, (byte) 197, (byte) 132, (byte) 218, (byte) 56, (byte) 102, (byte) 229, (byte) 187, (byte) 89, (byte) 7, (byte) 219, (byte) 133, (byte) 103, (byte) 57, (byte) 186, (byte) 228, (byte) 6, (byte) 88, (byte) 25, (byte) 71, (byte) 165, (byte) 251, (byte) 120, (byte) 38, (byte) 196, (byte) 154, (byte) 101, (byte) 59, (byte) 217, (byte) 135, (byte) 4, (byte) 90, (byte) 184, (byte) 230, (byte) 167, (byte) 249, (byte) 27, (byte) 69, (byte) 198, (byte) 152, (byte) 122, (byte) 36, (byte) 248, (byte) 166, (byte) 68, (byte) 26, (byte) 153, (byte) 199, (byte) 37, (byte) 123, (byte) 58, (byte) 100, (byte) 134, (byte) 216, (byte) 91, (byte) 5, (byte) 231, (byte) 185, (byte) 140, (byte) 210, (byte) 48, (byte) 110, (byte) 237,              (byte) 179, (byte) 81, (byte) 15, (byte) 78, (byte) 16, (byte) 242, (byte) 172, (byte) 47, (byte) 113, (byte) 147, (byte) 205, (byte) 17, (byte) 79, (byte) 173, (byte) 243, (byte) 112, (byte) 46, (byte) 204, (byte) 146, (byte) 211, (byte) 141, (byte) 111, (byte) 49, (byte) 178, (byte) 236, (byte) 14, (byte) 80, (byte) 175, (byte) 241, (byte) 19, (byte) 77, (byte) 206, (byte) 144, (byte) 114, (byte) 44, (byte) 109, (byte) 51, (byte) 209, (byte) 143, (byte) 12, (byte) 82, (byte) 176, (byte) 238, (byte) 50, (byte) 108, (byte) 142, (byte) 208, (byte) 83, (byte) 13, (byte) 239, (byte) 177, (byte) 240, (byte) 174, (byte) 76, (byte) 18, (byte) 145, (byte) 207, (byte) 45, (byte) 115, (byte) 202, (byte) 148, (byte) 118, (byte) 40, (byte) 171, (byte) 245, (byte) 23, (byte) 73, (byte) 8,              (byte) 86, (byte) 180, (byte) 234, (byte) 105, (byte) 55, (byte) 213, (byte) 139, (byte) 87, (byte) 9, (byte) 235, (byte) 181, (byte) 54, (byte) 104, (byte) 138, (byte) 212, (byte) 149, (byte) 203, (byte) 41, (byte) 119, (byte) 244, (byte) 170, (byte) 72, (byte) 22, (byte) 233, (byte) 183, (byte) 85, (byte) 11, (byte) 136, (byte) 214, (byte) 52, (byte) 106, (byte) 43, (byte) 117, (byte) 151, (byte) 201, (byte) 74, (byte) 20, (byte) 246, (byte) 168, (byte) 116, (byte) 42, (byte) 200, (byte) 150, (byte) 21, (byte) 75, (byte) 169, (byte) 247, (byte) 182, (byte) 232, (byte) 10, (byte) 84, (byte) 215, (byte) 137, (byte) 107, 53 };      /**      * 计算数组的CRC8校验值      *       * @param data      *            需要计算的数组      * @return CRC8校验值      */      public static byte calcCrc8(byte[] data) {          return calcCrc8(data, 0, data.length, (byte) 0);      }      /**      * 计算CRC8校验值      *       * @param data      *            数据      * @param offset      *            起始位置      * @param len      *            长度      * @return 校验值      */      public static byte calcCrc8(byte[] data, int offset, int len) {          return calcCrc8(data, offset, len, (byte) 0);      }      /**      * 计算CRC8校验值      *       * @param data      *            数据      * @param offset      *            起始位置      * @param len      *            长度      * @param preval      *            之前的校验值      * @return 校验值      */      public static byte calcCrc8(byte[] data, int offset, int len, byte preval) {          byte ret = preval;          for (int i = offset; i < (offset + len); ++i) {              ret = crc8_tab[(0x00ff & (ret ^ data[i]))];          }          return ret;      }      // 测试      public static void main(String[] args) {          byte crc = CRC8.calcCrc8(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });          System.out.println("" + Integer.toHexString(0x00ff & crc));      }  }  
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67

    参考:http://www.xjtudll.cn/Exp/273/

     

    关注我的公众号,轻松了解和学习更多技术
      这里写图片描述

               

    再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

    展开全文
  • CRC8校验算法总结

    万次阅读 2019-09-02 17:37:36
    最近做项目时,一直在用crc8算法校验,但是编程平台多样,所以总结一下。使用的多项式是:X8 + X2 + X + 1 1 C语言 /************************************************************* * 函数名称: gh_crc8 * * ...

    最近做项目时,一直在用crc8算法做校验,但是编程平台多样,所以总结一下。使用的多项式是:X8 + X2 + X + 1

    1 C语言

    /*************************************************************
    *	函数名称:	gh_crc8
    *
    *	函数功能:	生成crc8 密匙
    *
    *	入口参数:	p_buffer 需要校验的数据首地址 buf_size:需要校验的数据的长度
    *
    *	返回参数:	生成的crc8 秘钥
    *
    *	说明:p_buffer的空间必须要要>=buf_size 此函数不负责检测数据溢出
    *************************************************************/
    static uint8_t gh_crc8( uint8_t * p_buffer, uint16_t buf_size )
    {
        uint8_t crc = 0;
        if(buf_size <= 0)
        {
            return crc;
        }
        while( buf_size-- )
        {
            for ( uint8_t i = 0x80; i != 0; i /= 2 )
            {
                if ( (crc & 0x80) != 0)
                {
                    crc *= 2;
                    crc ^= 0x07; // 多项式:X8 + X2 + X + 1
                }
                else
                {
                    crc *= 2;
                }
    
                if ( (*p_buffer & i) != 0 )
                {
                    crc ^= 0x07;
                }
            }
            p_buffer++;
        }
        return crc;
    }
    

    2 C#

            /*************************************************************
            *	函数名称:	gh_crc8
            *
            *	函数功能:	生成crc8 密匙
            *
            *	入口参数:	p_buffer 需要校验的数据首地址 buf_size:需要校验的数据的长度
            *
            *	返回参数:	生成的crc8 秘钥
            *
            *	说明:p_buffer的空间必须要要>=buf_size 此函数不负责检测数据溢出
            *************************************************************/
            private byte CRC8(byte[] buffer)
            {
                byte crc = 0;
    
                for (int j = 0; j < buffer.Length; j++)
                {
                    for (byte i = 0x80; i != 0; i /= 2)
                    {
                        if ((crc & 0x80) != 0)
                        {
                            crc *= 2;
                            crc ^= 0x07; // 多项式:X8 + X2 + X + 1
                        }
                        else
                        {
                            crc *= 2;
                        }
    
                        if ((buffer[j] & i) != 0)
                        {
                            crc ^= 0x07;
                        }
                    }
                }
                return crc;
            }
    

    3 JS

    const CHECKSUM_TABLE = [
      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
    ];
    
    function gh_crc8(buffer){
      let crc = new Uint8Array(1);
      crc = 0;
      for (let i = 0; i < buffer.length; i++) {
        crc = CHECKSUM_TABLE[(crc ^ (buffer[i] & 0xFF)) & 0xFF];
      }
      return (crc & 0xff);
    }
    

    以上算法经过实际测试可用!

    展开全文
  • 校验算法用C语言实现/* 代码片段,摘自:plat_lib.c */ 使用1个字节的校验和还是多个字节的校验和会在协议(protocol)中定义,另外,在数据包中,校验和的计算从哪个字节开始到哪个字节结束,也会在协议中定义。...

    所谓校验和,就是将被校验数据进行累加,并舍弃累加溢出的位,最终得到的1个或多个字节的结果。

    校验和算法用C语言实现
    /* 代码片段,摘自:plat_lib.c */
    /******************************************************************************
     *  @fn      uint8_t calc_checksum(uint8_t const *p_data, int32_t data_len)
     *
     *  @brief   计算校验和的算法,校验和占用1个字节。
     *
     *  @param   p_data    待校验数据的首地址
     *  @param   data_len  数据长度
     *
     *  @return  checksum, 0x00 ~ 0xFF
     */
    uint8_t calc_checksum(uint8_t const *p_data, int32_t data_len)
    {
        uint8_t sum = 0;
    
        while (data_len--) {
            sum += *p_data++;
        }
        
        return sum;
    }

    使用1个字节的校验和还是多个字节的校验和会在协议(protocol)中定义,另外,在数据包中,校验和的计算从哪个字节开始到哪个字节结束,也会在协议中定义。

    比如,某通信协议中,对包数据做如下定义:

    2b999321b117593079a9ca7bd7657e4d.png
    • 协议头:固定使用0xAA
    • 长度:数据部分的长度
    • 数据:元数据,最多20字节
    • 校验:对协议头长度数据进行累加,舍弃溢出的位。
    定义数据结构描述如下:
    /* 代码片段,摘自:protocol.h */
    #define MAX_DATA_LEN  20     /* 元数据的最大长度 */
    typedef struct tag_data_pack {
        uint8_t sop;                     /* 协议头 */
        uint8_t len;                     /* 长度 */
        uint8_t datas[MAX_DATA_LEN + 1]; /* 数据 + 1字节的校验 */
    }data_pack_t;
    C语言测试代码
    /* 代码片段,摘自:protocol.c */
    /******************************************************************************
     *  @fn      int32_t make_data_pack(uint8_t const *p_data, 
     *               int32_t data_len,
     *               data_pack_t *p_pack)
     *
     *  @brief   根据协议将元数据打包成数据包,并返回数据包的长度。
     *
     *  @param   p_data   元数据首地址
     *  @param   data_len 元数据长度
     *  @param   p_pack   数据包
     *
     *  @return  数据包的总长度
     */
    int32_t make_data_pack(uint8_t const *p_data, 
        int32_t data_len, 
        data_pack_t *p_pack)
    {
        // PF_ASSERT(NULL != p_data);
        // PF_ASSERT(data_len > 0);
        // PF_ASSERT(NULL != p_pack);
    
        p_pack->sop = 0xAA;
        p_pack->len = (uint8_t)data_len;
        memcpy(p_pack->datas, p_data, data_len);
        p_pack->datas[data_len] = 
            calc_checksum((uint8_t const *)p_pack, data_len + 2);
        
        /* 协议头,1字节;长度,1字节;校验,1字节 */
        return data_len + 3;
    }
    /* 代码片段,摘自:test.c */
    /******************************************************************************
     *  @fn      int main(int argc, char * argv[])
     *
     *  @brief   主函数
     *
     *  @param   argc 命令函传入的参数数量
     *  @param   argv 命令行传入的参数字符串数组
     *
     *  @return  0
     */
    int main(int argc, char * argv[])
    {
        data_pack_t pack;
        uint8_t user_data[] = {0x01, 0x02, 0x03, 0x04, 0x05};
        int32_t pack_len;
    
        pack_len = make_data_pack(user_data, sizeof(user_data), &pack);
    
        /* 以16进制形式打印数据包 */
        log_dump("pack", (uint8_t const *)&pack, pack_len);
        
        return 0;
    }
    Makefile
    TARGET = checksum_test
    SOURCE  := $(wildcard *.c) $(wildcard *.cpp)
    OBJS    := $(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SOURCE)))
    ​
    $(TARGET): $(OBJS)
        gcc -o $@ $(OBJS)
    clean:
        rm -rf *.o $(TARGET)
    测试结果
    // 编译
    [root@localhost checksum]# make
    cc    -c -o protocol.o protocol.c
    cc    -c -o plat_lib.o plat_lib.c
    cc    -c -o plat_log.o plat_log.c
    cc    -c -o test.o test.c
    gcc -o checksum_test protocol.o plat_lib.o plat_log.o test.o
    ​
    // 运行测试程序
    [root@localhost checksum]# ./checksum_test
    [pack], 0xAA, 0x05, 0x01, 0x02, 0x03, 0x04, 0x05, 0xBE
    优缺点

    校验和校验算法由于规则简单,因此算法也很简单,算法运行时占用系统资源少、计算速度非常快;缺点是当多个字节同时出现错误时,可能无法检出,比如:原始数据为:0xAA, 0x05, 0x01, 0x02, 0x03, 0x04, 0x05, 0xBE,有2个字节的数据出现错误:0xAA, 0x05, 0x02, 0x02, 0x02, 0x04, 0x05, 0xBE,通过校验和无法检出错误。

    展开全文
  • CDT协议中crc8校验算法

    2021-05-04 16:57:37
    本文计算方法均参考他人文档...void crc8_CDT_init(uint32_t poly) { uint16_t crc; for (int i = 0, j; i < 256; i++) { crc = 0x00FF & i; for (j = 0; j < 8; j++) { crc = 0x00FF & (((crc ..
  • CRC(Cyclic Redundancy Check,循环冗余校验)是数据帧传输中常用的一种差错控制编码方式,针对要发送的数据帧,使用一些特定的多项式可以计算出CRC校验结果,CRC校验结果和原始数据一起发送至接收端。接收端在接收...
  • 使用simulink的Generate CRC Generator模块 以下是一种实现方式: 实际模型:https://download.csdn.net/download/liuwinner/13214389 https://download.csdn.net/download/liuwinner/13214377 验证方法...
  • function crcnifull ($dato, $byte){static $PolyFull=0x8c;...8; $i++){$x=$byte&1;$byte>>=1;if ($dato&1) $byte|=0x80;if ($x) $byte^=$PolyFull;$dato>>=1;}return $byte;}fu...
  • IP/ICMP/IGMP/TCP/UDP等协议的校验算法都是相同的,算法如下:在发送数据时,为了计算数IP据报的校验和。应该按如下步骤:(1)把IP数据报的校验和字段置为0;(2)把首部看成以16位为单位的数字组成,依次进行二...
  • 算法的重要性不言而喻啦,每次求职之前刷 LeetCode 刷的头昏脑胀,大厂笔试时看到 Hard 级的算法题瞬间头皮发麻。算法是很重要,问题是如何更好的学习好算法才是关键 。一提到算法,大部分人应该都像我一样吧,立马...
  • 转载自:五分钟算法小吴花了几天时间整理了一下学习「数据结构与算法」可以参考的书籍,希望能在学习的道路上帮到你,文末提供收集的PDF版。一.入门系列 这些书籍通过图片、打比方等通俗易懂的方法来讲述,让你能达到...
  •  //函数体 } 演示结果: 3+5=8. 2函数原型和作用: (1)函数原型就是函数的声明,说白了就是函数的函数名、返回值类型、参数列表。 (2)函数原型的主要作用就是给编译器提供原型,让编译器在编译程序时帮我们进行参数...
  • Byte型CRC8校验算法使用

    千次阅读 2009-03-04 17:15:00
    //*******************************************************************************************/* CRC余式表 */const static crc_ta_Array[]={0x0, 0x0, 0x10, 0x21, 0x20, 0x42, 0x30, 0x63, 0x40, 0x84, 0x50
  • C#实现所有CRC8,CRC16,CRC32校验算法

    千次阅读 2019-12-01 15:50:23
    CRC8与串口大傻计算结果不一致 CRC16与串口大傻计算结果一致 CRC32与串口大傻计算结果一致,但4.5版本大傻计算结果最高字节始终为0 同时对16进制字符串11 22 33 进行校验计算结果如下 本算法结果如下: ...
  • 最近用到CRC校验算法,就找了些资料,学习了一下,网上关于CRC32的资料也多,但感觉不是很完整,或者太高深。CRC算法查表法很常见,但表是怎么来的,有些资料说得不很清楚。我来说一下我的看法:1.CRC校验变化太多,...
  • 最近使用PHP开发串口通信业务,在发送485Modbus命令时,基本都要...代码如下:/***crc16计算*传入字符串格式:001624180101*返回值格式:[高8位,低8位]*/functioncrc16($string){$string=pack('H*',$string);$crc=...
  • Java实现CRC16校验算法

    2021-03-12 16:36:16
    本文主要记录java版的crc校验算法,顺带贴上c的crc校验 先上c的校验函数,本文java版的校验就是根据此函数而来的,希望能帮到大家 当时开发时通过一个在线检验工具辅助开发的,工具连接:戳我 /** ****************...
  • Python CRC16校验算法

    2019-10-08 17:58:06
    def crc16(x, invert): a = 0xFFFF b = 0xA001 for byte in x: a ^= ord(byte) for i in range(8): last = a % 2 a >>= 1 i...
  • CRC校验算法

    2019-12-11 17:15:29
    发现网上好多人把CRC8校验算法搞错了,尤其是查表法,把多项式和表的对应关系搞错了,虽然对校验功能没有影响,但是明显是没有理解CRC8的算法过程。 当要校验字节为1时,table[1]肯定应该就是校验多项式,网上...
  • 并行输入的CRC32校验算法 module crc32 #(parameter N=4) ( input rst, /*async reset,active low*/ input clk, /*clock input*/ input [N*8-1:0] data_in, /*Serial ...
  • 查看RDB文件结构,发现最后的8字节是CRC64校验算得,从文件头开始直到8字节校验码前的FF结束码(含),经过CRC64校验计算发现,貌似最后的8字节是小端模式实现的。 参考redis的crc64实现的代码,点击查看 Java代码...
  • CRC16校验算法程序

    千次阅读 2017-07-13 16:12:43
    const unsigned char code auchCRCLo[] = { 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x8
  • C语言 CRC32校验算法

    万次阅读 2016-01-20 22:41:13
    内核中的linux 内核中的 crc32算法在..\linux-2.6.38\crypto\crc32c.c文件中,可做参考 /* * Cryptographic API. * * CRC32C chksum * *@Article{castagnoli-crc, * author = { Guy Castagnoli and Stefan ...
  • def crc16(x, invert):a = 0xFFFFb = 0xA001for byte in x:a ^= ord(byte)for i in range(8):last = a % 2a >>= 1if last == 1:a ^= bs = hex(a).upper()return s[4:6]+s[2:4] if invert == True else s[2:4]+...

空空如也

空空如也

1 2 3 4 5 ... 16
收藏数 303
精华内容 121
关键字:

crc8校验算法