ios android 小程序 蓝牙 CRC16_MODBUS

安卓 MODBUS

复制代码
   public static int CRC16_MODBUS(byte[] source, int offset, int length) {
            int wCRCin = 0xFFFF;
            // Integer.reverse(0x8005) >>> 16
            int wCPoly = 0xA001;
            for (int i = offset, cnt = offset + length; i < cnt; i++) {
                wCRCin ^= ((int) source[i] & 0x00FF);
                for (int j = 0; j < 8; j++) {
                    if ((wCRCin & 0x0001) != 0) {
                        wCRCin >>= 1;
                        wCRCin ^= wCPoly;
                    } else {
                        wCRCin >>= 1;
                    }
                }
            }
            return wCRCin ^= 0x0000;
        }

调用:

int crc16 = CRC16_MODBUS(data,0,data.length-3);

参数 1. 数组 2.数组的第几个开始参与MODBUS 3 .数组的第几个到第几个参与MODBUS

苹果 MODBUS

复制代码
//const uint8_t *data   是结构体地址。
uint16_t CRC16ModbusByteCalc(const uint8_t *data, uint8_t length) {
    uint16_t tmp = 0xFFFF;
    uint16_t ret1;
    for (int n = 0; n < length; n++) {
        tmp = data[n] ^ tmp;
        for (int i = 0; i < 8; i++) {
            if (tmp & 0x01) {
                tmp = tmp >> 1;
                tmp = tmp ^ 0xA001;
            } else {
                tmp = tmp >> 1;
            }
        }
    }
    /* CRC校验后的值 */
    printf("CRC校验结果为: %X \n",tmp);
    
    /* 如需要:将CRC校验小端输出 */
    ret1 = tmp >> 8;
    ret1 = ret1 | (tmp << 8);
    printf("CRC校验结果小端: %X \n",ret1);
    
    return (tmp);
}

//求 CRC 数组的和  
unsigned short CRC16(unsigned char *puchMsg,unsigned   short usDataLen )
{
unsigned char uchCRCHi = 0xFF ; /* 高CRC字节初始化 */
unsigned char uchCRCLo = 0xFF ; /* 低CRC 字节初始化 */
unsigned uIndex ; /* CRC循环中的索引 */
uIndex = 0x01 ^ 0x02;
while (usDataLen--) /* 传输消息缓冲区 */
{
    uIndex = uchCRCHi ^ (*puchMsg++); /* 计算CRC */
    //(*puchMsg)++;
    uchCRCHi = uchCRCLo ^ (auchCRCHi[uIndex]);
    uchCRCLo = auchCRCLo[uIndex];
}
// 左移前uchCRCHi先转换为unsigned short,否则就变成0了。
 return (uchCRCHi << 8 | uchCRCLo) ;
// return (unsigned short)((unsigned short)uchCRCHi << 8 | uchCRCLo) ;
}

   short  a= CRC16(&struct,17);

调用

int16_t reValue1 = CRC16ModbusByteCalc(&struct, 14);


安卓其它CRC加密 比如 USB CRC16_MAXIM

java 复制代码
package com.sbas.utils;

public class CrcUtils {
    public static class CRC8 {
        public static int CRC8(byte[] source, int offset, int length) {
            int wCRCin = 0x00;
            int wCPoly = 0x07;
            for (int i = offset, cnt = offset + length; i < cnt; i++) {
                for (int j = 0; j < 8; j++) {
                    boolean bit = ((source[i] >> (7 - j) & 1) == 1);
                    boolean c07 = ((wCRCin >> 7 & 1) == 1);
                    wCRCin <<= 1;
                    if (c07 ^ bit)
                        wCRCin ^= wCPoly;
                }
            }
            wCRCin &= 0xFF;
            return wCRCin ^= 0x00;
        }

        public static int CRC8_DARC(byte[] source, int offset, int length) {
            int wCRCin = 0x00;
            // Integer.reverse(0x39) >>> 24
            int wCPoly = 0x9C;
            for (int i = offset, cnt = offset + length; i < cnt; i++) {
                wCRCin ^= ((long) source[i] & 0xFF);
                for (int j = 0; j < 8; j++) {
                    if ((wCRCin & 0x01) != 0) {
                        wCRCin >>= 1;
                        wCRCin ^= wCPoly;
                    } else {
                        wCRCin >>= 1;
                    }
                }
            }
            return wCRCin ^= 0x00;
        }

