UNPKG

modbus-connect

Version:

Modbus RTU over Web Serial and Node.js SerialPort

214 lines (201 loc) 5.6 kB
// utils/crc.js // CRC16 Modbus (полином 0x8005 в отражённом виде 0xA001, init 0xFFFF) function crc16Modbus(buffer) { let crc = 0xFFFF; for (let pos = 0; pos < buffer.length; pos++) { crc ^= buffer[pos]; for (let i = 0; i < 8; i++) { if ((crc & 0x0001) !== 0) { crc >>= 1; crc ^= 0xA001; } else { crc >>= 1; } } } return new Uint8Array([crc & 0xFF, (crc >> 8) & 0xFF]); } // CRC16-CCITT-FALSE (полином 0x1021, init 0xFFFF, без отражения) function crc16CcittFalse(buffer) { let crc = 0xFFFF; for (let pos = 0; pos < buffer.length; pos++) { crc ^= (buffer[pos] << 8); for (let i = 0; i < 8; i++) { if ((crc & 0x8000) !== 0) { crc = (crc << 1) ^ 0x1021; } else { crc <<= 1; } crc &= 0xFFFF; // Ограничение 16 бит } } return new Uint8Array([(crc >> 8) & 0xFF, crc & 0xFF]); // Big-endian } // CRC32 (полином 0x04C11DB7, init 0xFFFFFFFF, отражение и финальный XOR) function crc32(buffer) { let crc = 0xFFFFFFFF; for (let pos = 0; pos < buffer.length; pos++) { crc ^= buffer[pos]; for (let i = 0; i < 8; i++) { if ((crc & 1) !== 0) { crc = (crc >>> 1) ^ 0xEDB88320; } else { crc >>>= 1; } } } crc ^= 0xFFFFFFFF; return new Uint8Array([ crc & 0xFF, (crc >>> 8) & 0xFF, (crc >>> 16) & 0xFF, (crc >>> 24) & 0xFF ]); // Little-endian } // CRC8 (полином 0x07, init 0x00, без отражения) function crc8(buffer) { let crc = 0x00; for (let pos = 0; pos < buffer.length; pos++) { crc ^= buffer[pos]; for (let i = 0; i < 8; i++) { if ((crc & 0x80) !== 0) { crc = (crc << 1) ^ 0x07; } else { crc <<= 1; } crc &= 0xFF; // Ограничение 8 бит } } return new Uint8Array([crc]); } // CRC-1 (простейший CRC, полином 0x01, init 0x00) function crc1(buffer) { let crc = 0x00; for (let byte of buffer) { for (let i = 0; i < 8; i++) { crc ^= (byte >> (7 - i)) & 0x01; } } return new Uint8Array([crc & 0x01]); } // CRC-8 1-Wire (полином 0x31, init 0x00, отражение, нет финального XOR) function crc8_1wire(buffer) { let crc = 0x00; for (let b of buffer) { crc ^= b; for (let i = 0; i < 8; i++) { if (crc & 0x01) { crc = (crc >> 1) ^ 0x8C; // отражённый 0x31 → 0x8C } else { crc >>= 1; } } } return new Uint8Array([crc]); } // CRC-8 DVB-S2 (полином 0xD5, init 0x00, нет отражения и финального XOR) function crc8_dvbs2(buffer) { let crc = 0x00; for (let b of buffer) { crc ^= b; for (let i = 0; i < 8; i++) { crc = (crc & 0x80) ? ((crc << 1) ^ 0xD5) : (crc << 1); crc &= 0xFF; } } return new Uint8Array([crc]); } // CRC-16 Kermit (полином 0x1021, init 0x0000, отражение, финальный XOR = 0x0000) function crc16_kermit(buffer) { let crc = 0x0000; for (let b of buffer) { crc ^= b; for (let i = 0; i < 8; i++) { if (crc & 0x0001) { crc = (crc >> 1) ^ 0x8408; // отражённый 0x1021 } else { crc >>= 1; } } } return new Uint8Array([crc & 0xFF, (crc >> 8) & 0xFF]); } // CRC-16 XModem (полином 0x1021, init 0x0000, без отражения) function crc16_xmodem(buffer) { let crc = 0x0000; for (let b of buffer) { crc ^= (b << 8); for (let i = 0; i < 8; i++) { crc = (crc & 0x8000) ? ((crc << 1) ^ 0x1021) : (crc << 1); crc &= 0xFFFF; } } return new Uint8Array([(crc >> 8) & 0xFF, crc & 0xFF]); } // CRC-24 (полином 0x864CFB, init 0xB704CE) — часто используется в Bluetooth, OpenPGP function crc24(buffer) { let crc = 0xB704CE; for (let b of buffer) { crc ^= (b << 16); for (let i = 0; i < 8; i++) { crc = (crc & 0x800000) ? ((crc << 1) ^ 0x864CFB) : (crc << 1); crc &= 0xFFFFFF; } } return new Uint8Array([ (crc >> 16) & 0xFF, (crc >> 8) & 0xFF, crc & 0xFF ]); } // CRC-32 MPEG-2 (полином 0x04C11DB7, init 0xFFFFFFFF, без отражения, финальный XOR = 0x00000000) function crc32mpeg(buffer) { let crc = 0xFFFFFFFF; for (let b of buffer) { crc ^= (b << 24); for (let i = 0; i < 8; i++) { crc = (crc & 0x80000000) ? ((crc << 1) ^ 0x04C11DB7) : (crc << 1); crc >>>= 0; // Принудительно как unsigned 32-bit } } return new Uint8Array([ (crc >>> 24) & 0xFF, (crc >>> 16) & 0xFF, (crc >>> 8) & 0xFF, crc & 0xFF ]); } // CRC-JAM (иногда называют CRC-32-JAMCRC, как CRC-32, но без финального XOR) function crcjam(buffer) { let crc = 0xFFFFFFFF; for (let b of buffer) { crc ^= b; for (let i = 0; i < 8; i++) { if ((crc & 1) !== 0) { crc = (crc >>> 1) ^ 0xEDB88320; } else { crc >>>= 1; } } } return new Uint8Array([ crc & 0xFF, (crc >>> 8) & 0xFF, (crc >>> 16) & 0xFF, (crc >>> 24) & 0xFF ]); } module.exports = { crc16Modbus, crc16CcittFalse, crc32, crc8, crc1, crc8_1wire, crc8_dvbs2, crc16_kermit, crc16_xmodem, crc24, crc32mpeg, crcjam }