/** * Calculates CRC16 according to the UHF Reader Manual. * Polynomial: 0x8408 * Preset: 0xFFFF */ export const calculateCRC16 = (data: Uint8Array): number => { const PRESET_VALUE = 0xFFFF; const POLYNOMIAL = 0x8408; let uiCrcValue = PRESET_VALUE; for (let i = 0; i < data.length; i++) { uiCrcValue = uiCrcValue ^ data[i]; for (let j = 0; j < 8; j++) { if ((uiCrcValue & 0x0001) !== 0) { uiCrcValue = (uiCrcValue >> 1) ^ POLYNOMIAL; } else { uiCrcValue = (uiCrcValue >> 1); } } } return uiCrcValue; }; /** * Splits a 16-bit CRC into LSB and MSB bytes */ export const getCRCBytes = (crc: number): [number, number] => { const lsb = crc & 0xFF; const msb = (crc >> 8) & 0xFF; return [lsb, msb]; }; /** * Converts a hex string (e.g., "A1 B2") to Uint8Array */ export const hexStringToBytes = (hex: string): Uint8Array | null => { const cleanHex = hex.replace(/[\s-]/g, ''); if (cleanHex.length % 2 !== 0 || !/^[0-9A-Fa-f]+$/.test(cleanHex)) { return null; } const bytes = new Uint8Array(cleanHex.length / 2); for (let i = 0; i < cleanHex.length; i += 2) { bytes[i / 2] = parseInt(cleanHex.substring(i, i + 2), 16); } return bytes; }; /** * Converts bytes to Hex String */ export const bytesToHexString = (bytes: Uint8Array | number[]): string => { return Array.from(bytes) .map(b => b.toString(16).padStart(2, '0').toUpperCase()) .join(' '); }; /** * Converts a hex string (with spaces) to ASCII string */ export const hexToAscii = (hex: string): string => { if (!hex) return ""; const cleanHex = hex.replace(/[\s-]/g, ''); let str = ""; for (let i = 0; i < cleanHex.length; i += 2) { const charCode = parseInt(cleanHex.substring(i, i + 2), 16); // Replace non-printable characters with dots if (charCode >= 32 && charCode <= 126) { str += String.fromCharCode(charCode); } else { str += "."; } } return str; }; /** * Converts an ASCII string to Hex string */ export const asciiToHex = (ascii: string): string => { let hex = ""; for (let i = 0; i < ascii.length; i++) { const code = ascii.charCodeAt(i); hex += code.toString(16).padStart(2, "0").toUpperCase(); } return hex; };