        public static int CRC8_ITU(byte[] source, int offset, int length) {
            int wCRCin = 0x00;
            int wCPoly = 0x07;
            for (int i = offset, cnt = offset + length; i < cnt; i++) {
                for (int j = 0; j < 8; j++) {
                    boolean bit = ((source[i] >> (7 - j) & 1) == 1);
                    boolean c07 = ((wCRCin >> 7 & 1) == 1);
                    wCRCin <<= 1;
                    if (c07 ^ bit)
                        wCRCin ^= wCPoly;
                }
            }
            wCRCin &= 0xFF;
            return wCRCin ^= 0x55;
        }

        public static int CRC8_MAXIM(byte[] source, int offset, int length) {
            int wCRCin = 0x00;
            // Integer.reverse(0x31) >>> 24
            int wCPoly = 0x8C;
            for (int i = offset, cnt = offset + length; i < cnt; i++) {
                wCRCin ^= ((long) source[i] & 0xFF);
                for (int j = 0; j < 8; j++) {
                    if ((wCRCin & 0x01) != 0) {
                        wCRCin >>= 1;
                        wCRCin ^= wCPoly;
                    } else {
                        wCRCin >>= 1;
                    }
                }
            }
            return wCRCin ^= 0x00;
        }

        public static int CRC8_ROHC(byte[] source, int offset, int length) {
            int wCRCin = 0xFF;
            // Integer.reverse(0x07) >>> 24
            int wCPoly = 0xE0;
            for (int i = offset, cnt = offset + length; i < cnt; i++) {
                wCRCin ^= ((long) source[i] & 0xFF);
                for (int j = 0; j < 8; j++) {
                    if ((wCRCin & 0x01) != 0) {
                        wCRCin >>= 1;
                        wCRCin ^= wCPoly;
                    } else {
                        wCRCin >>= 1;
                    }
                }
            }
            return wCRCin ^= 0x00;
        }

    }
    public static class CRC16 {
        public static int CRC16_IBM(byte[] source, int offset, int length) {
            int wCRCin = 0x0000;
            // Integer.reverse(0x8005) >>> 16
            int wCPoly = 0xA001;
            for (int i = offset, cnt = offset + length; i < cnt; i++) {
                wCRCin ^= ((int) source[i] & 0x00FF);
                for (int j = 0; j < 8; j++) {
                    if ((wCRCin & 0x0001) != 0) {
                        wCRCin >>= 1;
                        wCRCin ^= wCPoly;
                    } else {
                        wCRCin >>= 1;
                    }
                }
            }
            return wCRCin ^= 0x0000;
        }

        public static int CRC16_CCITT(byte[] source, int offset, int length) {
            int wCRCin = 0x0000;
            // Integer.reverse(0x1021) >>> 16
            int wCPoly = 0x8408;
            for (int i = offset, cnt = offset + length; i < cnt; i++) {
                wCRCin ^= ((int) source[i] & 0x00FF);
                for (int j = 0; j < 8; j++) {
                    if ((wCRCin & 0x0001) != 0) {
                        wCRCin >>= 1;
                        wCRCin ^= wCPoly;
                    } else {
                        wCRCin >>= 1;
                    }
                }
            }
            return wCRCin ^= 0x0000;
        }

        public static int CRC16_CCITT_FALSE(byte[] source, int offset, int length) {
            int wCRCin = 0xFFFF;
            int wCPoly = 0x1021;
            for (int i = offset, cnt = offset + length; i < cnt; i++) {
                for (int j = 0; j < 8; j++) {
                    boolean bit = ((source[i] >> (7 - j) & 1) == 1);
                    boolean c15 = ((wCRCin >> 15 & 1) == 1);
                    wCRCin <<= 1;
                    if (c15 ^ bit)
                        wCRCin ^= wCPoly;
                }
            }
            wCRCin &= 0xFFFF;
            return wCRCin ^= 0x0000;
        }

