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

相关推荐
Daniel_Coder3 小时前
iOS Widget 开发-9:可配置 Widget:使用 IntentConfiguration 实现参数选择
ios·swiftui·swift·widget·intents
百锦再3 小时前
第11章 泛型、trait与生命周期
android·网络·人工智能·python·golang·rust·go
会跑的兔子4 小时前
Android 16 Kotlin协程 第二部分
android·windows·kotlin
键来大师4 小时前
Android15 RK3588 修改默认不锁屏不休眠
android·java·framework·rk3588
非专业程序员Ping5 小时前
Vibe Coding 实战!花了两天时间,让 AI 写了一个富文本渲染引擎!
ios·ai·swift·claude·vibecoding
江上清风山间明月6 小时前
Android 系统超级实用的分析调试命令
android·内存·调试·dumpsys
百锦再7 小时前
第12章 测试编写
android·java·开发语言·python·rust·go·erlang
00后程序员张7 小时前
HTTP抓包工具推荐,Fiddler配置方法、代理设置与使用教程详解(开发者必学网络调试技巧)
网络·http·ios·小程序·fiddler·uni-app·webview
2501_940094028 小时前
iphone Delta模拟器如何从夸克网盘导入游戏ROM 附游戏资源下载
游戏·ios·iphone
悟空码字9 小时前
微信小程序管理系统,代运营3600+医院小程序
微信·小程序·编程·软件开发