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除法流程,硬件复杂度低且漏检率优于传统校验方案

相关推荐
狂团商城小师妹3 小时前
XYlease租赁商城小程序
微信·微信小程序·小程序
weixin_177297220693 小时前
家政小程序系统开发:打造便捷高效的家政服务平台
大数据·小程序·家政
非专业程序员Ping4 小时前
从0到1自定义文字排版引擎:原理篇
ios·swift·assembly·font
2501_915909064 小时前
“绑定 HTTPS” 的工程全流程 从证书配置到真机验证与故障排查
网络协议·http·ios·小程序·https·uni-app·iphone
2501_915918415 小时前
iOS 混淆实战 多工具组合完成 IPA 混淆、加固与工程化落地(iOS混淆|IPA加固|无源码混淆|Ipa Guard|Swift Shield)
android·ios·小程序·https·uni-app·iphone·webview
雨白5 小时前
让协程更健壮:全面的异常处理策略
android·kotlin
Jeled6 小时前
AI: 生成Android自我学习路线规划与实战
android·学习·面试·kotlin
游戏开发爱好者88 小时前
如何系统化掌握 iOS 26 App 耗电管理,多工具协作
android·macos·ios·小程序·uni-app·cocoa·iphone
shaominjin1238 小时前
android在sd卡中可以mkdir, 但是不可以createNewFile
android·开发语言·python