48 lines
1.3 KiB
Plaintext
48 lines
1.3 KiB
Plaintext
/**
|
||
* 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
|
||
}
|