        public static int CRC16_DECT_R(byte[] source, int offset, int length) {
            int wCRCin = 0x0000;
            int wCPoly = 0x0589;
            for (int i = offset, cnt = offset + length; i < cnt; i++) {
                for (int j = 0; j < 8; j++) {
                    boolean bit = ((source[i] >> (7 - j) & 1) == 1);
                    boolean c15 = ((wCRCin >> 15 & 1) == 1);
                    wCRCin <<= 1;
                    if (c15 ^ bit)
                        wCRCin ^= wCPoly;
                }
            }
            wCRCin &= 0xFFFF;
            return wCRCin ^= 0x0001;
        }

        public static int CRC16_DECT_X(byte[] source, int offset, int length) {
            int wCRCin = 0x0000;
            int wCPoly = 0x0589;
            for (int i = offset, cnt = offset + length; i < cnt; i++) {
                for (int j = 0; j < 8; j++) {
                    boolean bit = ((source[i] >> (7 - j) & 1) == 1);
                    boolean c15 = ((wCRCin >> 15 & 1) == 1);
                    wCRCin <<= 1;
                    if (c15 ^ bit)
                        wCRCin ^= wCPoly;
                }
            }
            wCRCin &= 0xFFFF;
            return wCRCin ^= 0x0000;
        }

        public static int CRC16_DNP(byte[] source, int offset, int length) {
            int wCRCin = 0x0000;
            // Integer.reverse(0x3D65) >>> 16
            int wCPoly = 0xA6BC;
            for (int i = offset, cnt = offset + length; i < cnt; i++) {
                wCRCin ^= ((int) source[i] & 0x00FF);
                for (int j = 0; j < 8; j++) {
                    if ((wCRCin & 0x0001) != 0) {
                        wCRCin >>= 1;
                        wCRCin ^= wCPoly;
                    } else {
                        wCRCin >>= 1;
                    }
                }
            }
            return wCRCin ^= 0xFFFF;
        }

        public static int CRC16_GENIBUS(byte[] source, int offset, int length) {
            int wCRCin = 0xFFFF;
            int wCPoly = 0x1021;
            for (int i = offset, cnt = offset + length; i < cnt; i++) {
                for (int j = 0; j < 8; j++) {
                    boolean bit = ((source[i] >> (7 - j) & 1) == 1);
                    boolean c15 = ((wCRCin >> 15 & 1) == 1);
                    wCRCin <<= 1;
                    if (c15 ^ bit)
                        wCRCin ^= wCPoly;
                }
            }
            wCRCin &= 0xFFFF;
            return wCRCin ^= 0xFFFF;
        }

        public static int CRC16_MAXIM(byte[] source, int offset, int length) {
            int wCRCin = 0x0000;
            // Integer.reverse(0x8005) >>> 16
            int wCPoly = 0xA001;
            for (int i = offset, cnt = offset + length; i < cnt; i++) {
                wCRCin ^= ((int) source[i] & 0x00FF);
                for (int j = 0; j < 8; j++) {
                    if ((wCRCin & 0x0001) != 0) {
                        wCRCin >>= 1;
                        wCRCin ^= wCPoly;
                    } else {
                        wCRCin >>= 1;
                    }
                }
            }
            return wCRCin ^= 0xFFFF;
        }

        public static int CRC16_MODBUS(byte[] source, int offset, int length) {
            int wCRCin = 0xFFFF;
            // Integer.reverse(0x8005) >>> 16
            int wCPoly = 0xA001;
            for (int i = offset, cnt = offset + length; i < cnt; i++) {
                wCRCin ^= ((int) source[i] & 0x00FF);
                for (int j = 0; j < 8; j++) {
                    if ((wCRCin & 0x0001) != 0) {
                        wCRCin >>= 1;
                        wCRCin ^= wCPoly;
                    } else {
                        wCRCin >>= 1;
                    }
                }
            }
            return wCRCin ^= 0x0000;
        }

