/** * CRC 校验算法(CAIIC BLE 协议 V1.0) * - crc16Ccitt: 帧校验,CRC16-CCITT poly 0x1021 初值 0xFFFF * - crc32Ieee : 固件镜像校验,zlib CRC32 poly 0xEDB88320 初值/异或出 0xFFFFFFFF * * 注意:uts number 位运算按 32 位有符号处理,CRC32 中间值全部保持在 Int 范围内, * 无符号右移用 (x >> 1) & 0x7FFFFFFF 实现;最终返回值转为无符号(0..2^32-1)。 */ // 0xEDB88320 的 32 位补码形式(避免字面量超出 Int 范围) const CRC32_POLY = -306674912 export function crc16Ccitt(data: number[], offset: number, len: number): number { let crc = 0xFFFF for (let i = offset; i < offset + len; i++) { crc = crc ^ ((data[i] & 0xFF) << 8) for (let k = 0; k < 8; k++) { if ((crc & 0x8000) != 0) { crc = ((crc << 1) ^ 0x1021) & 0xFFFF } else { crc = (crc << 1) & 0xFFFF } } } return crc } export function crc32Ieee(data: number[]): number { let crc = -1 // 0xFFFFFFFF for (let i = 0; i < data.length; i++) { crc = crc ^ (data[i] & 0xFF) for (let k = 0; k < 8; k++) { const shifted = (crc >> 1) & 0x7FFFFFFF if ((crc & 1) != 0) { crc = shifted ^ CRC32_POLY } else { crc = shifted } } } crc = crc ^ -1 // 转为无符号返回值(避免后续 >> 算术右移出问题) if (crc < 0) { return crc + 4294967296 } return crc }