Due to its rather unique polynomial, the CRC-16 variant XMODEM uses can be implemented efficiently in JavaScript with optimal performance.
This function will produce the XMODEM CRC-16 of a given string:
function crc16(str, crc = 0, xorout = 0) {
for(let i = 0, t; i < str.length; i++, crc &= 0xFFFF) {
t = (crc >> 8) ^ str.charCodeAt(i);
t ^= t >> 4;
crc = (crc << 8) ^ (t << 12) ^ (t << 5) ^ t;
}
return crc ^ xorout;
}
// Check if test string matches expected result
console.log(crc16("123456789") === 0x31c3);
It's worth noting that this function can also be used to specify certain other variants of CRC-16. For example, initializing crc
to 0xFFFF
will correctly model the CRC-16 variant used on IBM 3740 floppy disks.
The XMODEM CRC-16 is sometimes misidentified as the more common CCITT CRC-16 (less-confusingly known as the KERMIT CRC-16). They are nearly identical. The only difference is that XMODEM uses an unreflected polynomial, whereas KERMIT uses a reflected polynomial.
So purely for comparison purposes, here is the KERMIT CRC-16 version:
function crc16_refl(str, crc = 0, xorout = 0) {
for(let i = 0, t; i < str.length; i++, crc &= 0xFFFF) {
t = crc ^ str.charCodeAt(i);
t ^= t << 4, t &= 0xFF;
crc = (crc >> 8) ^ (t << 8) ^ (t >> 4) ^ (t << 3);
}
return crc ^ xorout;
}
// Check if test string matches expected result
console.log(crc16_refl("123456789") === 0x2189);