        public static int CRC16_USB(byte[] source, int offset, int length) {
            int wCRCin = 0xFFFF;
            // Integer.reverse(0x8005) >>> 16
            int wCPoly = 0xA001;
            for (int i = offset, cnt = offset + length; i < cnt; i++) {
                wCRCin ^= ((int) source[i] & 0x00FF);
                for (int j = 0; j < 8; j++) {
                    if ((wCRCin & 0x0001) != 0) {
                        wCRCin >>= 1;
                        wCRCin ^= wCPoly;
                    } else {
                        wCRCin >>= 1;
                    }
                }
            }
            return wCRCin ^= 0xFFFF;
        }

        public static int CRC16_X25(byte[] source, int offset, int length) {
            int wCRCin = 0xFFFF;
            // Integer.reverse(0x1021) >>> 16
            int wCPoly = 0x8408;
            for (int i = offset, cnt = offset + length; i < cnt; i++) {
                wCRCin ^= ((int) source[i] & 0x00FF);
                for (int j = 0; j < 8; j++) {
                    if ((wCRCin & 0x0001) != 0) {
                        wCRCin >>= 1;
                        wCRCin ^= wCPoly;
                    } else {
                        wCRCin >>= 1;
                    }
                }
            }
            return wCRCin ^= 0xFFFF;
        }

        public static int CRC16_XMODEM(byte[] source, int offset, int length) {
            int wCRCin = 0x0000;
            int wCPoly = 0x1021;
            for (int i = offset, cnt = offset + length; i < cnt; i++) {
                for (int j = 0; j < 8; j++) {
                    boolean bit = ((source[i] >> (7 - j) & 1) == 1);
                    boolean c15 = ((wCRCin >> 15 & 1) == 1);
                    wCRCin <<= 1;
                    if (c15 ^ bit)
                        wCRCin ^= wCPoly;
                }
            }
            wCRCin &= 0xFFFF;
            return wCRCin ^= 0x0000;
        }

    }

    public static class CRC32 {
        public static long CRC32(byte[] source, int offset, int length) {
            long wCRCin = 0xFFFFFFFFL;
            // Long.reverse(0x04C11DB7L) >>> 32
            long wCPoly = 0xEDB88320L;
            for (int i = offset, cnt = offset + length; i < cnt; i++) {
                wCRCin ^= ((long) source[i] & 0x000000FFL);
                for (int j = 0; j < 8; j++) {
                    if ((wCRCin & 0x00000001L) != 0) {
                        wCRCin >>= 1;
                        wCRCin ^= wCPoly;
                    } else {
                        wCRCin >>= 1;
                    }
                }
            }
            return wCRCin ^= 0xFFFFFFFFL;
        }

        public static long CRC32_B(byte[] source, int offset, int length) {
            long wCRCin = 0xFFFFFFFFL;
            long wCPoly = 0x04C11DB7L;
            for (int i = offset, cnt = offset + length; i < cnt; i++) {
                for (int j = 0; j < 8; j++) {
                    boolean bit = ((source[i] >> (7 - j) & 1) == 1);
                    boolean c31 = ((wCRCin >> 31 & 1) == 1);
                    wCRCin <<= 1;
                    if (c31 ^ bit) {
                        wCRCin ^= wCPoly;
                    }
                }
            }
            wCRCin &= 0xFFFFFFFFL;
            return wCRCin ^= 0xFFFFFFFFL;
        }

        public static long CRC32_C(byte[] source, int offset, int length) {
            long wCRCin = 0xFFFFFFFFL;
            // Long.reverse(0x1EDC6F41L) >>> 32
            long wCPoly = 0x82F63B78L;
            for (int i = offset, cnt = offset + length; i < cnt; i++) {
                wCRCin ^= ((long) source[i] & 0x000000FFL);
                for (int j = 0; j < 8; j++) {
                    if ((wCRCin & 0x00000001L) != 0) {
                        wCRCin >>= 1;
                        wCRCin ^= wCPoly;
                    } else {
                        wCRCin >>= 1;
                    }
                }
            }
            return wCRCin ^= 0xFFFFFFFFL;
        }

