JavaScript CRC32

Adria picture Adria · Sep 5, 2013 · Viewed 42.8k times · Source

I'm looking for a modern JavaScript implementation of CRC32.

This implementation, which may have originated from here, and is now here, there and everywhere, is unacceptable because it's slow (500ms/MB), and depends on over 2KB of space delimited table, accessed using substr. Yuck!

There appears to be a few variations of CRC32, so I need to match this output:

mysql> SELECT CRC32('abcde');
> 2240272485

Function doesn't actually need to accept a string however, since I'm working with byte arrays.

Answer

Alex picture Alex · Sep 5, 2013

Update

I added a helper function to create the CRCTable instead of having this enormous literal in the code. It could also be used to create the table once and save it in an object or variable and have the crc32 function use that (or as W3C's example, check for the existence and create if necessary). I also updated the jsPerf to compare using a CRCtable with the literal string, literal array, saved window variable and dynamic pointer (the example shown here).

var makeCRCTable = function(){
    var c;
    var crcTable = [];
    for(var n =0; n < 256; n++){
        c = n;
        for(var k =0; k < 8; k++){
            c = ((c&1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1));
        }
        crcTable[n] = c;
    }
    return crcTable;
}

var crc32 = function(str) {
    var crcTable = window.crcTable || (window.crcTable = makeCRCTable());
    var crc = 0 ^ (-1);

    for (var i = 0; i < str.length; i++ ) {
        crc = (crc >>> 8) ^ crcTable[(crc ^ str.charCodeAt(i)) & 0xFF];
    }

    return (crc ^ (-1)) >>> 0;
};

Here's a link to the performance difference: http://jsperf.com/js-crc32

Well here's my ameatur shot at this. I figured reading off an array is faster than substringing it.

Warning though, I forwent the use of the Utf8Encode function in these examples to simplify the tests. After all, these are just examples and pretty rough ones at that.