最近做蓝牙连接手环发送请求时,数据传输时需要把CRC16生成的校验码拼接到真实数据后面
// 方式1
function C16func(cData, cLen) {
if (((cData << cLen).toString(2).length > 16) && (cData.toString(2).length <= 16)) {
cData = (cData << cLen).toString(2).substr((cData << cLen).toString(2).length - 16, 16);
cData = parseInt(cData, 2);
} else {
cData = cData << cLen;
}
return cData;
}
function CRC16(aData) {
let cnCRC_CCITT = 0x1021;
let i = -1,
j = -1;
let nData = -1,
nAccum = -1,
nYAccum = -1;
let Table_CRC = [];
let aSize = aData.length;
for (i = 0; i < 256; i++) {
nData = C16func.call(this, i, 8);
nAccum = 0;
for (j = 0; j < 8; j++) {
if ((nData ^ nAccum) & 0x8000) {
nAccum = C16func.call(this, nAccum, 1);
nAccum = nAccum ^ cnCRC_CCITT;
} else {
nAccum = C16func.call(this, nAccum, 1);
nAccum = nAccum;
}
nData = C16func.call(this, nData, 1);
}
Table_CRC[i] = nAccum;
}
nAccum = 0;
for (i = 0; i < aSize; i++) {
nYAccum = nAccum;
nAccum = C16func.call(this, nAccum, 8);
nAccum = nAccum ^ Table_CRC[(nYAccum >>> 8) ^ (aData[i])]; //数组
// nAccum = nAccum ^ Table_CRC[(nYAccum >>> 8) ^ (AllDATA.charCodeAt(i))];//字符串
}
return nAccum.toString(16).toUpperCase().padStart(4, '0');
}
// 使用
CRC16([0x01,0x02,...])
// 方式二
const parse = (s) => {
let result = s.toString(16).toUpperCase()
return result.padStart(4, 0);
}
const convert = (c) => {
const code = c.charCodeAt();
if ('0'.charCodeAt() <= code && code <= '9'.charCodeAt()) {
return (code - '0'.charCodeAt());
} else if ('A'.charCodeAt() <= code && code <= 'F'.charCodeAt()) {
return (code - 'A'.charCodeAt() + 0x0A);
} else if ('a'.charCodeAt() <= code && code <= 'f'.charCodeAt()) {
return (code - 'a'.charCodeAt() + 0x0a);
}
}
const crc16 = (s) => {
const codes = Array.from(s);
let result = 0x00;
const remainder = 0x1021;
const len = s.length / 2;
for (let i = 0, j = 0; i < len; i++) {
const b = convert(codes[j++]) << 4 | convert(codes[j++]);
for (let i = 0; i < 8; i++) {
let bit = ((b >> (7 - i) & 1) == 1);
let c15 = ((result >> 15 & 1) == 1);
result <<= 1;
if (c15 ^ bit) result ^= remainder;
}
}
result &= 0xffff;
return parse(result);
};
// 使用
crc16('0102')