        public static long CRC32_D(byte[] source, int offset, int length) {
            long wCRCin = 0xFFFFFFFFL;
            // Long.reverse(0xA833982BL) >>> 32
            long wCPoly = 0xD419CC15L;
            for (int i = offset, cnt = offset + length; i < cnt; i++) {
                wCRCin ^= ((long) source[i] & 0x000000FFL);
                for (int j = 0; j < 8; j++) {
                    if ((wCRCin & 0x00000001L) != 0) {
                        wCRCin >>= 1;
                        wCRCin ^= wCPoly;
                    } else {
                        wCRCin >>= 1;
                    }
                }
            }
            return wCRCin ^= 0xFFFFFFFFL;
        }

        public static long CRC32_MPEG_2(byte[] source, int offset, int length) {
            long wCRCin = 0xFFFFFFFFL;
            long wCPoly = 0x04C11DB7L;
            for (int i = offset, cnt = offset + length; i < cnt; i++) {
                for (int j = 0; j < 8; j++) {
                    boolean bit = ((source[i] >> (7 - j) & 1) == 1);
                    boolean c31 = ((wCRCin >> 31 & 1) == 1);
                    wCRCin <<= 1;
                    if (c31 ^ bit) {
                        wCRCin ^= wCPoly;
                    }
                }
            }
            wCRCin &= 0xFFFFFFFFL;
            return wCRCin ^= 0x00000000L;
        }

        public static long CRC32_POSIX(byte[] source, int offset, int length) {
            long wCRCin = 0x00000000L;
            long wCPoly = 0x04C11DB7L;
            for (int i = offset, cnt = offset + length; i < cnt; i++) {
                for (int j = 0; j < 8; j++) {
                    boolean bit = ((source[i] >> (7 - j) & 1) == 1);
                    boolean c31 = ((wCRCin >> 31 & 1) == 1);
                    wCRCin <<= 1;
                    if (c31 ^ bit) {
                        wCRCin ^= wCPoly;
                    }
                }
            }
            wCRCin &= 0xFFFFFFFFL;
            return wCRCin ^= 0xFFFFFFFFL;
        }
    }
}

冗余位是循环冗余校验(CRC)中用于检测数据传输错误的附加校验位,其核心原理是通过生成多项式对数据块进行编码,生成可被多项式整除的二进制序列并附加冗余位,接收端通过相同多项式验证余数以判断传输正确性 1。该技术利用模2除法运算,发送端在数据末尾补零后除以生成多项式,所得余数作为校验码附加发送;接收端重复运算,余数非零则判定存在差错并触发重传 2。

循环冗余码的生成多项式决定校验位长度和错误检测能力,如CRC-32、CRC-16等标准差异在于多项式选择及校验位长度 1-2。CRC可检测所有奇数位错、双比特错及小于校验位长度的突发错误,适用于以太网、蓝牙、存储设备等场景。其实现基于异或运算简化模2除法流程,硬件复杂度低且漏检率优于传统校验方案

相关推荐
茶底世界之下36 分钟前
阴天窗边的柿子:用 Awaking 让暖色成为主角
ios·app·产品
普通人64 小时前
MySQL_FIND_IN_SET函数详解
android·数据库·mysql
好的佩奇15 小时前
Dart 之集合元素
android·flutter·dart
Easyhood16 小时前
Android 开发入门实践(十四):Compose 副作用入门与四个常用 API
android·开发语言·kotlin·android jetpack·compose
FlightYe17 小时前
音视频修炼之容器与协议(四):RTSP详解
android·linux·ffmpeg·音视频·dash
kango18 小时前
iOS 远程推送全链路拆解:从 deviceToken 到多账号绑定
ios·app
疯华整猫19 小时前
删掉 LeakCanary 那天,我用 Trae 自己撸了一套:最难的不是分析堆,是决定什么时候 dump
android·人工智能·性能优化
李纲明1 天前
微信小程序 getSystemInfo 提示已废弃、屏幕高度算错胶囊还对不齐?getWindowInfo 和 getDeviceInfo 怎么接才稳
javascript·微信小程序·小程序·小程序开发·devdiy
dreams_dream1 天前
微信小程序-使用npm包
微信小程序·小程序·npm
mmsx1 天前
耳切法切带洞多边形:论文能跑通,真实数据为什么崩
android·kotlin