From eaabd0c8fceab4c0b8548eb02af926135aa916a4 Mon Sep 17 00:00:00 2001 From: Garrett Luu Date: Thu, 25 Jun 2020 16:25:52 -0700 Subject: [PATCH 01/11] Refactored CLI * Moved bin scripts to packages folder * Created crc32-cli package * Moved code to index.js --- bin/crc32.njs | 87 ---------------------- packages/crc32-cli/bin/crc32.njs | 9 +++ {bin => packages/crc32-cli/bin}/crc32.py | 0 packages/crc32-cli/index.js | 91 ++++++++++++++++++++++++ packages/crc32-cli/package.json | 16 +++++ 5 files changed, 116 insertions(+), 87 deletions(-) delete mode 100755 bin/crc32.njs create mode 100755 packages/crc32-cli/bin/crc32.njs rename {bin => packages/crc32-cli/bin}/crc32.py (100%) create mode 100644 packages/crc32-cli/index.js create mode 100644 packages/crc32-cli/package.json diff --git a/bin/crc32.njs b/bin/crc32.njs deleted file mode 100755 index 657291a..0000000 --- a/bin/crc32.njs +++ /dev/null @@ -1,87 +0,0 @@ -#!/usr/bin/env node -/* crc32.js (C) 2014-present SheetJS -- http://sheetjs.com */ -/* eslint-env node */ -/* vim: set ts=2 ft=javascript: */ -/*jshint node:true */ - -var X/*:CRC32Module*/; -try { X = require('../'); } catch(e) { X = require('crc-32'); } - -function help()/*:number*/ { -[ -"usage: crc32 [options] [filename]", -"", -"Options:", -" -h, --help output usage information", -" -V, --version output the version number", -" -S, --seed= use integer seed as starting value (rolling CRC)", -" -H, --hex-seed= use hex seed as starting value (rolling CRC)", -" -d, --signed print result with format `%d` (default)", -" -u, --unsigned print result with format `%u`", -" -x, --hex print result with format `%0.8x`", -" -X, --HEX print result with format `%0.8X`", -" -F, --format= use specified printf format", -"", -"Set filename = '-' or pipe data into crc32 to read from stdin", -"Default output mode is signed (-d)", -"" -].forEach(function(l) { console.log(l); }); - return 0; -} - -function version()/*:number*/ { console.log(X.version); return 0; } - -var fs = require('fs'); -require('exit-on-epipe'); - -function die(msg/*:string*/, ec/*:?number*/)/*:void*/ { console.error(msg); process.exit(ec || 0); } - -var args/*:Array*/ = process.argv.slice(2); -var filename/*:string*/ = ""; -var fmt/*:string*/ = ""; -var seed = 0, r = 10; - -for(var i = 0; i < args.length; ++i) { - var arg = args[i]; - if(arg.charCodeAt(0) != 45) { if(filename === "") filename = arg; continue; } - var m = arg.indexOf("=") == -1 ? arg : arg.substr(0, arg.indexOf("=")); - switch(m) { - case "-": filename = "-"; break; - - case "--help": case "-h": process.exit(help()); break; - case "--version": case "-V": process.exit(version()); break; - - case "--signed": case "-d": fmt = "%d"; break; - case "--unsigned": case "-u": fmt = "%u"; break; - case "--hex": case "-x": fmt = "%0.8x"; break; - case "--HEX": case "-X": fmt = "%0.8X"; break; - case "--format": case "-F": - fmt = ((m!=arg) ? arg.substr(m.length+1) : args[++i])||""; break; - - case "--hex-seed": case "-H": r = 16; - /* falls through */ - case "--seed": case "-S": - seed=parseInt((m!=arg) ? arg.substr(m.length+1) : args[++i], r)||0; break; - - default: die("crc32: unrecognized option `" + arg + "'", 22); - } -} - -if(!process.stdin.isTTY) filename = filename || "-"; -if(filename.length===0) die("crc32: must specify a filename ('-' for stdin)",1); - -var crc32 = seed; -// $FlowIgnore -- Writable is callable but type sig disagrees -var writable = require('stream').Writable(); -writable._write = function(chunk, e, cb) { crc32 = X.buf(chunk, crc32); cb(); }; -writable._writev = function(chunks, cb) { - chunks.forEach(function(c) { crc32 = X.buf(c.chunk, crc32);}); - cb(); -}; -writable.on('finish', function() { - console.log(fmt === "" ? crc32 : require("printj").sprintf(fmt, crc32)); -}); - -if(filename === "-") process.stdin.pipe(writable); -else if(fs.existsSync(filename)) fs.createReadStream(filename).pipe(writable); -else die("crc32: " + filename + ": No such file or directory", 2); diff --git a/packages/crc32-cli/bin/crc32.njs b/packages/crc32-cli/bin/crc32.njs new file mode 100755 index 0000000..d9bf02e --- /dev/null +++ b/packages/crc32-cli/bin/crc32.njs @@ -0,0 +1,9 @@ +#!/usr/bin/env node +/* crc32.js (C) 2014-present SheetJS -- http://sheetjs.com */ +/* eslint-env node */ +/* vim: set ts=2 ft=javascript: */ +/*jshint node:true */ + +var cli = require('../'); + +cli(); \ No newline at end of file diff --git a/bin/crc32.py b/packages/crc32-cli/bin/crc32.py similarity index 100% rename from bin/crc32.py rename to packages/crc32-cli/bin/crc32.py diff --git a/packages/crc32-cli/index.js b/packages/crc32-cli/index.js new file mode 100644 index 0000000..6a410a6 --- /dev/null +++ b/packages/crc32-cli/index.js @@ -0,0 +1,91 @@ +#!/usr/bin/env node +/* index.js (C) 2020-present SheetJS -- http://sheetjs.com */ +/* eslint-env node */ +/* vim: set ts=2 ft=javascript: */ +/*jshint node:true */ + +/*:CRC32Module*/ +var X = require('crc-32'); + +function help()/*:number*/ { + [ + "usage: crc32 [options] [filename]", + "", + "Options:", + " -h, --help output usage information", + " -V, --version output the version number", + " -S, --seed= use integer seed as starting value (rolling CRC)", + " -H, --hex-seed= use hex seed as starting value (rolling CRC)", + " -d, --signed print result with format `%d` (default)", + " -u, --unsigned print result with format `%u`", + " -x, --hex print result with format `%0.8x`", + " -X, --HEX print result with format `%0.8X`", + " -F, --format= use specified printf format", + "", + "Set filename = '-' or pipe data into crc32 to read from stdin", + "Default output mode is signed (-d)", + "" + ].forEach(function (l) { console.log(l); }); + return 0; +} + +function version()/*:number*/ { console.log(X.version); return 0; } + +var fs = require('fs'); +require('exit-on-epipe'); + +function die(msg/*:string*/, ec/*:?number*/)/*:void*/ { console.error(msg); process.exit(ec || 0); } + +function run() { + var args/*:Array*/ = process.argv.slice(2); + var filename/*:string*/ = ""; + var fmt/*:string*/ = ""; + var seed = 0, r = 10; + + for (var i = 0; i < args.length; ++i) { + var arg = args[i]; + if (arg.charCodeAt(0) != 45) { if (filename === "") filename = arg; continue; } + var m = arg.indexOf("=") == -1 ? arg : arg.substr(0, arg.indexOf("=")); + switch (m) { + case "-": filename = "-"; break; + + case "--help": case "-h": process.exit(help()); break; + case "--version": case "-V": process.exit(version()); break; + + case "--signed": case "-d": fmt = "%d"; break; + case "--unsigned": case "-u": fmt = "%u"; break; + case "--hex": case "-x": fmt = "%0.8x"; break; + case "--HEX": case "-X": fmt = "%0.8X"; break; + case "--format": case "-F": + fmt = ((m != arg) ? arg.substr(m.length + 1) : args[++i]) || ""; break; + + case "--hex-seed": case "-H": r = 16; + /* falls through */ + case "--seed": case "-S": + seed = parseInt((m != arg) ? arg.substr(m.length + 1) : args[++i], r) || 0; break; + + default: die("crc32: unrecognized option `" + arg + "'", 22); + } + } + + if (!process.stdin.isTTY) filename = filename || "-"; + if (filename.length === 0) die("crc32: must specify a filename ('-' for stdin)", 1); + + var crc32 = seed; + // $FlowIgnore -- Writable is callable but type sig disagrees + var writable = require('stream').Writable(); + writable._write = function (chunk, e, cb) { crc32 = X.buf(chunk, crc32); cb(); }; + writable._writev = function (chunks, cb) { + chunks.forEach(function (c) { crc32 = X.buf(c.chunk, crc32); }); + cb(); + }; + writable.on('finish', function () { + console.log(fmt === "" ? crc32 : require("printj").sprintf(fmt, crc32)); + }); + + if (filename === "-") process.stdin.pipe(writable); + else if (fs.existsSync(filename)) fs.createReadStream(filename).pipe(writable); + else die("crc32: " + filename + ": No such file or directory", 2); +} + +module.exports = run; \ No newline at end of file diff --git a/packages/crc32-cli/package.json b/packages/crc32-cli/package.json new file mode 100644 index 0000000..8ded8d2 --- /dev/null +++ b/packages/crc32-cli/package.json @@ -0,0 +1,16 @@ +{ + "name": "crc32-cli", + "version": "1.0.0", + "description": "Command-line interface for crc32", + "bin": { + "crc32-cli": "./bin/crc32.njs" + }, + "main": "index.js", + "author": "Garrett Luu", + "license": "Apache-2.0", + "dependencies": { + "crc-32": "^1.2.0", + "exit-on-epipe": "^1.0.1", + "fs": "0.0.1-security" + } +} -- 2.34.1 From 3093cbddca79aaab4ea1dfb83edaaa65be12ff50 Mon Sep 17 00:00:00 2001 From: Ryan Ghods Date: Thu, 20 Jan 2022 14:50:25 -0800 Subject: [PATCH 02/11] package.json: use file extensions for esmodules compatibility --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 09bdd66..7834c48 100644 --- a/package.json +++ b/package.json @@ -7,8 +7,8 @@ "bin": { "crc32": "./bin/crc32.njs" }, - "main": "./crc32", - "types": "types", + "main": "./crc32.js", + "types": "./types/index.d.ts", "dependencies": { "printj": "~1.1.0", "exit-on-epipe": "~1.0.1" -- 2.34.1 From 49af36393a109910880a8647506a0951eb0eb6d9 Mon Sep 17 00:00:00 2001 From: Ryan Ghods Date: Thu, 20 Jan 2022 20:21:19 -0800 Subject: [PATCH 03/11] Update package.json --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 7834c48..5f3655e 100644 --- a/package.json +++ b/package.json @@ -7,8 +7,8 @@ "bin": { "crc32": "./bin/crc32.njs" }, - "main": "./crc32.js", - "types": "./types/index.d.ts", + "main": "crc32.js", + "types": "types/index.d.ts", "dependencies": { "printj": "~1.1.0", "exit-on-epipe": "~1.0.1" -- 2.34.1 From 9f973467551e2ca00a69fe878a6cb332ef7bdd37 Mon Sep 17 00:00:00 2001 From: SheetJS Date: Mon, 24 Jan 2022 03:14:46 -0500 Subject: [PATCH 04/11] CRC32C --- Makefile | 5 +- bin/crc32.njs | 3 ++ crc32c.flow.js | 127 +++++++++++++++++++++++++++++++++++++++++++++++++ crc32c.js | 118 +++++++++++++++++++++++++++++++++++++++++++++ package.json | 7 +-- 5 files changed, 256 insertions(+), 4 deletions(-) create mode 100644 crc32c.flow.js create mode 100644 crc32c.js diff --git a/Makefile b/Makefile index cee5833..eb26e01 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ LIB=crc32 REQS= ADDONS= -AUXTARGETS=demo/browser.js +AUXTARGETS=crc32c.js demo/browser.js CMDS=bin/crc32.njs HTMLLINT=index.html @@ -30,6 +30,9 @@ bits/01_version.js: package.json clean: clean-baseline ## Remove targets and build artifacts rm -f $(TARGET) $(FLOWTARGET) +crc32c.flow.js: crc32.flow.js + cat $^ | sed 's/-306674912/-2097792136/g' > $@ + ## Testing .PHONY: test mocha diff --git a/bin/crc32.njs b/bin/crc32.njs index 657291a..b5b02a1 100755 --- a/bin/crc32.njs +++ b/bin/crc32.njs @@ -20,6 +20,7 @@ function help()/*:number*/ { " -u, --unsigned print result with format `%u`", " -x, --hex print result with format `%0.8x`", " -X, --HEX print result with format `%0.8X`", +" -c, --crc32c use CRC32C (Castagnoli)", " -F, --format= use specified printf format", "", "Set filename = '-' or pipe data into crc32 to read from stdin", @@ -51,6 +52,8 @@ for(var i = 0; i < args.length; ++i) { case "--help": case "-h": process.exit(help()); break; case "--version": case "-V": process.exit(version()); break; + case "--crc32c": case "-c": try { X = require('../crc32c'); } catch(e) { X = require('crc-32/crc32c'); } break; + case "--signed": case "-d": fmt = "%d"; break; case "--unsigned": case "-u": fmt = "%u"; break; case "--hex": case "-x": fmt = "%0.8x"; break; diff --git a/crc32c.flow.js b/crc32c.flow.js new file mode 100644 index 0000000..221e826 --- /dev/null +++ b/crc32c.flow.js @@ -0,0 +1,127 @@ +/* crc32.js (C) 2014-present SheetJS -- http://sheetjs.com */ +/* vim: set ts=2: */ +/*exported CRC32 */ +/*:: declare var DO_NOT_EXPORT_CRC:?boolean; */ +/*:: declare function define(cb:()=>any):void; */ +var CRC32/*:CRC32Module*/; +(function (factory/*:(a:any)=>void*/)/*:void*/ { + /*jshint ignore:start */ + /*eslint-disable */ + if(typeof DO_NOT_EXPORT_CRC === 'undefined') { + if('object' === typeof exports) { + factory(exports); + } else if ('function' === typeof define && define.amd) { + define(function () { + var module/*:CRC32Module*/ = /*::(*/{}/*:: :any)*/; + factory(module); + return module; + }); + } else { + factory(CRC32 = /*::(*/{}/*:: :any)*/); + } + } else { + factory(CRC32 = /*::(*/{}/*:: :any)*/); + } + /*eslint-enable */ + /*jshint ignore:end */ +}(function(CRC32/*:CRC32Module*/) { +CRC32.version = '1.2.0'; +/*:: +type CRC32Type = number; +type ABuf = Array | Buffer | Uint8Array; +type CRC32TableType = Array | Int32Array; +*/ +/* see perf/crc32table.js */ +/*global Int32Array */ +function signed_crc_table()/*:CRC32TableType*/ { + var c = 0, table/*:Array*/ = new Array(256); + + for(var n =0; n != 256; ++n){ + c = n; + c = ((c&1) ? (-2097792136 ^ (c >>> 1)) : (c >>> 1)); + c = ((c&1) ? (-2097792136 ^ (c >>> 1)) : (c >>> 1)); + c = ((c&1) ? (-2097792136 ^ (c >>> 1)) : (c >>> 1)); + c = ((c&1) ? (-2097792136 ^ (c >>> 1)) : (c >>> 1)); + c = ((c&1) ? (-2097792136 ^ (c >>> 1)) : (c >>> 1)); + c = ((c&1) ? (-2097792136 ^ (c >>> 1)) : (c >>> 1)); + c = ((c&1) ? (-2097792136 ^ (c >>> 1)) : (c >>> 1)); + c = ((c&1) ? (-2097792136 ^ (c >>> 1)) : (c >>> 1)); + table[n] = c; + } + + return typeof Int32Array !== 'undefined' ? new Int32Array(table) : table; +} + +var T = signed_crc_table(); +/*# charCodeAt is the best approach for binary strings */ +function crc32_bstr(bstr/*:string*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { + var C = seed/*:: ? 0 : 0 */ ^ -1, L = bstr.length - 1; + for(var i = 0; i < L;) { + C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF]; + C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF]; + } + if(i === L) C = (C>>>8) ^ T[(C ^ bstr.charCodeAt(i))&0xFF]; + return C ^ -1; +} + +function crc32_buf(buf/*:ABuf*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { + if(buf.length > 10000) return crc32_buf_8(buf, seed); + var C = seed/*:: ? 0 : 0 */ ^ -1, L = buf.length - 3; + for(var i = 0; i < L;) { + C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; + C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; + C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; + C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; + } + while(i < L+3) C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; + return C ^ -1; +} + +function crc32_buf_8(buf/*:ABuf*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { + var C = seed/*:: ? 0 : 0 */ ^ -1, L = buf.length - 7; + for(var i = 0; i < L;) { + C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; + C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; + C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; + C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; + C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; + C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; + C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; + C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; + } + while(i < L+7) C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; + return C ^ -1; +} + +/*# much much faster to intertwine utf8 and crc */ +function crc32_str(str/*:string*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { + var C = seed/*:: ? 0 : 0 */ ^ -1; + for(var i = 0, L=str.length, c, d; i < L;) { + c = str.charCodeAt(i++); + if(c < 0x80) { + C = (C>>>8) ^ T[(C ^ c)&0xFF]; + } else if(c < 0x800) { + C = (C>>>8) ^ T[(C ^ (192|((c>>6)&31)))&0xFF]; + C = (C>>>8) ^ T[(C ^ (128|(c&63)))&0xFF]; + } else if(c >= 0xD800 && c < 0xE000) { + c = (c&1023)+64; d = str.charCodeAt(i++)&1023; + C = (C>>>8) ^ T[(C ^ (240|((c>>8)&7)))&0xFF]; + C = (C>>>8) ^ T[(C ^ (128|((c>>2)&63)))&0xFF]; + C = (C>>>8) ^ T[(C ^ (128|((d>>6)&15)|((c&3)<<4)))&0xFF]; + C = (C>>>8) ^ T[(C ^ (128|(d&63)))&0xFF]; + } else { + C = (C>>>8) ^ T[(C ^ (224|((c>>12)&15)))&0xFF]; + C = (C>>>8) ^ T[(C ^ (128|((c>>6)&63)))&0xFF]; + C = (C>>>8) ^ T[(C ^ (128|(c&63)))&0xFF]; + } + } + return C ^ -1; +} +CRC32.table = T; +// $FlowIgnore +CRC32.bstr = crc32_bstr; +// $FlowIgnore +CRC32.buf = crc32_buf; +// $FlowIgnore +CRC32.str = crc32_str; +})); diff --git a/crc32c.js b/crc32c.js new file mode 100644 index 0000000..0cd8ffb --- /dev/null +++ b/crc32c.js @@ -0,0 +1,118 @@ +/* crc32.js (C) 2014-present SheetJS -- http://sheetjs.com */ +/* vim: set ts=2: */ +/*exported CRC32 */ +var CRC32; +(function (factory) { + /*jshint ignore:start */ + /*eslint-disable */ + if(typeof DO_NOT_EXPORT_CRC === 'undefined') { + if('object' === typeof exports) { + factory(exports); + } else if ('function' === typeof define && define.amd) { + define(function () { + var module = {}; + factory(module); + return module; + }); + } else { + factory(CRC32 = {}); + } + } else { + factory(CRC32 = {}); + } + /*eslint-enable */ + /*jshint ignore:end */ +}(function(CRC32) { +CRC32.version = '1.2.0'; +/* see perf/crc32table.js */ +/*global Int32Array */ +function signed_crc_table() { + var c = 0, table = new Array(256); + + for(var n =0; n != 256; ++n){ + c = n; + c = ((c&1) ? (-2097792136 ^ (c >>> 1)) : (c >>> 1)); + c = ((c&1) ? (-2097792136 ^ (c >>> 1)) : (c >>> 1)); + c = ((c&1) ? (-2097792136 ^ (c >>> 1)) : (c >>> 1)); + c = ((c&1) ? (-2097792136 ^ (c >>> 1)) : (c >>> 1)); + c = ((c&1) ? (-2097792136 ^ (c >>> 1)) : (c >>> 1)); + c = ((c&1) ? (-2097792136 ^ (c >>> 1)) : (c >>> 1)); + c = ((c&1) ? (-2097792136 ^ (c >>> 1)) : (c >>> 1)); + c = ((c&1) ? (-2097792136 ^ (c >>> 1)) : (c >>> 1)); + table[n] = c; + } + + return typeof Int32Array !== 'undefined' ? new Int32Array(table) : table; +} + +var T = signed_crc_table(); +function crc32_bstr(bstr, seed) { + var C = seed ^ -1, L = bstr.length - 1; + for(var i = 0; i < L;) { + C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF]; + C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF]; + } + if(i === L) C = (C>>>8) ^ T[(C ^ bstr.charCodeAt(i))&0xFF]; + return C ^ -1; +} + +function crc32_buf(buf, seed) { + if(buf.length > 10000) return crc32_buf_8(buf, seed); + var C = seed ^ -1, L = buf.length - 3; + for(var i = 0; i < L;) { + C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; + C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; + C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; + C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; + } + while(i < L+3) C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; + return C ^ -1; +} + +function crc32_buf_8(buf, seed) { + var C = seed ^ -1, L = buf.length - 7; + for(var i = 0; i < L;) { + C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; + C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; + C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; + C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; + C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; + C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; + C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; + C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; + } + while(i < L+7) C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; + return C ^ -1; +} + +function crc32_str(str, seed) { + var C = seed ^ -1; + for(var i = 0, L=str.length, c, d; i < L;) { + c = str.charCodeAt(i++); + if(c < 0x80) { + C = (C>>>8) ^ T[(C ^ c)&0xFF]; + } else if(c < 0x800) { + C = (C>>>8) ^ T[(C ^ (192|((c>>6)&31)))&0xFF]; + C = (C>>>8) ^ T[(C ^ (128|(c&63)))&0xFF]; + } else if(c >= 0xD800 && c < 0xE000) { + c = (c&1023)+64; d = str.charCodeAt(i++)&1023; + C = (C>>>8) ^ T[(C ^ (240|((c>>8)&7)))&0xFF]; + C = (C>>>8) ^ T[(C ^ (128|((c>>2)&63)))&0xFF]; + C = (C>>>8) ^ T[(C ^ (128|((d>>6)&15)|((c&3)<<4)))&0xFF]; + C = (C>>>8) ^ T[(C ^ (128|(d&63)))&0xFF]; + } else { + C = (C>>>8) ^ T[(C ^ (224|((c>>12)&15)))&0xFF]; + C = (C>>>8) ^ T[(C ^ (128|((c>>6)&63)))&0xFF]; + C = (C>>>8) ^ T[(C ^ (128|(c&63)))&0xFF]; + } + } + return C ^ -1; +} +CRC32.table = T; +// $FlowIgnore +CRC32.bstr = crc32_bstr; +// $FlowIgnore +CRC32.buf = crc32_buf; +// $FlowIgnore +CRC32.str = crc32_str; +})); diff --git a/package.json b/package.json index 5f3655e..80de338 100644 --- a/package.json +++ b/package.json @@ -5,12 +5,13 @@ "description": "Pure-JS CRC-32", "keywords": [ "crc", "crc32", "checksum" ], "bin": { - "crc32": "./bin/crc32.njs" + "crc32": "bin/crc32.njs" }, "main": "crc32.js", "types": "types/index.d.ts", + "typesVersions": { "*": { "*": ["types/index.d.ts" ] } }, "dependencies": { - "printj": "~1.1.0", + "printj": "~1.3.1", "exit-on-epipe": "~1.0.1" }, "devDependencies": { @@ -35,7 +36,7 @@ } }, "homepage": "http://sheetjs.com/opensource", - "files": ["crc32.js", "bin/crc32.njs", "LICENSE", "README.md", "types/index.d.ts", "types/*.json"], + "files": ["crc32.js", "crc32c.js", "bin/crc32.njs", "LICENSE", "README.md", "types/index.d.ts", "types/*.json"], "bugs": { "url": "https://github.com/SheetJS/js-crc32/issues" }, "license": "Apache-2.0", "engines": { "node": ">=0.8" } -- 2.34.1 From d2e236fe5e8a1a27b20d0d4a8c27e65238656c1a Mon Sep 17 00:00:00 2001 From: 101arrowz Date: Mon, 24 Jan 2022 12:59:51 -0800 Subject: [PATCH 05/11] Slice-by-16 for buf and bstr (fixes #17) --- bits/20_crctable.js | 17 ++++++++++ bits/40_crc.js | 66 +++++++++++++++++++++++++---------- crc32.flow.js | 83 +++++++++++++++++++++++++++++++++++---------- crc32.js | 80 ++++++++++++++++++++++++++++++++++--------- crc32c.flow.js | 83 +++++++++++++++++++++++++++++++++++---------- crc32c.js | 80 ++++++++++++++++++++++++++++++++++--------- 6 files changed, 326 insertions(+), 83 deletions(-) diff --git a/bits/20_crctable.js b/bits/20_crctable.js index 25f2d6c..c0236a1 100644 --- a/bits/20_crctable.js +++ b/bits/20_crctable.js @@ -20,3 +20,20 @@ function signed_crc_table()/*:CRC32TableType*/ { } var T = signed_crc_table(); +/*# slice by 16 tables */ +function slice_by_16_tables(T) { + var c = 0, v = 0, n = 0, table/*:Array*/ = typeof Int32Array !== 'undefined' ? new Int32Array(4096) : new Array(4096) ; + + for(n = 0; n != 256; ++n) table[n] = T[n]; + for(n = 0; n != 256; ++n) { + v = T[n]; + for(c = 256 + n; c < 4096; c += 256) v = table[c] = (v >>> 8) ^ T[v & 0xFF]; + } + var out = []; + for(n = 1; n != 16; ++n) out[n - 1] = typeof Int32Array !== 'undefined' ? table.subarray(n * 256, n * 256 + 256) : table.slice(n * 256, n * 256 + 256); + return out; +} +var TT = slice_by_16_tables(T); +var T1 = TT[0], T2 = TT[1], T3 = TT[2], T4 = TT[3], T5 = TT[4]; +var T6 = TT[5], T7 = TT[6], T8 = TT[7], T9 = TT[8], Ta = TT[9]; +var Tb = TT[10], Tc = TT[11], Td = TT[12], Te = TT[13], Tf = TT[14]; diff --git a/bits/40_crc.js b/bits/40_crc.js index b6fa7f9..0e55946 100644 --- a/bits/40_crc.js +++ b/bits/40_crc.js @@ -1,5 +1,6 @@ /*# charCodeAt is the best approach for binary strings */ function crc32_bstr(bstr/*:string*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { + if(bstr.length > 10000) return crc32_bstr_16(bstr, seed); var C = seed/*:: ? 0 : 0 */ ^ -1, L = bstr.length - 1; for(var i = 0; i < L;) { C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF]; @@ -8,9 +9,32 @@ function crc32_bstr(bstr/*:string*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { if(i === L) C = (C>>>8) ^ T[(C ^ bstr.charCodeAt(i))&0xFF]; return C ^ -1; } +function crc32_bstr_16(bstr/*:string*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { + var C = seed/*:: ? 0 : 0 */ ^ -1, L = bstr.length - 15; + for(var i = 0; i < L;) C = + Tf[bstr.charCodeAt(i++) ^ (C & 255)] ^ + Te[bstr.charCodeAt(i++) ^ ((C >> 8) & 255)] ^ + Td[bstr.charCodeAt(i++) ^ ((C >> 16) & 255)] ^ + Tc[bstr.charCodeAt(i++) ^ (C >>> 24)] ^ + Tb[bstr.charCodeAt(i++)] ^ + Ta[bstr.charCodeAt(i++)] ^ + T9[bstr.charCodeAt(i++)] ^ + T8[bstr.charCodeAt(i++)] ^ + T7[bstr.charCodeAt(i++)] ^ + T6[bstr.charCodeAt(i++)] ^ + T5[bstr.charCodeAt(i++)] ^ + T4[bstr.charCodeAt(i++)] ^ + T3[bstr.charCodeAt(i++)] ^ + T2[bstr.charCodeAt(i++)] ^ + T1[bstr.charCodeAt(i++)] ^ + T[bstr.charCodeAt(i++)]; + L += 15; + while(i < L) C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF]; + return C ^ -1; +} function crc32_buf(buf/*:ABuf*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { - if(buf.length > 10000) return crc32_buf_8(buf, seed); + if(buf.length > 2000) return crc32_buf_16(buf, seed); var C = seed/*:: ? 0 : 0 */ ^ -1, L = buf.length - 3; for(var i = 0; i < L;) { C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; @@ -21,27 +45,35 @@ function crc32_buf(buf/*:ABuf*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { while(i < L+3) C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; return C ^ -1; } - -function crc32_buf_8(buf/*:ABuf*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { - var C = seed/*:: ? 0 : 0 */ ^ -1, L = buf.length - 7; - for(var i = 0; i < L;) { - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - } - while(i < L+7) C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; +function crc32_buf_16(buf/*:ABuf*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { + var C = seed/*:: ? 0 : 0 */ ^ -1, L = buf.length - 15; + for(var i = 0; i < L;) C = + Tf[buf[i++] ^ (C & 255)] ^ + Te[buf[i++] ^ ((C >> 8) & 255)] ^ + Td[buf[i++] ^ ((C >> 16) & 255)] ^ + Tc[buf[i++] ^ (C >>> 24)] ^ + Tb[buf[i++]] ^ + Ta[buf[i++]] ^ + T9[buf[i++]] ^ + T8[buf[i++]] ^ + T7[buf[i++]] ^ + T6[buf[i++]] ^ + T5[buf[i++]] ^ + T4[buf[i++]] ^ + T3[buf[i++]] ^ + T2[buf[i++]] ^ + T1[buf[i++]] ^ + T[buf[i++]]; + L += 15; + while(i < L) C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; return C ^ -1; } -/*# much much faster to intertwine utf8 and crc */ + +/*# much much faster to intertwine utf8 and crc, slower to slice by 8 or 16 */ function crc32_str(str/*:string*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { var C = seed/*:: ? 0 : 0 */ ^ -1; - for(var i = 0, L=str.length, c, d; i < L;) { + for(var i = 0, L = str.length, c = 0, d = 0; i < L;) { c = str.charCodeAt(i++); if(c < 0x80) { C = (C>>>8) ^ T[(C ^ c)&0xFF]; diff --git a/crc32.flow.js b/crc32.flow.js index 145b7a6..18e5725 100644 --- a/crc32.flow.js +++ b/crc32.flow.js @@ -53,8 +53,26 @@ function signed_crc_table()/*:CRC32TableType*/ { } var T = signed_crc_table(); +/*# slice by 16 tables */ +function slice_by_16_tables(T) { + var c = 0, v = 0, n = 0, table/*:Array*/ = typeof Int32Array !== 'undefined' ? new Int32Array(4096) : new Array(4096) ; + + for(n = 0; n != 256; ++n) table[n] = T[n]; + for(n = 0; n != 256; ++n) { + v = T[n]; + for(c = 256 + n; c < 4096; c += 256) v = table[c] = (v >>> 8) ^ T[v & 0xFF]; + } + var out = []; + for(n = 1; n != 16; ++n) out[n - 1] = typeof Int32Array !== 'undefined' ? table.subarray(n * 256, n * 256 + 256) : table.slice(n * 256, n * 256 + 256); + return out; +} +var TT = slice_by_16_tables(T); +var T1 = TT[0], T2 = TT[1], T3 = TT[2], T4 = TT[3], T5 = TT[4]; +var T6 = TT[5], T7 = TT[6], T8 = TT[7], T9 = TT[8], Ta = TT[9]; +var Tb = TT[10], Tc = TT[11], Td = TT[12], Te = TT[13], Tf = TT[14]; /*# charCodeAt is the best approach for binary strings */ function crc32_bstr(bstr/*:string*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { + if(bstr.length > 10000) return crc32_bstr_16(bstr, seed); var C = seed/*:: ? 0 : 0 */ ^ -1, L = bstr.length - 1; for(var i = 0; i < L;) { C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF]; @@ -63,9 +81,32 @@ function crc32_bstr(bstr/*:string*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { if(i === L) C = (C>>>8) ^ T[(C ^ bstr.charCodeAt(i))&0xFF]; return C ^ -1; } +function crc32_bstr_16(bstr/*:string*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { + var C = seed/*:: ? 0 : 0 */ ^ -1, L = bstr.length - 15; + for(var i = 0; i < L;) C = + Tf[bstr.charCodeAt(i++) ^ (C & 255)] ^ + Te[bstr.charCodeAt(i++) ^ ((C >> 8) & 255)] ^ + Td[bstr.charCodeAt(i++) ^ ((C >> 16) & 255)] ^ + Tc[bstr.charCodeAt(i++) ^ (C >>> 24)] ^ + Tb[bstr.charCodeAt(i++)] ^ + Ta[bstr.charCodeAt(i++)] ^ + T9[bstr.charCodeAt(i++)] ^ + T8[bstr.charCodeAt(i++)] ^ + T7[bstr.charCodeAt(i++)] ^ + T6[bstr.charCodeAt(i++)] ^ + T5[bstr.charCodeAt(i++)] ^ + T4[bstr.charCodeAt(i++)] ^ + T3[bstr.charCodeAt(i++)] ^ + T2[bstr.charCodeAt(i++)] ^ + T1[bstr.charCodeAt(i++)] ^ + T[bstr.charCodeAt(i++)]; + L += 15; + while(i < L) C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF]; + return C ^ -1; +} function crc32_buf(buf/*:ABuf*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { - if(buf.length > 10000) return crc32_buf_8(buf, seed); + if(buf.length > 2000) return crc32_buf_16(buf, seed); var C = seed/*:: ? 0 : 0 */ ^ -1, L = buf.length - 3; for(var i = 0; i < L;) { C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; @@ -76,27 +117,35 @@ function crc32_buf(buf/*:ABuf*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { while(i < L+3) C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; return C ^ -1; } - -function crc32_buf_8(buf/*:ABuf*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { - var C = seed/*:: ? 0 : 0 */ ^ -1, L = buf.length - 7; - for(var i = 0; i < L;) { - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - } - while(i < L+7) C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; +function crc32_buf_16(buf/*:ABuf*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { + var C = seed/*:: ? 0 : 0 */ ^ -1, L = buf.length - 15; + for(var i = 0; i < L;) C = + Tf[buf[i++] ^ (C & 255)] ^ + Te[buf[i++] ^ ((C >> 8) & 255)] ^ + Td[buf[i++] ^ ((C >> 16) & 255)] ^ + Tc[buf[i++] ^ (C >>> 24)] ^ + Tb[buf[i++]] ^ + Ta[buf[i++]] ^ + T9[buf[i++]] ^ + T8[buf[i++]] ^ + T7[buf[i++]] ^ + T6[buf[i++]] ^ + T5[buf[i++]] ^ + T4[buf[i++]] ^ + T3[buf[i++]] ^ + T2[buf[i++]] ^ + T1[buf[i++]] ^ + T[buf[i++]]; + L += 15; + while(i < L) C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; return C ^ -1; } -/*# much much faster to intertwine utf8 and crc */ + +/*# much much faster to intertwine utf8 and crc, slower to slice by 8 or 16 */ function crc32_str(str/*:string*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { var C = seed/*:: ? 0 : 0 */ ^ -1; - for(var i = 0, L=str.length, c, d; i < L;) { + for(var i = 0, L = str.length, c = 0, d = 0; i < L;) { c = str.charCodeAt(i++); if(c < 0x80) { C = (C>>>8) ^ T[(C ^ c)&0xFF]; diff --git a/crc32.js b/crc32.js index 6bcecef..b310fb9 100644 --- a/crc32.js +++ b/crc32.js @@ -46,7 +46,24 @@ function signed_crc_table() { } var T = signed_crc_table(); +function slice_by_16_tables(T) { + var c = 0, v = 0, n = 0, table = typeof Int32Array !== 'undefined' ? new Int32Array(4096) : new Array(4096) ; + + for(n = 0; n != 256; ++n) table[n] = T[n]; + for(n = 0; n != 256; ++n) { + v = T[n]; + for(c = 256 + n; c < 4096; c += 256) v = table[c] = (v >>> 8) ^ T[v & 0xFF]; + } + var out = []; + for(n = 1; n != 16; ++n) out[n - 1] = typeof Int32Array !== 'undefined' ? table.subarray(n * 256, n * 256 + 256) : table.slice(n * 256, n * 256 + 256); + return out; +} +var TT = slice_by_16_tables(T); +var T1 = TT[0], T2 = TT[1], T3 = TT[2], T4 = TT[3], T5 = TT[4]; +var T6 = TT[5], T7 = TT[6], T8 = TT[7], T9 = TT[8], Ta = TT[9]; +var Tb = TT[10], Tc = TT[11], Td = TT[12], Te = TT[13], Tf = TT[14]; function crc32_bstr(bstr, seed) { + if(bstr.length > 10000) return crc32_bstr_16(bstr, seed); var C = seed ^ -1, L = bstr.length - 1; for(var i = 0; i < L;) { C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF]; @@ -55,9 +72,32 @@ function crc32_bstr(bstr, seed) { if(i === L) C = (C>>>8) ^ T[(C ^ bstr.charCodeAt(i))&0xFF]; return C ^ -1; } +function crc32_bstr_16(bstr, seed) { + var C = seed ^ -1, L = bstr.length - 15; + for(var i = 0; i < L;) C = + Tf[bstr.charCodeAt(i++) ^ (C & 255)] ^ + Te[bstr.charCodeAt(i++) ^ ((C >> 8) & 255)] ^ + Td[bstr.charCodeAt(i++) ^ ((C >> 16) & 255)] ^ + Tc[bstr.charCodeAt(i++) ^ (C >>> 24)] ^ + Tb[bstr.charCodeAt(i++)] ^ + Ta[bstr.charCodeAt(i++)] ^ + T9[bstr.charCodeAt(i++)] ^ + T8[bstr.charCodeAt(i++)] ^ + T7[bstr.charCodeAt(i++)] ^ + T6[bstr.charCodeAt(i++)] ^ + T5[bstr.charCodeAt(i++)] ^ + T4[bstr.charCodeAt(i++)] ^ + T3[bstr.charCodeAt(i++)] ^ + T2[bstr.charCodeAt(i++)] ^ + T1[bstr.charCodeAt(i++)] ^ + T[bstr.charCodeAt(i++)]; + L += 15; + while(i < L) C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF]; + return C ^ -1; +} function crc32_buf(buf, seed) { - if(buf.length > 10000) return crc32_buf_8(buf, seed); + if(buf.length > 2000) return crc32_buf_16(buf, seed); var C = seed ^ -1, L = buf.length - 3; for(var i = 0; i < L;) { C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; @@ -68,26 +108,34 @@ function crc32_buf(buf, seed) { while(i < L+3) C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; return C ^ -1; } - -function crc32_buf_8(buf, seed) { - var C = seed ^ -1, L = buf.length - 7; - for(var i = 0; i < L;) { - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - } - while(i < L+7) C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; +function crc32_buf_16(buf, seed) { + var C = seed ^ -1, L = buf.length - 15; + for(var i = 0; i < L;) C = + Tf[buf[i++] ^ (C & 255)] ^ + Te[buf[i++] ^ ((C >> 8) & 255)] ^ + Td[buf[i++] ^ ((C >> 16) & 255)] ^ + Tc[buf[i++] ^ (C >>> 24)] ^ + Tb[buf[i++]] ^ + Ta[buf[i++]] ^ + T9[buf[i++]] ^ + T8[buf[i++]] ^ + T7[buf[i++]] ^ + T6[buf[i++]] ^ + T5[buf[i++]] ^ + T4[buf[i++]] ^ + T3[buf[i++]] ^ + T2[buf[i++]] ^ + T1[buf[i++]] ^ + T[buf[i++]]; + L += 15; + while(i < L) C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; return C ^ -1; } + function crc32_str(str, seed) { var C = seed ^ -1; - for(var i = 0, L=str.length, c, d; i < L;) { + for(var i = 0, L = str.length, c = 0, d = 0; i < L;) { c = str.charCodeAt(i++); if(c < 0x80) { C = (C>>>8) ^ T[(C ^ c)&0xFF]; diff --git a/crc32c.flow.js b/crc32c.flow.js index 221e826..fae81b1 100644 --- a/crc32c.flow.js +++ b/crc32c.flow.js @@ -53,8 +53,26 @@ function signed_crc_table()/*:CRC32TableType*/ { } var T = signed_crc_table(); +/*# slice by 16 tables */ +function slice_by_16_tables(T) { + var c = 0, v = 0, n = 0, table/*:Array*/ = typeof Int32Array !== 'undefined' ? new Int32Array(4096) : new Array(4096) ; + + for(n = 0; n != 256; ++n) table[n] = T[n]; + for(n = 0; n != 256; ++n) { + v = T[n]; + for(c = 256 + n; c < 4096; c += 256) v = table[c] = (v >>> 8) ^ T[v & 0xFF]; + } + var out = []; + for(n = 1; n != 16; ++n) out[n - 1] = typeof Int32Array !== 'undefined' ? table.subarray(n * 256, n * 256 + 256) : table.slice(n * 256, n * 256 + 256); + return out; +} +var TT = slice_by_16_tables(T); +var T1 = TT[0], T2 = TT[1], T3 = TT[2], T4 = TT[3], T5 = TT[4]; +var T6 = TT[5], T7 = TT[6], T8 = TT[7], T9 = TT[8], Ta = TT[9]; +var Tb = TT[10], Tc = TT[11], Td = TT[12], Te = TT[13], Tf = TT[14]; /*# charCodeAt is the best approach for binary strings */ function crc32_bstr(bstr/*:string*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { + if(bstr.length > 10000) return crc32_bstr_16(bstr, seed); var C = seed/*:: ? 0 : 0 */ ^ -1, L = bstr.length - 1; for(var i = 0; i < L;) { C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF]; @@ -63,9 +81,32 @@ function crc32_bstr(bstr/*:string*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { if(i === L) C = (C>>>8) ^ T[(C ^ bstr.charCodeAt(i))&0xFF]; return C ^ -1; } +function crc32_bstr_16(bstr/*:string*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { + var C = seed/*:: ? 0 : 0 */ ^ -1, L = bstr.length - 15; + for(var i = 0; i < L;) C = + Tf[bstr.charCodeAt(i++) ^ (C & 255)] ^ + Te[bstr.charCodeAt(i++) ^ ((C >> 8) & 255)] ^ + Td[bstr.charCodeAt(i++) ^ ((C >> 16) & 255)] ^ + Tc[bstr.charCodeAt(i++) ^ (C >>> 24)] ^ + Tb[bstr.charCodeAt(i++)] ^ + Ta[bstr.charCodeAt(i++)] ^ + T9[bstr.charCodeAt(i++)] ^ + T8[bstr.charCodeAt(i++)] ^ + T7[bstr.charCodeAt(i++)] ^ + T6[bstr.charCodeAt(i++)] ^ + T5[bstr.charCodeAt(i++)] ^ + T4[bstr.charCodeAt(i++)] ^ + T3[bstr.charCodeAt(i++)] ^ + T2[bstr.charCodeAt(i++)] ^ + T1[bstr.charCodeAt(i++)] ^ + T[bstr.charCodeAt(i++)]; + L += 15; + while(i < L) C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF]; + return C ^ -1; +} function crc32_buf(buf/*:ABuf*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { - if(buf.length > 10000) return crc32_buf_8(buf, seed); + if(buf.length > 2000) return crc32_buf_16(buf, seed); var C = seed/*:: ? 0 : 0 */ ^ -1, L = buf.length - 3; for(var i = 0; i < L;) { C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; @@ -76,27 +117,35 @@ function crc32_buf(buf/*:ABuf*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { while(i < L+3) C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; return C ^ -1; } - -function crc32_buf_8(buf/*:ABuf*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { - var C = seed/*:: ? 0 : 0 */ ^ -1, L = buf.length - 7; - for(var i = 0; i < L;) { - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - } - while(i < L+7) C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; +function crc32_buf_16(buf/*:ABuf*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { + var C = seed/*:: ? 0 : 0 */ ^ -1, L = buf.length - 15; + for(var i = 0; i < L;) C = + Tf[buf[i++] ^ (C & 255)] ^ + Te[buf[i++] ^ ((C >> 8) & 255)] ^ + Td[buf[i++] ^ ((C >> 16) & 255)] ^ + Tc[buf[i++] ^ (C >>> 24)] ^ + Tb[buf[i++]] ^ + Ta[buf[i++]] ^ + T9[buf[i++]] ^ + T8[buf[i++]] ^ + T7[buf[i++]] ^ + T6[buf[i++]] ^ + T5[buf[i++]] ^ + T4[buf[i++]] ^ + T3[buf[i++]] ^ + T2[buf[i++]] ^ + T1[buf[i++]] ^ + T[buf[i++]]; + L += 15; + while(i < L) C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; return C ^ -1; } -/*# much much faster to intertwine utf8 and crc */ + +/*# much much faster to intertwine utf8 and crc, slower to slice by 8 or 16 */ function crc32_str(str/*:string*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { var C = seed/*:: ? 0 : 0 */ ^ -1; - for(var i = 0, L=str.length, c, d; i < L;) { + for(var i = 0, L = str.length, c = 0, d = 0; i < L;) { c = str.charCodeAt(i++); if(c < 0x80) { C = (C>>>8) ^ T[(C ^ c)&0xFF]; diff --git a/crc32c.js b/crc32c.js index 0cd8ffb..7b471c0 100644 --- a/crc32c.js +++ b/crc32c.js @@ -46,7 +46,24 @@ function signed_crc_table() { } var T = signed_crc_table(); +function slice_by_16_tables(T) { + var c = 0, v = 0, n = 0, table = typeof Int32Array !== 'undefined' ? new Int32Array(4096) : new Array(4096) ; + + for(n = 0; n != 256; ++n) table[n] = T[n]; + for(n = 0; n != 256; ++n) { + v = T[n]; + for(c = 256 + n; c < 4096; c += 256) v = table[c] = (v >>> 8) ^ T[v & 0xFF]; + } + var out = []; + for(n = 1; n != 16; ++n) out[n - 1] = typeof Int32Array !== 'undefined' ? table.subarray(n * 256, n * 256 + 256) : table.slice(n * 256, n * 256 + 256); + return out; +} +var TT = slice_by_16_tables(T); +var T1 = TT[0], T2 = TT[1], T3 = TT[2], T4 = TT[3], T5 = TT[4]; +var T6 = TT[5], T7 = TT[6], T8 = TT[7], T9 = TT[8], Ta = TT[9]; +var Tb = TT[10], Tc = TT[11], Td = TT[12], Te = TT[13], Tf = TT[14]; function crc32_bstr(bstr, seed) { + if(bstr.length > 10000) return crc32_bstr_16(bstr, seed); var C = seed ^ -1, L = bstr.length - 1; for(var i = 0; i < L;) { C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF]; @@ -55,9 +72,32 @@ function crc32_bstr(bstr, seed) { if(i === L) C = (C>>>8) ^ T[(C ^ bstr.charCodeAt(i))&0xFF]; return C ^ -1; } +function crc32_bstr_16(bstr, seed) { + var C = seed ^ -1, L = bstr.length - 15; + for(var i = 0; i < L;) C = + Tf[bstr.charCodeAt(i++) ^ (C & 255)] ^ + Te[bstr.charCodeAt(i++) ^ ((C >> 8) & 255)] ^ + Td[bstr.charCodeAt(i++) ^ ((C >> 16) & 255)] ^ + Tc[bstr.charCodeAt(i++) ^ (C >>> 24)] ^ + Tb[bstr.charCodeAt(i++)] ^ + Ta[bstr.charCodeAt(i++)] ^ + T9[bstr.charCodeAt(i++)] ^ + T8[bstr.charCodeAt(i++)] ^ + T7[bstr.charCodeAt(i++)] ^ + T6[bstr.charCodeAt(i++)] ^ + T5[bstr.charCodeAt(i++)] ^ + T4[bstr.charCodeAt(i++)] ^ + T3[bstr.charCodeAt(i++)] ^ + T2[bstr.charCodeAt(i++)] ^ + T1[bstr.charCodeAt(i++)] ^ + T[bstr.charCodeAt(i++)]; + L += 15; + while(i < L) C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF]; + return C ^ -1; +} function crc32_buf(buf, seed) { - if(buf.length > 10000) return crc32_buf_8(buf, seed); + if(buf.length > 2000) return crc32_buf_16(buf, seed); var C = seed ^ -1, L = buf.length - 3; for(var i = 0; i < L;) { C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; @@ -68,26 +108,34 @@ function crc32_buf(buf, seed) { while(i < L+3) C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; return C ^ -1; } - -function crc32_buf_8(buf, seed) { - var C = seed ^ -1, L = buf.length - 7; - for(var i = 0; i < L;) { - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - } - while(i < L+7) C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; +function crc32_buf_16(buf, seed) { + var C = seed ^ -1, L = buf.length - 15; + for(var i = 0; i < L;) C = + Tf[buf[i++] ^ (C & 255)] ^ + Te[buf[i++] ^ ((C >> 8) & 255)] ^ + Td[buf[i++] ^ ((C >> 16) & 255)] ^ + Tc[buf[i++] ^ (C >>> 24)] ^ + Tb[buf[i++]] ^ + Ta[buf[i++]] ^ + T9[buf[i++]] ^ + T8[buf[i++]] ^ + T7[buf[i++]] ^ + T6[buf[i++]] ^ + T5[buf[i++]] ^ + T4[buf[i++]] ^ + T3[buf[i++]] ^ + T2[buf[i++]] ^ + T1[buf[i++]] ^ + T[buf[i++]]; + L += 15; + while(i < L) C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; return C ^ -1; } + function crc32_str(str, seed) { var C = seed ^ -1; - for(var i = 0, L=str.length, c, d; i < L;) { + for(var i = 0, L = str.length, c = 0, d = 0; i < L;) { c = str.charCodeAt(i++); if(c < 0x80) { C = (C>>>8) ^ T[(C ^ c)&0xFF]; -- 2.34.1 From d64513c9525ff50dda0eeb538ed0535a61ae7243 Mon Sep 17 00:00:00 2001 From: SheetJS Date: Tue, 25 Jan 2022 00:48:10 -0500 Subject: [PATCH 06/11] version bump 1.2.1 --- Makefile | 2 +- README.md | 100 ++++++++++++++++++++++++++++----- bits/00_header.js | 2 +- bits/01_version.js | 2 +- bits/20_crctable.js | 6 +- bits/40_crc.js | 106 +++++++++-------------------------- bits/90_exports.js | 2 +- crc32.flow.js | 118 +++++++++++--------------------------- crc32.js | 113 ++++++++++--------------------------- crc32c.flow.js | 134 +++++++++++++------------------------------- crc32c.js | 129 +++++++++++++----------------------------- ctest/crc32.js | 99 ++++++++++++++++---------------- ctest/fixtures.js | 4 +- ctest/test.js | 16 ++++-- package.json | 4 +- 15 files changed, 325 insertions(+), 512 deletions(-) diff --git a/Makefile b/Makefile index eb26e01..14d5128 100644 --- a/Makefile +++ b/Makefile @@ -31,7 +31,7 @@ clean: clean-baseline ## Remove targets and build artifacts rm -f $(TARGET) $(FLOWTARGET) crc32c.flow.js: crc32.flow.js - cat $^ | sed 's/-306674912/-2097792136/g' > $@ + cat $^ | sed 's/-306674912/-2097792136/g; s/CRC32\([ \/\.]\)/CRC32C\1/g' > $@ ## Testing diff --git a/README.md b/README.md index 38445de..082127a 100644 --- a/README.md +++ b/README.md @@ -11,16 +11,57 @@ With [npm](https://www.npmjs.org/package/crc-32): $ npm install crc-32 ``` -In the browser: +When installed globally, npm installs a script `crc32` that computes the +checksum for a specified file or standard input. + +
+ CDN Availability (click to show) + +| CDN | URL | +|-----------:|:-------------------------------------------| +| `unpkg` | | +| `jsDelivr` | | +| `CDNjs` | | + +
+ + +## Integration + +Using NodeJS or a bundler: + +```js +var CRC32 = require("crc-32"); +``` + +In the browser, the `crc32.js` script can be loaded directly: ```html ``` -The browser exposes a variable `CRC32`. +The browser script exposes a variable `CRC32`. -When installed globally, npm installs a script `crc32` that computes the -checksum for a specified file or standard input. +The script will manipulate `module.exports` if available . This is not always +desirable. To prevent the behavior, define `DO_NOT_EXPORT_CRC`. + +### CRC32C (Castagnoli) + +The module and CDNs also include a parallel script for CRC32C calculations. + +Using NodeJS or a bundler: + +```js +var CRC32C = require("crc-32/crc32c"); +``` + +In the browser, the `crc32c.js` script can be loaded directly: + +```html + +``` + +The browser exposes a variable `CRC32C`. The script will manipulate `module.exports` if available . This is not always desirable. To prevent the behavior, define `DO_NOT_EXPORT_CRC`. @@ -44,20 +85,51 @@ The return value is a signed 32-bit integer. For example: ```js -// var CRC32 = require('crc-32'); // uncomment this line if in node -CRC32.str("SheetJS") // -1647298270 -CRC32.bstr("SheetJS") // -1647298270 -CRC32.buf([ 83, 104, 101, 101, 116, 74, 83 ]) // -1647298270 +// var CRC32 = require('crc-32'); // uncomment this line if in node +CRC32.str("SheetJS") // -1647298270 +CRC32.bstr("SheetJS") // -1647298270 +CRC32.buf([ 83, 104, 101, 101, 116, 74, 83 ]) // -1647298270 -crc32 = CRC32.buf([83, 104]) // -1826163454 "Sh" -crc32 = CRC32.str("eet", crc32) // 1191034598 "Sheet" -CRC32.bstr("JS", crc32) // -1647298270 "SheetJS" +crc32 = CRC32.buf([83, 104]) // -1826163454 "Sh" +crc32 = CRC32.str("eet", crc32) // 1191034598 "Sheet" +CRC32.bstr("JS", crc32) // -1647298270 "SheetJS" -[CRC32.str("\u2603"), CRC32.str("\u0003")] // [ -1743909036, 1259060791 ] -[CRC32.bstr("\u2603"), CRC32.bstr("\u0003")] // [ 1259060791, 1259060791 ] -[CRC32.buf([0x2603]), CRC32.buf([0x0003])] // [ 1259060791, 1259060791 ] +[CRC32.str("\u2603"), CRC32.str("\u0003")] // [ -1743909036, 1259060791 ] +[CRC32.bstr("\u2603"), CRC32.bstr("\u0003")] // [ 1259060791, 1259060791 ] +[CRC32.buf([0x2603]), CRC32.buf([0x0003])] // [ 1259060791, 1259060791 ] + +// var CRC32C = require('crc-32/crc32c'); // uncomment this line if in node +CRC32C.str("SheetJS") // -284764294 +CRC32C.bstr("SheetJS") // -284764294 +CRC32C.buf([ 83, 104, 101, 101, 116, 74, 83 ]) // -284764294 + +crc32c = CRC32C.buf([83, 104]) // -297065629 "Sh" +crc32c = CRC32C.str("eet", crc32c) // 1241364256 "Sheet" +CRC32C.bstr("JS", crc32c) // -284764294 "SheetJS" + +[CRC32C.str("\u2603"), CRC32C.str("\u0003")] // [ 1253703093, 1093509285 ] +[CRC32C.bstr("\u2603"), CRC32C.bstr("\u0003")] // [ 1093509285, 1093509285 ] +[CRC32C.buf([0x2603]), CRC32C.buf([0x0003])] // [ 1093509285, 1093509285 ] ``` +### Best Practices + +Even though the initial seed is optional, for performance reasons it is highly +recommended to explicitly pass the default seed 0. + +In NodeJS with the native Buffer implementation, it is oftentimes faster to +convert binary strings with `Buffer.from(bstr, "binary")` first: + +```js +/* Frequently slower in NodeJS */ +crc32 = CRC32.bstr(bstr, 0); +/* Frequently faster in NodeJS */ +crc32 = CRC32.buf(Buffer.from(bstr, "binary"), 0); +``` + +This does not apply to browser `Buffer` shims, and thus is not implemented in +the library directly. + ## Testing `make test` will run the nodejs-based test. diff --git a/bits/00_header.js b/bits/00_header.js index 102cdad..c97b148 100644 --- a/bits/00_header.js +++ b/bits/00_header.js @@ -1,4 +1,4 @@ -/* crc32.js (C) 2014-present SheetJS -- http://sheetjs.com */ +/*! crc32.js (C) 2014-present SheetJS -- http://sheetjs.com */ /* vim: set ts=2: */ /*exported CRC32 */ /*:: declare var DO_NOT_EXPORT_CRC:?boolean; */ diff --git a/bits/01_version.js b/bits/01_version.js index 782ea1d..45bc6f8 100644 --- a/bits/01_version.js +++ b/bits/01_version.js @@ -1 +1 @@ -CRC32.version = '1.2.0'; +CRC32.version = '1.2.1'; diff --git a/bits/20_crctable.js b/bits/20_crctable.js index c0236a1..b187020 100644 --- a/bits/20_crctable.js +++ b/bits/20_crctable.js @@ -1,4 +1,3 @@ -/* see perf/crc32table.js */ /*global Int32Array */ function signed_crc_table()/*:CRC32TableType*/ { var c = 0, table/*:Array*/ = new Array(256); @@ -19,8 +18,7 @@ function signed_crc_table()/*:CRC32TableType*/ { return typeof Int32Array !== 'undefined' ? new Int32Array(table) : table; } -var T = signed_crc_table(); -/*# slice by 16 tables */ +var T0 = signed_crc_table(); function slice_by_16_tables(T) { var c = 0, v = 0, n = 0, table/*:Array*/ = typeof Int32Array !== 'undefined' ? new Int32Array(4096) : new Array(4096) ; @@ -33,7 +31,7 @@ function slice_by_16_tables(T) { for(n = 1; n != 16; ++n) out[n - 1] = typeof Int32Array !== 'undefined' ? table.subarray(n * 256, n * 256 + 256) : table.slice(n * 256, n * 256 + 256); return out; } -var TT = slice_by_16_tables(T); +var TT = slice_by_16_tables(T0); var T1 = TT[0], T2 = TT[1], T3 = TT[2], T4 = TT[3], T5 = TT[4]; var T6 = TT[5], T7 = TT[6], T8 = TT[7], T9 = TT[8], Ta = TT[9]; var Tb = TT[10], Tc = TT[11], Td = TT[12], Te = TT[13], Tf = TT[14]; diff --git a/bits/40_crc.js b/bits/40_crc.js index 0e55946..1a872ab 100644 --- a/bits/40_crc.js +++ b/bits/40_crc.js @@ -1,96 +1,44 @@ -/*# charCodeAt is the best approach for binary strings */ function crc32_bstr(bstr/*:string*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { - if(bstr.length > 10000) return crc32_bstr_16(bstr, seed); - var C = seed/*:: ? 0 : 0 */ ^ -1, L = bstr.length - 1; - for(var i = 0; i < L;) { - C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF]; - C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF]; - } - if(i === L) C = (C>>>8) ^ T[(C ^ bstr.charCodeAt(i))&0xFF]; - return C ^ -1; + var C = seed/*:: ? 0 : 0 */ ^ -1; + for(var i = 0, L = bstr.length; i < L;) C = (C>>>8) ^ T0[(C^bstr.charCodeAt(i++))&0xFF]; + return ~C; } -function crc32_bstr_16(bstr/*:string*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { - var C = seed/*:: ? 0 : 0 */ ^ -1, L = bstr.length - 15; - for(var i = 0; i < L;) C = - Tf[bstr.charCodeAt(i++) ^ (C & 255)] ^ - Te[bstr.charCodeAt(i++) ^ ((C >> 8) & 255)] ^ - Td[bstr.charCodeAt(i++) ^ ((C >> 16) & 255)] ^ - Tc[bstr.charCodeAt(i++) ^ (C >>> 24)] ^ - Tb[bstr.charCodeAt(i++)] ^ - Ta[bstr.charCodeAt(i++)] ^ - T9[bstr.charCodeAt(i++)] ^ - T8[bstr.charCodeAt(i++)] ^ - T7[bstr.charCodeAt(i++)] ^ - T6[bstr.charCodeAt(i++)] ^ - T5[bstr.charCodeAt(i++)] ^ - T4[bstr.charCodeAt(i++)] ^ - T3[bstr.charCodeAt(i++)] ^ - T2[bstr.charCodeAt(i++)] ^ - T1[bstr.charCodeAt(i++)] ^ - T[bstr.charCodeAt(i++)]; + +function crc32_buf(B/*:ABuf*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { + var C = seed/*:: ? 0 : 0 */ ^ -1, L = B.length - 15, i = 0; + for(; i < L;) C = + Tf[B[i++] ^ (C & 255)] ^ + Te[B[i++] ^ ((C >> 8) & 255)] ^ + Td[B[i++] ^ ((C >> 16) & 255)] ^ + Tc[B[i++] ^ (C >>> 24)] ^ + Tb[B[i++]] ^ Ta[B[i++]] ^ T9[B[i++]] ^ T8[B[i++]] ^ + T7[B[i++]] ^ T6[B[i++]] ^ T5[B[i++]] ^ T4[B[i++]] ^ + T3[B[i++]] ^ T2[B[i++]] ^ T1[B[i++]] ^ T0[B[i++]]; L += 15; - while(i < L) C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF]; - return C ^ -1; + while(i < L) C = (C>>>8) ^ T0[(C^B[i++])&0xFF]; + return ~C; } -function crc32_buf(buf/*:ABuf*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { - if(buf.length > 2000) return crc32_buf_16(buf, seed); - var C = seed/*:: ? 0 : 0 */ ^ -1, L = buf.length - 3; - for(var i = 0; i < L;) { - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - } - while(i < L+3) C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - return C ^ -1; -} -function crc32_buf_16(buf/*:ABuf*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { - var C = seed/*:: ? 0 : 0 */ ^ -1, L = buf.length - 15; - for(var i = 0; i < L;) C = - Tf[buf[i++] ^ (C & 255)] ^ - Te[buf[i++] ^ ((C >> 8) & 255)] ^ - Td[buf[i++] ^ ((C >> 16) & 255)] ^ - Tc[buf[i++] ^ (C >>> 24)] ^ - Tb[buf[i++]] ^ - Ta[buf[i++]] ^ - T9[buf[i++]] ^ - T8[buf[i++]] ^ - T7[buf[i++]] ^ - T6[buf[i++]] ^ - T5[buf[i++]] ^ - T4[buf[i++]] ^ - T3[buf[i++]] ^ - T2[buf[i++]] ^ - T1[buf[i++]] ^ - T[buf[i++]]; - L += 15; - while(i < L) C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - return C ^ -1; -} - - -/*# much much faster to intertwine utf8 and crc, slower to slice by 8 or 16 */ function crc32_str(str/*:string*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { var C = seed/*:: ? 0 : 0 */ ^ -1; for(var i = 0, L = str.length, c = 0, d = 0; i < L;) { c = str.charCodeAt(i++); if(c < 0x80) { - C = (C>>>8) ^ T[(C ^ c)&0xFF]; + C = (C>>>8) ^ T0[(C^c)&0xFF]; } else if(c < 0x800) { - C = (C>>>8) ^ T[(C ^ (192|((c>>6)&31)))&0xFF]; - C = (C>>>8) ^ T[(C ^ (128|(c&63)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (192|((c>>6)&31)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|(c&63)))&0xFF]; } else if(c >= 0xD800 && c < 0xE000) { c = (c&1023)+64; d = str.charCodeAt(i++)&1023; - C = (C>>>8) ^ T[(C ^ (240|((c>>8)&7)))&0xFF]; - C = (C>>>8) ^ T[(C ^ (128|((c>>2)&63)))&0xFF]; - C = (C>>>8) ^ T[(C ^ (128|((d>>6)&15)|((c&3)<<4)))&0xFF]; - C = (C>>>8) ^ T[(C ^ (128|(d&63)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (240|((c>>8)&7)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|((c>>2)&63)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|((d>>6)&15)|((c&3)<<4)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|(d&63)))&0xFF]; } else { - C = (C>>>8) ^ T[(C ^ (224|((c>>12)&15)))&0xFF]; - C = (C>>>8) ^ T[(C ^ (128|((c>>6)&63)))&0xFF]; - C = (C>>>8) ^ T[(C ^ (128|(c&63)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (224|((c>>12)&15)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|((c>>6)&63)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|(c&63)))&0xFF]; } } - return C ^ -1; + return ~C; } diff --git a/bits/90_exports.js b/bits/90_exports.js index 76e4ccf..90570b1 100644 --- a/bits/90_exports.js +++ b/bits/90_exports.js @@ -1,4 +1,4 @@ -CRC32.table = T; +CRC32.table = T0; // $FlowIgnore CRC32.bstr = crc32_bstr; // $FlowIgnore diff --git a/crc32.flow.js b/crc32.flow.js index 18e5725..3a80772 100644 --- a/crc32.flow.js +++ b/crc32.flow.js @@ -1,4 +1,4 @@ -/* crc32.js (C) 2014-present SheetJS -- http://sheetjs.com */ +/*! crc32.js (C) 2014-present SheetJS -- http://sheetjs.com */ /* vim: set ts=2: */ /*exported CRC32 */ /*:: declare var DO_NOT_EXPORT_CRC:?boolean; */ @@ -25,13 +25,12 @@ var CRC32/*:CRC32Module*/; /*eslint-enable */ /*jshint ignore:end */ }(function(CRC32/*:CRC32Module*/) { -CRC32.version = '1.2.0'; +CRC32.version = '1.2.1'; /*:: type CRC32Type = number; type ABuf = Array | Buffer | Uint8Array; type CRC32TableType = Array | Int32Array; */ -/* see perf/crc32table.js */ /*global Int32Array */ function signed_crc_table()/*:CRC32TableType*/ { var c = 0, table/*:Array*/ = new Array(256); @@ -52,8 +51,7 @@ function signed_crc_table()/*:CRC32TableType*/ { return typeof Int32Array !== 'undefined' ? new Int32Array(table) : table; } -var T = signed_crc_table(); -/*# slice by 16 tables */ +var T0 = signed_crc_table(); function slice_by_16_tables(T) { var c = 0, v = 0, n = 0, table/*:Array*/ = typeof Int32Array !== 'undefined' ? new Int32Array(4096) : new Array(4096) ; @@ -66,107 +64,55 @@ function slice_by_16_tables(T) { for(n = 1; n != 16; ++n) out[n - 1] = typeof Int32Array !== 'undefined' ? table.subarray(n * 256, n * 256 + 256) : table.slice(n * 256, n * 256 + 256); return out; } -var TT = slice_by_16_tables(T); +var TT = slice_by_16_tables(T0); var T1 = TT[0], T2 = TT[1], T3 = TT[2], T4 = TT[3], T5 = TT[4]; var T6 = TT[5], T7 = TT[6], T8 = TT[7], T9 = TT[8], Ta = TT[9]; var Tb = TT[10], Tc = TT[11], Td = TT[12], Te = TT[13], Tf = TT[14]; -/*# charCodeAt is the best approach for binary strings */ function crc32_bstr(bstr/*:string*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { - if(bstr.length > 10000) return crc32_bstr_16(bstr, seed); - var C = seed/*:: ? 0 : 0 */ ^ -1, L = bstr.length - 1; - for(var i = 0; i < L;) { - C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF]; - C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF]; - } - if(i === L) C = (C>>>8) ^ T[(C ^ bstr.charCodeAt(i))&0xFF]; - return C ^ -1; + var C = seed/*:: ? 0 : 0 */ ^ -1; + for(var i = 0, L = bstr.length; i < L;) C = (C>>>8) ^ T0[(C^bstr.charCodeAt(i++))&0xFF]; + return ~C; } -function crc32_bstr_16(bstr/*:string*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { - var C = seed/*:: ? 0 : 0 */ ^ -1, L = bstr.length - 15; - for(var i = 0; i < L;) C = - Tf[bstr.charCodeAt(i++) ^ (C & 255)] ^ - Te[bstr.charCodeAt(i++) ^ ((C >> 8) & 255)] ^ - Td[bstr.charCodeAt(i++) ^ ((C >> 16) & 255)] ^ - Tc[bstr.charCodeAt(i++) ^ (C >>> 24)] ^ - Tb[bstr.charCodeAt(i++)] ^ - Ta[bstr.charCodeAt(i++)] ^ - T9[bstr.charCodeAt(i++)] ^ - T8[bstr.charCodeAt(i++)] ^ - T7[bstr.charCodeAt(i++)] ^ - T6[bstr.charCodeAt(i++)] ^ - T5[bstr.charCodeAt(i++)] ^ - T4[bstr.charCodeAt(i++)] ^ - T3[bstr.charCodeAt(i++)] ^ - T2[bstr.charCodeAt(i++)] ^ - T1[bstr.charCodeAt(i++)] ^ - T[bstr.charCodeAt(i++)]; + +function crc32_buf(B/*:ABuf*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { + var C = seed/*:: ? 0 : 0 */ ^ -1, L = B.length - 15, i = 0; + for(; i < L;) C = + Tf[B[i++] ^ (C & 255)] ^ + Te[B[i++] ^ ((C >> 8) & 255)] ^ + Td[B[i++] ^ ((C >> 16) & 255)] ^ + Tc[B[i++] ^ (C >>> 24)] ^ + Tb[B[i++]] ^ Ta[B[i++]] ^ T9[B[i++]] ^ T8[B[i++]] ^ + T7[B[i++]] ^ T6[B[i++]] ^ T5[B[i++]] ^ T4[B[i++]] ^ + T3[B[i++]] ^ T2[B[i++]] ^ T1[B[i++]] ^ T0[B[i++]]; L += 15; - while(i < L) C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF]; - return C ^ -1; + while(i < L) C = (C>>>8) ^ T0[(C^B[i++])&0xFF]; + return ~C; } -function crc32_buf(buf/*:ABuf*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { - if(buf.length > 2000) return crc32_buf_16(buf, seed); - var C = seed/*:: ? 0 : 0 */ ^ -1, L = buf.length - 3; - for(var i = 0; i < L;) { - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - } - while(i < L+3) C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - return C ^ -1; -} -function crc32_buf_16(buf/*:ABuf*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { - var C = seed/*:: ? 0 : 0 */ ^ -1, L = buf.length - 15; - for(var i = 0; i < L;) C = - Tf[buf[i++] ^ (C & 255)] ^ - Te[buf[i++] ^ ((C >> 8) & 255)] ^ - Td[buf[i++] ^ ((C >> 16) & 255)] ^ - Tc[buf[i++] ^ (C >>> 24)] ^ - Tb[buf[i++]] ^ - Ta[buf[i++]] ^ - T9[buf[i++]] ^ - T8[buf[i++]] ^ - T7[buf[i++]] ^ - T6[buf[i++]] ^ - T5[buf[i++]] ^ - T4[buf[i++]] ^ - T3[buf[i++]] ^ - T2[buf[i++]] ^ - T1[buf[i++]] ^ - T[buf[i++]]; - L += 15; - while(i < L) C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - return C ^ -1; -} - - -/*# much much faster to intertwine utf8 and crc, slower to slice by 8 or 16 */ function crc32_str(str/*:string*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { var C = seed/*:: ? 0 : 0 */ ^ -1; for(var i = 0, L = str.length, c = 0, d = 0; i < L;) { c = str.charCodeAt(i++); if(c < 0x80) { - C = (C>>>8) ^ T[(C ^ c)&0xFF]; + C = (C>>>8) ^ T0[(C^c)&0xFF]; } else if(c < 0x800) { - C = (C>>>8) ^ T[(C ^ (192|((c>>6)&31)))&0xFF]; - C = (C>>>8) ^ T[(C ^ (128|(c&63)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (192|((c>>6)&31)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|(c&63)))&0xFF]; } else if(c >= 0xD800 && c < 0xE000) { c = (c&1023)+64; d = str.charCodeAt(i++)&1023; - C = (C>>>8) ^ T[(C ^ (240|((c>>8)&7)))&0xFF]; - C = (C>>>8) ^ T[(C ^ (128|((c>>2)&63)))&0xFF]; - C = (C>>>8) ^ T[(C ^ (128|((d>>6)&15)|((c&3)<<4)))&0xFF]; - C = (C>>>8) ^ T[(C ^ (128|(d&63)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (240|((c>>8)&7)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|((c>>2)&63)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|((d>>6)&15)|((c&3)<<4)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|(d&63)))&0xFF]; } else { - C = (C>>>8) ^ T[(C ^ (224|((c>>12)&15)))&0xFF]; - C = (C>>>8) ^ T[(C ^ (128|((c>>6)&63)))&0xFF]; - C = (C>>>8) ^ T[(C ^ (128|(c&63)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (224|((c>>12)&15)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|((c>>6)&63)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|(c&63)))&0xFF]; } } - return C ^ -1; + return ~C; } -CRC32.table = T; +CRC32.table = T0; // $FlowIgnore CRC32.bstr = crc32_bstr; // $FlowIgnore diff --git a/crc32.js b/crc32.js index b310fb9..af85913 100644 --- a/crc32.js +++ b/crc32.js @@ -1,4 +1,4 @@ -/* crc32.js (C) 2014-present SheetJS -- http://sheetjs.com */ +/*! crc32.js (C) 2014-present SheetJS -- http://sheetjs.com */ /* vim: set ts=2: */ /*exported CRC32 */ var CRC32; @@ -23,8 +23,7 @@ var CRC32; /*eslint-enable */ /*jshint ignore:end */ }(function(CRC32) { -CRC32.version = '1.2.0'; -/* see perf/crc32table.js */ +CRC32.version = '1.2.1'; /*global Int32Array */ function signed_crc_table() { var c = 0, table = new Array(256); @@ -45,7 +44,7 @@ function signed_crc_table() { return typeof Int32Array !== 'undefined' ? new Int32Array(table) : table; } -var T = signed_crc_table(); +var T0 = signed_crc_table(); function slice_by_16_tables(T) { var c = 0, v = 0, n = 0, table = typeof Int32Array !== 'undefined' ? new Int32Array(4096) : new Array(4096) ; @@ -58,105 +57,55 @@ function slice_by_16_tables(T) { for(n = 1; n != 16; ++n) out[n - 1] = typeof Int32Array !== 'undefined' ? table.subarray(n * 256, n * 256 + 256) : table.slice(n * 256, n * 256 + 256); return out; } -var TT = slice_by_16_tables(T); +var TT = slice_by_16_tables(T0); var T1 = TT[0], T2 = TT[1], T3 = TT[2], T4 = TT[3], T5 = TT[4]; var T6 = TT[5], T7 = TT[6], T8 = TT[7], T9 = TT[8], Ta = TT[9]; var Tb = TT[10], Tc = TT[11], Td = TT[12], Te = TT[13], Tf = TT[14]; function crc32_bstr(bstr, seed) { - if(bstr.length > 10000) return crc32_bstr_16(bstr, seed); - var C = seed ^ -1, L = bstr.length - 1; - for(var i = 0; i < L;) { - C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF]; - C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF]; - } - if(i === L) C = (C>>>8) ^ T[(C ^ bstr.charCodeAt(i))&0xFF]; - return C ^ -1; -} -function crc32_bstr_16(bstr, seed) { - var C = seed ^ -1, L = bstr.length - 15; - for(var i = 0; i < L;) C = - Tf[bstr.charCodeAt(i++) ^ (C & 255)] ^ - Te[bstr.charCodeAt(i++) ^ ((C >> 8) & 255)] ^ - Td[bstr.charCodeAt(i++) ^ ((C >> 16) & 255)] ^ - Tc[bstr.charCodeAt(i++) ^ (C >>> 24)] ^ - Tb[bstr.charCodeAt(i++)] ^ - Ta[bstr.charCodeAt(i++)] ^ - T9[bstr.charCodeAt(i++)] ^ - T8[bstr.charCodeAt(i++)] ^ - T7[bstr.charCodeAt(i++)] ^ - T6[bstr.charCodeAt(i++)] ^ - T5[bstr.charCodeAt(i++)] ^ - T4[bstr.charCodeAt(i++)] ^ - T3[bstr.charCodeAt(i++)] ^ - T2[bstr.charCodeAt(i++)] ^ - T1[bstr.charCodeAt(i++)] ^ - T[bstr.charCodeAt(i++)]; - L += 15; - while(i < L) C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF]; - return C ^ -1; + var C = seed ^ -1; + for(var i = 0, L = bstr.length; i < L;) C = (C>>>8) ^ T0[(C^bstr.charCodeAt(i++))&0xFF]; + return ~C; } -function crc32_buf(buf, seed) { - if(buf.length > 2000) return crc32_buf_16(buf, seed); - var C = seed ^ -1, L = buf.length - 3; - for(var i = 0; i < L;) { - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - } - while(i < L+3) C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - return C ^ -1; -} -function crc32_buf_16(buf, seed) { - var C = seed ^ -1, L = buf.length - 15; - for(var i = 0; i < L;) C = - Tf[buf[i++] ^ (C & 255)] ^ - Te[buf[i++] ^ ((C >> 8) & 255)] ^ - Td[buf[i++] ^ ((C >> 16) & 255)] ^ - Tc[buf[i++] ^ (C >>> 24)] ^ - Tb[buf[i++]] ^ - Ta[buf[i++]] ^ - T9[buf[i++]] ^ - T8[buf[i++]] ^ - T7[buf[i++]] ^ - T6[buf[i++]] ^ - T5[buf[i++]] ^ - T4[buf[i++]] ^ - T3[buf[i++]] ^ - T2[buf[i++]] ^ - T1[buf[i++]] ^ - T[buf[i++]]; +function crc32_buf(B, seed) { + var C = seed ^ -1, L = B.length - 15, i = 0; + for(; i < L;) C = + Tf[B[i++] ^ (C & 255)] ^ + Te[B[i++] ^ ((C >> 8) & 255)] ^ + Td[B[i++] ^ ((C >> 16) & 255)] ^ + Tc[B[i++] ^ (C >>> 24)] ^ + Tb[B[i++]] ^ Ta[B[i++]] ^ T9[B[i++]] ^ T8[B[i++]] ^ + T7[B[i++]] ^ T6[B[i++]] ^ T5[B[i++]] ^ T4[B[i++]] ^ + T3[B[i++]] ^ T2[B[i++]] ^ T1[B[i++]] ^ T0[B[i++]]; L += 15; - while(i < L) C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - return C ^ -1; + while(i < L) C = (C>>>8) ^ T0[(C^B[i++])&0xFF]; + return ~C; } - function crc32_str(str, seed) { var C = seed ^ -1; for(var i = 0, L = str.length, c = 0, d = 0; i < L;) { c = str.charCodeAt(i++); if(c < 0x80) { - C = (C>>>8) ^ T[(C ^ c)&0xFF]; + C = (C>>>8) ^ T0[(C^c)&0xFF]; } else if(c < 0x800) { - C = (C>>>8) ^ T[(C ^ (192|((c>>6)&31)))&0xFF]; - C = (C>>>8) ^ T[(C ^ (128|(c&63)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (192|((c>>6)&31)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|(c&63)))&0xFF]; } else if(c >= 0xD800 && c < 0xE000) { c = (c&1023)+64; d = str.charCodeAt(i++)&1023; - C = (C>>>8) ^ T[(C ^ (240|((c>>8)&7)))&0xFF]; - C = (C>>>8) ^ T[(C ^ (128|((c>>2)&63)))&0xFF]; - C = (C>>>8) ^ T[(C ^ (128|((d>>6)&15)|((c&3)<<4)))&0xFF]; - C = (C>>>8) ^ T[(C ^ (128|(d&63)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (240|((c>>8)&7)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|((c>>2)&63)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|((d>>6)&15)|((c&3)<<4)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|(d&63)))&0xFF]; } else { - C = (C>>>8) ^ T[(C ^ (224|((c>>12)&15)))&0xFF]; - C = (C>>>8) ^ T[(C ^ (128|((c>>6)&63)))&0xFF]; - C = (C>>>8) ^ T[(C ^ (128|(c&63)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (224|((c>>12)&15)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|((c>>6)&63)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|(c&63)))&0xFF]; } } - return C ^ -1; + return ~C; } -CRC32.table = T; +CRC32.table = T0; // $FlowIgnore CRC32.bstr = crc32_bstr; // $FlowIgnore diff --git a/crc32c.flow.js b/crc32c.flow.js index fae81b1..ea7872c 100644 --- a/crc32c.flow.js +++ b/crc32c.flow.js @@ -1,9 +1,9 @@ -/* crc32.js (C) 2014-present SheetJS -- http://sheetjs.com */ +/*! crc32.js (C) 2014-present SheetJS -- http://sheetjs.com */ /* vim: set ts=2: */ -/*exported CRC32 */ +/*exported CRC32C */ /*:: declare var DO_NOT_EXPORT_CRC:?boolean; */ /*:: declare function define(cb:()=>any):void; */ -var CRC32/*:CRC32Module*/; +var CRC32C/*:CRC32Module*/; (function (factory/*:(a:any)=>void*/)/*:void*/ { /*jshint ignore:start */ /*eslint-disable */ @@ -17,21 +17,20 @@ var CRC32/*:CRC32Module*/; return module; }); } else { - factory(CRC32 = /*::(*/{}/*:: :any)*/); + factory(CRC32C = /*::(*/{}/*:: :any)*/); } } else { - factory(CRC32 = /*::(*/{}/*:: :any)*/); + factory(CRC32C = /*::(*/{}/*:: :any)*/); } /*eslint-enable */ /*jshint ignore:end */ -}(function(CRC32/*:CRC32Module*/) { -CRC32.version = '1.2.0'; +}(function(CRC32C/*:CRC32Module*/) { +CRC32C.version = '1.2.1'; /*:: type CRC32Type = number; type ABuf = Array | Buffer | Uint8Array; type CRC32TableType = Array | Int32Array; */ -/* see perf/crc32table.js */ /*global Int32Array */ function signed_crc_table()/*:CRC32TableType*/ { var c = 0, table/*:Array*/ = new Array(256); @@ -52,8 +51,7 @@ function signed_crc_table()/*:CRC32TableType*/ { return typeof Int32Array !== 'undefined' ? new Int32Array(table) : table; } -var T = signed_crc_table(); -/*# slice by 16 tables */ +var T0 = signed_crc_table(); function slice_by_16_tables(T) { var c = 0, v = 0, n = 0, table/*:Array*/ = typeof Int32Array !== 'undefined' ? new Int32Array(4096) : new Array(4096) ; @@ -66,111 +64,59 @@ function slice_by_16_tables(T) { for(n = 1; n != 16; ++n) out[n - 1] = typeof Int32Array !== 'undefined' ? table.subarray(n * 256, n * 256 + 256) : table.slice(n * 256, n * 256 + 256); return out; } -var TT = slice_by_16_tables(T); +var TT = slice_by_16_tables(T0); var T1 = TT[0], T2 = TT[1], T3 = TT[2], T4 = TT[3], T5 = TT[4]; var T6 = TT[5], T7 = TT[6], T8 = TT[7], T9 = TT[8], Ta = TT[9]; var Tb = TT[10], Tc = TT[11], Td = TT[12], Te = TT[13], Tf = TT[14]; -/*# charCodeAt is the best approach for binary strings */ function crc32_bstr(bstr/*:string*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { - if(bstr.length > 10000) return crc32_bstr_16(bstr, seed); - var C = seed/*:: ? 0 : 0 */ ^ -1, L = bstr.length - 1; - for(var i = 0; i < L;) { - C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF]; - C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF]; - } - if(i === L) C = (C>>>8) ^ T[(C ^ bstr.charCodeAt(i))&0xFF]; - return C ^ -1; + var C = seed/*:: ? 0 : 0 */ ^ -1; + for(var i = 0, L = bstr.length; i < L;) C = (C>>>8) ^ T0[(C^bstr.charCodeAt(i++))&0xFF]; + return ~C; } -function crc32_bstr_16(bstr/*:string*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { - var C = seed/*:: ? 0 : 0 */ ^ -1, L = bstr.length - 15; - for(var i = 0; i < L;) C = - Tf[bstr.charCodeAt(i++) ^ (C & 255)] ^ - Te[bstr.charCodeAt(i++) ^ ((C >> 8) & 255)] ^ - Td[bstr.charCodeAt(i++) ^ ((C >> 16) & 255)] ^ - Tc[bstr.charCodeAt(i++) ^ (C >>> 24)] ^ - Tb[bstr.charCodeAt(i++)] ^ - Ta[bstr.charCodeAt(i++)] ^ - T9[bstr.charCodeAt(i++)] ^ - T8[bstr.charCodeAt(i++)] ^ - T7[bstr.charCodeAt(i++)] ^ - T6[bstr.charCodeAt(i++)] ^ - T5[bstr.charCodeAt(i++)] ^ - T4[bstr.charCodeAt(i++)] ^ - T3[bstr.charCodeAt(i++)] ^ - T2[bstr.charCodeAt(i++)] ^ - T1[bstr.charCodeAt(i++)] ^ - T[bstr.charCodeAt(i++)]; + +function crc32_buf(B/*:ABuf*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { + var C = seed/*:: ? 0 : 0 */ ^ -1, L = B.length - 15, i = 0; + for(; i < L;) C = + Tf[B[i++] ^ (C & 255)] ^ + Te[B[i++] ^ ((C >> 8) & 255)] ^ + Td[B[i++] ^ ((C >> 16) & 255)] ^ + Tc[B[i++] ^ (C >>> 24)] ^ + Tb[B[i++]] ^ Ta[B[i++]] ^ T9[B[i++]] ^ T8[B[i++]] ^ + T7[B[i++]] ^ T6[B[i++]] ^ T5[B[i++]] ^ T4[B[i++]] ^ + T3[B[i++]] ^ T2[B[i++]] ^ T1[B[i++]] ^ T0[B[i++]]; L += 15; - while(i < L) C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF]; - return C ^ -1; + while(i < L) C = (C>>>8) ^ T0[(C^B[i++])&0xFF]; + return ~C; } -function crc32_buf(buf/*:ABuf*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { - if(buf.length > 2000) return crc32_buf_16(buf, seed); - var C = seed/*:: ? 0 : 0 */ ^ -1, L = buf.length - 3; - for(var i = 0; i < L;) { - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - } - while(i < L+3) C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - return C ^ -1; -} -function crc32_buf_16(buf/*:ABuf*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { - var C = seed/*:: ? 0 : 0 */ ^ -1, L = buf.length - 15; - for(var i = 0; i < L;) C = - Tf[buf[i++] ^ (C & 255)] ^ - Te[buf[i++] ^ ((C >> 8) & 255)] ^ - Td[buf[i++] ^ ((C >> 16) & 255)] ^ - Tc[buf[i++] ^ (C >>> 24)] ^ - Tb[buf[i++]] ^ - Ta[buf[i++]] ^ - T9[buf[i++]] ^ - T8[buf[i++]] ^ - T7[buf[i++]] ^ - T6[buf[i++]] ^ - T5[buf[i++]] ^ - T4[buf[i++]] ^ - T3[buf[i++]] ^ - T2[buf[i++]] ^ - T1[buf[i++]] ^ - T[buf[i++]]; - L += 15; - while(i < L) C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - return C ^ -1; -} - - -/*# much much faster to intertwine utf8 and crc, slower to slice by 8 or 16 */ function crc32_str(str/*:string*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { var C = seed/*:: ? 0 : 0 */ ^ -1; for(var i = 0, L = str.length, c = 0, d = 0; i < L;) { c = str.charCodeAt(i++); if(c < 0x80) { - C = (C>>>8) ^ T[(C ^ c)&0xFF]; + C = (C>>>8) ^ T0[(C^c)&0xFF]; } else if(c < 0x800) { - C = (C>>>8) ^ T[(C ^ (192|((c>>6)&31)))&0xFF]; - C = (C>>>8) ^ T[(C ^ (128|(c&63)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (192|((c>>6)&31)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|(c&63)))&0xFF]; } else if(c >= 0xD800 && c < 0xE000) { c = (c&1023)+64; d = str.charCodeAt(i++)&1023; - C = (C>>>8) ^ T[(C ^ (240|((c>>8)&7)))&0xFF]; - C = (C>>>8) ^ T[(C ^ (128|((c>>2)&63)))&0xFF]; - C = (C>>>8) ^ T[(C ^ (128|((d>>6)&15)|((c&3)<<4)))&0xFF]; - C = (C>>>8) ^ T[(C ^ (128|(d&63)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (240|((c>>8)&7)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|((c>>2)&63)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|((d>>6)&15)|((c&3)<<4)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|(d&63)))&0xFF]; } else { - C = (C>>>8) ^ T[(C ^ (224|((c>>12)&15)))&0xFF]; - C = (C>>>8) ^ T[(C ^ (128|((c>>6)&63)))&0xFF]; - C = (C>>>8) ^ T[(C ^ (128|(c&63)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (224|((c>>12)&15)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|((c>>6)&63)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|(c&63)))&0xFF]; } } - return C ^ -1; + return ~C; } -CRC32.table = T; +CRC32C.table = T0; // $FlowIgnore -CRC32.bstr = crc32_bstr; +CRC32C.bstr = crc32_bstr; // $FlowIgnore -CRC32.buf = crc32_buf; +CRC32C.buf = crc32_buf; // $FlowIgnore -CRC32.str = crc32_str; +CRC32C.str = crc32_str; })); diff --git a/crc32c.js b/crc32c.js index 7b471c0..6247199 100644 --- a/crc32c.js +++ b/crc32c.js @@ -1,7 +1,7 @@ -/* crc32.js (C) 2014-present SheetJS -- http://sheetjs.com */ +/*! crc32.js (C) 2014-present SheetJS -- http://sheetjs.com */ /* vim: set ts=2: */ -/*exported CRC32 */ -var CRC32; +/*exported CRC32C */ +var CRC32C; (function (factory) { /*jshint ignore:start */ /*eslint-disable */ @@ -15,16 +15,15 @@ var CRC32; return module; }); } else { - factory(CRC32 = {}); + factory(CRC32C = {}); } } else { - factory(CRC32 = {}); + factory(CRC32C = {}); } /*eslint-enable */ /*jshint ignore:end */ -}(function(CRC32) { -CRC32.version = '1.2.0'; -/* see perf/crc32table.js */ +}(function(CRC32C) { +CRC32C.version = '1.2.1'; /*global Int32Array */ function signed_crc_table() { var c = 0, table = new Array(256); @@ -45,7 +44,7 @@ function signed_crc_table() { return typeof Int32Array !== 'undefined' ? new Int32Array(table) : table; } -var T = signed_crc_table(); +var T0 = signed_crc_table(); function slice_by_16_tables(T) { var c = 0, v = 0, n = 0, table = typeof Int32Array !== 'undefined' ? new Int32Array(4096) : new Array(4096) ; @@ -58,109 +57,59 @@ function slice_by_16_tables(T) { for(n = 1; n != 16; ++n) out[n - 1] = typeof Int32Array !== 'undefined' ? table.subarray(n * 256, n * 256 + 256) : table.slice(n * 256, n * 256 + 256); return out; } -var TT = slice_by_16_tables(T); +var TT = slice_by_16_tables(T0); var T1 = TT[0], T2 = TT[1], T3 = TT[2], T4 = TT[3], T5 = TT[4]; var T6 = TT[5], T7 = TT[6], T8 = TT[7], T9 = TT[8], Ta = TT[9]; var Tb = TT[10], Tc = TT[11], Td = TT[12], Te = TT[13], Tf = TT[14]; function crc32_bstr(bstr, seed) { - if(bstr.length > 10000) return crc32_bstr_16(bstr, seed); - var C = seed ^ -1, L = bstr.length - 1; - for(var i = 0; i < L;) { - C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF]; - C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF]; - } - if(i === L) C = (C>>>8) ^ T[(C ^ bstr.charCodeAt(i))&0xFF]; - return C ^ -1; -} -function crc32_bstr_16(bstr, seed) { - var C = seed ^ -1, L = bstr.length - 15; - for(var i = 0; i < L;) C = - Tf[bstr.charCodeAt(i++) ^ (C & 255)] ^ - Te[bstr.charCodeAt(i++) ^ ((C >> 8) & 255)] ^ - Td[bstr.charCodeAt(i++) ^ ((C >> 16) & 255)] ^ - Tc[bstr.charCodeAt(i++) ^ (C >>> 24)] ^ - Tb[bstr.charCodeAt(i++)] ^ - Ta[bstr.charCodeAt(i++)] ^ - T9[bstr.charCodeAt(i++)] ^ - T8[bstr.charCodeAt(i++)] ^ - T7[bstr.charCodeAt(i++)] ^ - T6[bstr.charCodeAt(i++)] ^ - T5[bstr.charCodeAt(i++)] ^ - T4[bstr.charCodeAt(i++)] ^ - T3[bstr.charCodeAt(i++)] ^ - T2[bstr.charCodeAt(i++)] ^ - T1[bstr.charCodeAt(i++)] ^ - T[bstr.charCodeAt(i++)]; - L += 15; - while(i < L) C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF]; - return C ^ -1; + var C = seed ^ -1; + for(var i = 0, L = bstr.length; i < L;) C = (C>>>8) ^ T0[(C^bstr.charCodeAt(i++))&0xFF]; + return ~C; } -function crc32_buf(buf, seed) { - if(buf.length > 2000) return crc32_buf_16(buf, seed); - var C = seed ^ -1, L = buf.length - 3; - for(var i = 0; i < L;) { - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - } - while(i < L+3) C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - return C ^ -1; -} -function crc32_buf_16(buf, seed) { - var C = seed ^ -1, L = buf.length - 15; - for(var i = 0; i < L;) C = - Tf[buf[i++] ^ (C & 255)] ^ - Te[buf[i++] ^ ((C >> 8) & 255)] ^ - Td[buf[i++] ^ ((C >> 16) & 255)] ^ - Tc[buf[i++] ^ (C >>> 24)] ^ - Tb[buf[i++]] ^ - Ta[buf[i++]] ^ - T9[buf[i++]] ^ - T8[buf[i++]] ^ - T7[buf[i++]] ^ - T6[buf[i++]] ^ - T5[buf[i++]] ^ - T4[buf[i++]] ^ - T3[buf[i++]] ^ - T2[buf[i++]] ^ - T1[buf[i++]] ^ - T[buf[i++]]; +function crc32_buf(B, seed) { + var C = seed ^ -1, L = B.length - 15, i = 0; + for(; i < L;) C = + Tf[B[i++] ^ (C & 255)] ^ + Te[B[i++] ^ ((C >> 8) & 255)] ^ + Td[B[i++] ^ ((C >> 16) & 255)] ^ + Tc[B[i++] ^ (C >>> 24)] ^ + Tb[B[i++]] ^ Ta[B[i++]] ^ T9[B[i++]] ^ T8[B[i++]] ^ + T7[B[i++]] ^ T6[B[i++]] ^ T5[B[i++]] ^ T4[B[i++]] ^ + T3[B[i++]] ^ T2[B[i++]] ^ T1[B[i++]] ^ T0[B[i++]]; L += 15; - while(i < L) C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - return C ^ -1; + while(i < L) C = (C>>>8) ^ T0[(C^B[i++])&0xFF]; + return ~C; } - function crc32_str(str, seed) { var C = seed ^ -1; for(var i = 0, L = str.length, c = 0, d = 0; i < L;) { c = str.charCodeAt(i++); if(c < 0x80) { - C = (C>>>8) ^ T[(C ^ c)&0xFF]; + C = (C>>>8) ^ T0[(C^c)&0xFF]; } else if(c < 0x800) { - C = (C>>>8) ^ T[(C ^ (192|((c>>6)&31)))&0xFF]; - C = (C>>>8) ^ T[(C ^ (128|(c&63)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (192|((c>>6)&31)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|(c&63)))&0xFF]; } else if(c >= 0xD800 && c < 0xE000) { c = (c&1023)+64; d = str.charCodeAt(i++)&1023; - C = (C>>>8) ^ T[(C ^ (240|((c>>8)&7)))&0xFF]; - C = (C>>>8) ^ T[(C ^ (128|((c>>2)&63)))&0xFF]; - C = (C>>>8) ^ T[(C ^ (128|((d>>6)&15)|((c&3)<<4)))&0xFF]; - C = (C>>>8) ^ T[(C ^ (128|(d&63)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (240|((c>>8)&7)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|((c>>2)&63)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|((d>>6)&15)|((c&3)<<4)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|(d&63)))&0xFF]; } else { - C = (C>>>8) ^ T[(C ^ (224|((c>>12)&15)))&0xFF]; - C = (C>>>8) ^ T[(C ^ (128|((c>>6)&63)))&0xFF]; - C = (C>>>8) ^ T[(C ^ (128|(c&63)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (224|((c>>12)&15)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|((c>>6)&63)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|(c&63)))&0xFF]; } } - return C ^ -1; + return ~C; } -CRC32.table = T; +CRC32C.table = T0; // $FlowIgnore -CRC32.bstr = crc32_bstr; +CRC32C.bstr = crc32_bstr; // $FlowIgnore -CRC32.buf = crc32_buf; +CRC32C.buf = crc32_buf; // $FlowIgnore -CRC32.str = crc32_str; +CRC32C.str = crc32_str; })); diff --git a/ctest/crc32.js b/ctest/crc32.js index 6bcecef..af85913 100644 --- a/ctest/crc32.js +++ b/ctest/crc32.js @@ -1,4 +1,4 @@ -/* crc32.js (C) 2014-present SheetJS -- http://sheetjs.com */ +/*! crc32.js (C) 2014-present SheetJS -- http://sheetjs.com */ /* vim: set ts=2: */ /*exported CRC32 */ var CRC32; @@ -23,8 +23,7 @@ var CRC32; /*eslint-enable */ /*jshint ignore:end */ }(function(CRC32) { -CRC32.version = '1.2.0'; -/* see perf/crc32table.js */ +CRC32.version = '1.2.1'; /*global Int32Array */ function signed_crc_table() { var c = 0, table = new Array(256); @@ -45,70 +44,68 @@ function signed_crc_table() { return typeof Int32Array !== 'undefined' ? new Int32Array(table) : table; } -var T = signed_crc_table(); +var T0 = signed_crc_table(); +function slice_by_16_tables(T) { + var c = 0, v = 0, n = 0, table = typeof Int32Array !== 'undefined' ? new Int32Array(4096) : new Array(4096) ; + + for(n = 0; n != 256; ++n) table[n] = T[n]; + for(n = 0; n != 256; ++n) { + v = T[n]; + for(c = 256 + n; c < 4096; c += 256) v = table[c] = (v >>> 8) ^ T[v & 0xFF]; + } + var out = []; + for(n = 1; n != 16; ++n) out[n - 1] = typeof Int32Array !== 'undefined' ? table.subarray(n * 256, n * 256 + 256) : table.slice(n * 256, n * 256 + 256); + return out; +} +var TT = slice_by_16_tables(T0); +var T1 = TT[0], T2 = TT[1], T3 = TT[2], T4 = TT[3], T5 = TT[4]; +var T6 = TT[5], T7 = TT[6], T8 = TT[7], T9 = TT[8], Ta = TT[9]; +var Tb = TT[10], Tc = TT[11], Td = TT[12], Te = TT[13], Tf = TT[14]; function crc32_bstr(bstr, seed) { - var C = seed ^ -1, L = bstr.length - 1; - for(var i = 0; i < L;) { - C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF]; - C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF]; - } - if(i === L) C = (C>>>8) ^ T[(C ^ bstr.charCodeAt(i))&0xFF]; - return C ^ -1; + var C = seed ^ -1; + for(var i = 0, L = bstr.length; i < L;) C = (C>>>8) ^ T0[(C^bstr.charCodeAt(i++))&0xFF]; + return ~C; } -function crc32_buf(buf, seed) { - if(buf.length > 10000) return crc32_buf_8(buf, seed); - var C = seed ^ -1, L = buf.length - 3; - for(var i = 0; i < L;) { - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - } - while(i < L+3) C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - return C ^ -1; -} - -function crc32_buf_8(buf, seed) { - var C = seed ^ -1, L = buf.length - 7; - for(var i = 0; i < L;) { - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - } - while(i < L+7) C = (C>>>8) ^ T[(C^buf[i++])&0xFF]; - return C ^ -1; +function crc32_buf(B, seed) { + var C = seed ^ -1, L = B.length - 15, i = 0; + for(; i < L;) C = + Tf[B[i++] ^ (C & 255)] ^ + Te[B[i++] ^ ((C >> 8) & 255)] ^ + Td[B[i++] ^ ((C >> 16) & 255)] ^ + Tc[B[i++] ^ (C >>> 24)] ^ + Tb[B[i++]] ^ Ta[B[i++]] ^ T9[B[i++]] ^ T8[B[i++]] ^ + T7[B[i++]] ^ T6[B[i++]] ^ T5[B[i++]] ^ T4[B[i++]] ^ + T3[B[i++]] ^ T2[B[i++]] ^ T1[B[i++]] ^ T0[B[i++]]; + L += 15; + while(i < L) C = (C>>>8) ^ T0[(C^B[i++])&0xFF]; + return ~C; } function crc32_str(str, seed) { var C = seed ^ -1; - for(var i = 0, L=str.length, c, d; i < L;) { + for(var i = 0, L = str.length, c = 0, d = 0; i < L;) { c = str.charCodeAt(i++); if(c < 0x80) { - C = (C>>>8) ^ T[(C ^ c)&0xFF]; + C = (C>>>8) ^ T0[(C^c)&0xFF]; } else if(c < 0x800) { - C = (C>>>8) ^ T[(C ^ (192|((c>>6)&31)))&0xFF]; - C = (C>>>8) ^ T[(C ^ (128|(c&63)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (192|((c>>6)&31)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|(c&63)))&0xFF]; } else if(c >= 0xD800 && c < 0xE000) { c = (c&1023)+64; d = str.charCodeAt(i++)&1023; - C = (C>>>8) ^ T[(C ^ (240|((c>>8)&7)))&0xFF]; - C = (C>>>8) ^ T[(C ^ (128|((c>>2)&63)))&0xFF]; - C = (C>>>8) ^ T[(C ^ (128|((d>>6)&15)|((c&3)<<4)))&0xFF]; - C = (C>>>8) ^ T[(C ^ (128|(d&63)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (240|((c>>8)&7)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|((c>>2)&63)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|((d>>6)&15)|((c&3)<<4)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|(d&63)))&0xFF]; } else { - C = (C>>>8) ^ T[(C ^ (224|((c>>12)&15)))&0xFF]; - C = (C>>>8) ^ T[(C ^ (128|((c>>6)&63)))&0xFF]; - C = (C>>>8) ^ T[(C ^ (128|(c&63)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (224|((c>>12)&15)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|((c>>6)&63)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|(c&63)))&0xFF]; } } - return C ^ -1; + return ~C; } -CRC32.table = T; +CRC32.table = T0; // $FlowIgnore CRC32.bstr = crc32_bstr; // $FlowIgnore diff --git a/ctest/fixtures.js b/ctest/fixtures.js index 375d2b8..002840a 100644 --- a/ctest/fixtures.js +++ b/ctest/fixtures.js @@ -35,8 +35,8 @@ type _CB = {(data:Buffer):void;}; declare module 'concat-stream' {declare function exports(f:_CB):stream$Duplex;}; declare module 'exit-on-epipe' {}; -declare module 'crc-32' { declare var exports:CRC32Module; }; -declare module '../' { declare var exports:CRC32Module; }; +declare module 'crc-32' { declare module.exports:CRC32Module; }; +declare module '../' { declare module.exports:CRC32Module; }; declare module 'printj' { declare function sprintf(fmt:string, ...args:any):string; diff --git a/ctest/test.js b/ctest/test.js index 4b0f0a4..9f6b546 100644 --- a/ctest/test.js +++ b/ctest/test.js @@ -20,6 +20,14 @@ function msieversion() return parseInt (ua.substring (msie+5, ua.indexOf (".", msie ))); } +var Buffer_from = function(){}; + +if(typeof Buffer !== 'undefined') { + var nbfs = !Buffer.from; + if(!nbfs) try { Buffer.from("foo", "utf8"); } catch(e) { nbfs = true; } + Buffer_from = nbfs ? function(buf, enc) { return (enc) ? new Buffer(buf, enc) : new Buffer(buf); } : Buffer.from.bind(Buffer); +} + describe('crc32 table', function() { it('should match fixed table', function() { var overflow = 0; @@ -40,7 +48,7 @@ describe('crc32 bits', function() { it(msg, function() { if(i[2] === 1) assert.equal(X.bstr(i[0]), L); assert.equal(X.str(i[0]), i[1]|0); - if(typeof Buffer !== 'undefined') assert.equal(X.buf(new Buffer(i[0])), L); + if(typeof Buffer !== 'undefined') assert.equal(X.buf(Buffer_from(i[0])), L); var len = i[0].length, step = len < 20000 ? 1 : len < 50000 ? Math.ceil(len / 20000) : Math.ceil(len / 2000); for(var x = 0; x < len; x += step) { if(i[0].charCodeAt(x) >= 0xD800 && i[0].charCodeAt(x) < 0xE000) continue; @@ -51,7 +59,7 @@ describe('crc32 bits', function() { var strcrc = X.str(i[0].substr(x), X.str(i[0].substr(0, x))); assert.equal(strcrc, i[1]|0); if(typeof Buffer !== 'undefined') { - var buf = new Buffer(i[0]); + var buf = Buffer_from(i[0]); var bufcrc = X.buf(buf.slice(x), X.buf(buf.slice(0, x))); assert.equal(bufcrc, L); } @@ -74,9 +82,9 @@ if(typeof require !== 'undefined') describe("unicode", function() { var cc = corpus[ucidx], dd = X.str(c); assert.equal(dd, cc, ":" + ucidx + ":" + c + ":" + cc + ":" + dd); if(typeof Buffer !== 'undefined') { - var ee = X.buf(new Buffer(c, "utf8")); + var ee = X.buf(Buffer_from(c, "utf8")); assert.equal(ee, cc, ":" + ucidx + ":" + c + ":" + cc + ":" + ee); - var ff = X.bstr(String.fromCharCode.apply(null, new Buffer(c, "utf8"))); + var ff = X.bstr(String.fromCharCode.apply(null, Buffer_from(c, "utf8"))); assert.equal(ff, cc, ":" + ucidx + ":" + c + ":" + cc + ":" + ff); } }; diff --git a/package.json b/package.json index 80de338..b00267a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "crc-32", - "version": "1.2.0", + "version": "1.2.1", "author": "sheetjs", "description": "Pure-JS CRC-32", "keywords": [ "crc", "crc32", "checksum" ], @@ -35,7 +35,7 @@ "pattern": "crc32.js" } }, - "homepage": "http://sheetjs.com/opensource", + "homepage": "https://sheetjs.com/", "files": ["crc32.js", "crc32c.js", "bin/crc32.njs", "LICENSE", "README.md", "types/index.d.ts", "types/*.json"], "bugs": { "url": "https://github.com/SheetJS/js-crc32/issues" }, "license": "Apache-2.0", -- 2.34.1 From a1bcb01e8e77612d9dbbdd380eafa0363ee4144a Mon Sep 17 00:00:00 2001 From: Garrett Luu Date: Mon, 4 Apr 2022 14:53:03 -0700 Subject: [PATCH 07/11] crc32-cli --- packages/crc32-cli/bin/crc32.njs | 9 +++ packages/crc32-cli/index.js | 94 ++++++++++++++++++++++++++++++++ packages/crc32-cli/package.json | 16 ++++++ 3 files changed, 119 insertions(+) create mode 100755 packages/crc32-cli/bin/crc32.njs create mode 100644 packages/crc32-cli/index.js create mode 100644 packages/crc32-cli/package.json diff --git a/packages/crc32-cli/bin/crc32.njs b/packages/crc32-cli/bin/crc32.njs new file mode 100755 index 0000000..80c98b9 --- /dev/null +++ b/packages/crc32-cli/bin/crc32.njs @@ -0,0 +1,9 @@ +#!/usr/bin/env node +/* crc32.js (C) 2014-present SheetJS -- http://sheetjs.com */ +/* eslint-env node */ +/* vim: set ts=2 ft=javascript: */ +/*jshint node:true */ + +var cli = require('../'); + +cli(); diff --git a/packages/crc32-cli/index.js b/packages/crc32-cli/index.js new file mode 100644 index 0000000..949b36f --- /dev/null +++ b/packages/crc32-cli/index.js @@ -0,0 +1,94 @@ +/* index.js (C) 2020-present SheetJS -- http://sheetjs.com */ +/* eslint-env node */ +/* vim: set ts=2 ft=javascript: */ +/*jshint node:true */ + +/*:CRC32Module*/ +var X = require('crc-32'); + +function help()/*:number*/ { + [ + "usage: crc32 [options] [filename]", + "", + "Options:", + " -h, --help output usage information", + " -V, --version output the version number", + " -S, --seed= use integer seed as starting value (rolling CRC)", + " -H, --hex-seed= use hex seed as starting value (rolling CRC)", + " -d, --signed print result with format `%d` (default)", + " -u, --unsigned print result with format `%u`", + " -x, --hex print result with format `%0.8x`", + " -X, --HEX print result with format `%0.8X`", + " -c, --crc32c use CRC32C (Castagnoli)", + " -F, --format= use specified printf format", + "", + "Set filename = '-' or pipe data into crc32 to read from stdin", + "Default output mode is signed (-d)", + "" + ].forEach(function (l) { console.log(l); }); + return 0; +} + +function version()/*:number*/ { console.log(X.version); return 0; } + +var fs = require('fs'); +require('exit-on-epipe'); + +function die(msg/*:string*/, ec/*:?number*/)/*:void*/ { console.error(msg); process.exit(ec || 0); } + +function run() { + var args/*:Array*/ = process.argv.slice(2); + var filename/*:string*/ = ""; + var fmt/*:string*/ = ""; + var seed = 0, r = 10; + + for(var i = 0; i < args.length; ++i) { + var arg = args[i]; + if(arg.charCodeAt(0) != 45) { if(filename === "") filename = arg; continue; } + var m = arg.indexOf("=") == -1 ? arg : arg.substr(0, arg.indexOf("=")); + switch(m) { + case "-": filename = "-"; break; + + case "--help": case "-h": process.exit(help()); break; + case "--version": case "-V": process.exit(version()); break; + + case "--crc32c": case "-c": try { X = require('../crc32c'); } catch(e) { X = require('crc-32/crc32c'); } break; + + case "--signed": case "-d": fmt = "%d"; break; + case "--unsigned": case "-u": fmt = "%u"; break; + case "--hex": case "-x": fmt = "%0.8x"; break; + case "--HEX": case "-X": fmt = "%0.8X"; break; + case "--format": case "-F": + fmt = ((m!=arg) ? arg.substr(m.length+1) : args[++i])||""; break; + + case "--hex-seed": case "-H": r = 16; + /* falls through */ + case "--seed": case "-S": + seed=parseInt((m!=arg) ? arg.substr(m.length+1) : args[++i], r)||0; break; + + default: die("crc32: unrecognized option `" + arg + "'", 22); + } + } + + if(!process.stdin.isTTY) filename = filename || "-"; + if(filename.length===0) die("crc32: must specify a filename ('-' for stdin)",1); + + var crc32 = seed; + // $FlowIgnore -- Writable is callable but type sig disagrees + var writable = require('stream').Writable(); + writable._write = function(chunk, e, cb) { crc32 = X.buf(chunk, crc32); cb(); }; + writable._writev = function(chunks, cb) { + chunks.forEach(function(c) { crc32 = X.buf(c.chunk, crc32);}); + cb(); + }; + writable.on('finish', function() { + console.log(fmt === "" ? crc32 : require("printj").sprintf(fmt, crc32)); + }); + + if(filename === "-") process.stdin.pipe(writable); + else if(fs.existsSync(filename)) fs.createReadStream(filename).pipe(writable); + else die("crc32: " + filename + ": No such file or directory", 2); +} + +module.exports = run; + diff --git a/packages/crc32-cli/package.json b/packages/crc32-cli/package.json new file mode 100644 index 0000000..33161c4 --- /dev/null +++ b/packages/crc32-cli/package.json @@ -0,0 +1,16 @@ +{ + "name": "crc32-cli", + "version": "1.0.1", + "author": "sheetjs", + "description": "Command-line interface for crc32", + "bin": { + "crc32-cli": "bin/crc32.njs" + }, + "main": "index.js", + "dependencies": { + "crc-32": "^1.2.1", + "exit-on-epipe": "~1.0.1" + }, + "license": "Apache-2.0" +} + -- 2.34.1 From 6a752a8568e37e824e85da3abf45ff883ae2f651 Mon Sep 17 00:00:00 2001 From: SheetJS Date: Mon, 4 Apr 2022 18:53:34 -0400 Subject: [PATCH 08/11] version bump 1.2.2 --- .github/workflows/node-4+.yml | 92 ++++++++++++++++++++++++++++++ .github/workflows/node-iojs.yml | 45 +++++++++++++++ .github/workflows/node-pretest.yml | 32 +++++++++++ .github/workflows/node-zero.yml | 88 ++++++++++++++++++++++++++++ Makefile | 8 +-- bin/crc32.njs | 21 ++++++- bits/01_version.js | 2 +- crc32.flow.js | 2 +- crc32.js | 2 +- crc32c.flow.js | 2 +- crc32c.js | 2 +- ctest/crc32.js | 2 +- package.json | 6 +- packages/crc32-cli/.npmignore | 1 + 14 files changed, 289 insertions(+), 16 deletions(-) create mode 100644 .github/workflows/node-4+.yml create mode 100644 .github/workflows/node-iojs.yml create mode 100644 .github/workflows/node-pretest.yml create mode 100644 .github/workflows/node-zero.yml create mode 100644 packages/crc32-cli/.npmignore diff --git a/.github/workflows/node-4+.yml b/.github/workflows/node-4+.yml new file mode 100644 index 0000000..1accca6 --- /dev/null +++ b/.github/workflows/node-4+.yml @@ -0,0 +1,92 @@ +name: 'Tests: node.js' + +on: [pull_request, push] + +jobs: + matrix: + runs-on: ubuntu-latest + outputs: + latest: ${{ steps.set-matrix.outputs.requireds }} + steps: + - uses: ljharb/actions/node/matrix@main + id: set-matrix + with: + versionsAsRoot: true + type: 'majors' + preset: '>=4' + + latest: + needs: [matrix] + name: 'latest majors' + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + node-version: ${{ fromJson(needs.matrix.outputs.latest) }} + include: + - node-version: '14.' + env: + TZ: America/New_York + - node-version: '13.' + env: + TZ: Europe/London + - node-version: '12.' + env: + TZ: Asia/Seoul + - node-version: '11.' + env: + TZ: America/Los_Angeles + FMTS: misc + - node-version: '10.' + env: + TZ: Europe/Berlin + FMTS: misc + - node-version: '9.' + env: + TZ: Asia/Kolkata + FMTS: misc + - node-version: '8.' + env: + TZ: Asia/Shanghai + FMTS: misc + - node-version: '7.' + env: + TZ: America/Cancun + FMTS: misc + - node-version: '6.' + env: + TZ: Asia/Seoul + FMTS: misc + - node-version: '5.' + env: + TZ: America/Anchorage + FMTS: misc + - node-version: '4.' + env: + TZ: America/Barbados + FMTS: misc + - node-version: '4.4.7' # see GH issue #1150 + env: + TZ: Asia/Tokyo + FMTS: misc + + steps: + - uses: actions/checkout@v2 + - uses: ljharb/actions/node/install@main + name: 'nvm install ${{ matrix.node-version }} && npm install' + with: + node-version: ${{ matrix.node-version }} + - run: sudo curl -Lo /usr/bin/rooster https://github.com/SheetJS/rooster/releases/download/v0.2.0/rooster-v0.2.0-linux-amd64 + - run: sudo chmod a+x /usr/bin/rooster + #- run: make init + #- run: 'cd test_files; make all; cd -' + - run: npm run test + #- run: 'cd packages/ssf; npm install; npm run tests-only; cd -' + + node: + name: 'node 4+' + needs: [latest] + runs-on: ubuntu-latest + steps: + - run: 'echo tests completed' diff --git a/.github/workflows/node-iojs.yml b/.github/workflows/node-iojs.yml new file mode 100644 index 0000000..73b04cc --- /dev/null +++ b/.github/workflows/node-iojs.yml @@ -0,0 +1,45 @@ +name: 'Tests: node.js (io.js)' + +on: [pull_request, push] + +jobs: + matrix: + runs-on: ubuntu-latest + outputs: + latest: ${{ steps.set-matrix.outputs.requireds }} + steps: + - uses: ljharb/actions/node/matrix@main + id: set-matrix + with: + type: 'majors' + preset: 'iojs' + + latest: + needs: [matrix] + name: 'latest majors' + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: ${{ fromJson(needs.matrix.outputs.latest) }} + + steps: + - uses: actions/checkout@v2 + - uses: ljharb/actions/node/install@main + name: 'nvm install ${{ matrix.node-version }} && npm install' + with: + node-version: ${{ matrix.node-version }} + skip-ls-check: true + - run: sudo curl -Lo /usr/bin/rooster https://github.com/SheetJS/rooster/releases/download/v0.2.0/rooster-v0.2.0-linux-amd64 + - run: sudo chmod a+x /usr/bin/rooster + #- run: make init + #- run: 'cd test_files; make all; cd -' + - run: npm run test + #- run: 'cd packages/ssf; npm run tests-only; cd -' + + node: + name: 'io.js' + needs: [latest] + runs-on: ubuntu-latest + steps: + - run: 'echo tests completed' diff --git a/.github/workflows/node-pretest.yml b/.github/workflows/node-pretest.yml new file mode 100644 index 0000000..ccaff02 --- /dev/null +++ b/.github/workflows/node-pretest.yml @@ -0,0 +1,32 @@ +name: 'Tests: pretest/posttest' + +on: [pull_request, push] + +jobs: + pretest: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - uses: ljharb/actions/node/install@main + name: 'nvm install lts/* && npm install' + with: + node-version: 'lts/*' + - run: sudo curl -Lo /usr/bin/rooster https://github.com/SheetJS/rooster/releases/download/v0.2.0/rooster-v0.2.0-linux-amd64 + - run: sudo chmod a+x /usr/bin/rooster + #- run: make init + #- run: 'cd test_files; make all; cd -' + #- run: npm run pretest + + # posttest: + # runs-on: ubuntu-latest + + # steps: + # - uses: actions/checkout@v2 + # - uses: ljharb/actions/node/install@main + # name: 'nvm install lts/* && npm install' + # with: + # node-version: 'lts/*' + # - run: make init + # - run: 'cd test_files; make all; cd -' + # - run: npm run posttest diff --git a/.github/workflows/node-zero.yml b/.github/workflows/node-zero.yml new file mode 100644 index 0000000..5a95268 --- /dev/null +++ b/.github/workflows/node-zero.yml @@ -0,0 +1,88 @@ +name: 'Tests: node.js (0.x)' + +on: [pull_request, push] + +jobs: + matrix: + runs-on: ubuntu-latest + outputs: + stable: ${{ steps.set-matrix.outputs.requireds }} +# unstable: ${{ steps.set-matrix.outputs.optionals }} + steps: + - uses: ljharb/actions/node/matrix@main + id: set-matrix + with: + versionsAsRoot: true + preset: '0.x' + + stable: + needs: [matrix] + name: 'stable minors' + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + node-version: ${{ fromJson(needs.matrix.outputs.stable) }} + include: + - node-version: '0.12.' + env: + TZ: America/Cayman + FMTS: misc + - node-version: '0.10.' + env: + TZ: Pacific/Honolulu + FMTS: misc + #- node-version: '0.8.' + # env: + # TZ: America/Mexico_City + # FMTS: misc + + steps: + - uses: actions/checkout@v2 + - uses: ljharb/actions/node/install@main + name: 'nvm install ${{ matrix.node-version }} && npm install' + with: + node-version: ${{ matrix.node-version }} + cache-node-modules-key: node_modules-${{ github.workflow }}-${{ github.action }}-${{ github.run_id }} + skip-ls-check: true + - run: sudo curl -Lo /usr/bin/rooster https://github.com/SheetJS/rooster/releases/download/v0.2.0/rooster-v0.2.0-linux-amd64 + - run: sudo chmod a+x /usr/bin/rooster + #- run: make init + #- run: 'cd test_files; make all; cd -' + - run: npm run test + #- run: 'cd packages/ssf; npm run tests-only; cd -' + +# unstable: +# needs: [matrix, stable] +# name: 'unstable minors' +# continue-on-error: true +# if: ${{ !github.head_ref || !startsWith(github.head_ref, 'renovate') }} +# runs-on: ubuntu-latest + +# strategy: +# fail-fast: false +# matrix: +# node-version: ${{ fromJson(needs.matrix.outputs.unstable) }} +# +# steps: +# - uses: actions/checkout@v2 +# - uses: ljharb/actions/node/install@main +# name: 'nvm install ${{ matrix.node-version }} && npm install' +# with: +# node-version: ${{ matrix.node-version }} +# cache-node-modules-key: node_modules-${{ github.workflow }}-${{ github.action }}-${{ github.run_id }} +# skip-ls-check: true +# - run: sudo curl -Lo /usr/bin/rooster https://github.com/SheetJS/rooster/releases/download/v0.2.0/rooster-v0.2.0-linux-amd64 +# - run: sudo chmod a+x /usr/bin/rooster +# - run: make init +# - run: 'cd test_files; make all; cd -' +# - run: npm run tests-only + + node: + name: 'node 0.x' +# needs: [stable, unstable] + needs: [stable] + runs-on: ubuntu-latest + steps: + - run: 'echo tests completed' diff --git a/Makefile b/Makefile index 14d5128..47df70a 100644 --- a/Makefile +++ b/Makefile @@ -37,7 +37,7 @@ crc32c.flow.js: crc32.flow.js .PHONY: test mocha test mocha: test.js $(TARGET) baseline ## Run test suite - mocha -R spec -t 60000 + ./node_modules/.bin/mocha -R spec -t 60000 .PHONY: ctest ctest: ## Build browser test (into ctest/ subdirectory) @@ -65,7 +65,7 @@ fullint: lint old-lint tslint flow mdlint ## Run all checks .PHONY: lint lint: $(TARGET) $(AUXTARGETS) ## Run eslint checks - @eslint --ext .js,.njs,.json,.html,.htm $(TARGET) $(AUXTARGETS) $(CMDS) $(HTMLLINT) package.json bower.json + @eslint --ext .js,.njs,.json,.html,.htm $(TARGET) $(AUXTARGETS) $(CMDS) $(HTMLLINT) package.json if [ -e $(CLOSURE) ]; then java -jar $(CLOSURE) $(REQS) $(FLOWTARGET) --jscomp_warning=reportUnknownTypes >/dev/null; fi .PHONY: old-lint @@ -91,11 +91,11 @@ flow: lint ## Run flow checker cov: misc/coverage.html ## Run coverage test misc/coverage.html: $(TARGET) test.js - mocha --require blanket -R html-cov -t 60000 > $@ + ./node_modules/.bin/mocha --require blanket -R html-cov -t 60000 > $@ .PHONY: coveralls coveralls: ## Coverage Test + Send to coveralls.io - mocha --require blanket --reporter mocha-lcov-reporter -t 60000 | node ./node_modules/coveralls/bin/coveralls.js + ./node_modules/.bin/mocha --require blanket --reporter mocha-lcov-reporter -t 60000 | node ./node_modules/coveralls/bin/coveralls.js MDLINT=README.md .PHONY: mdlint diff --git a/bin/crc32.njs b/bin/crc32.njs index b5b02a1..334e7d2 100755 --- a/bin/crc32.njs +++ b/bin/crc32.njs @@ -33,7 +33,7 @@ function help()/*:number*/ { function version()/*:number*/ { console.log(X.version); return 0; } var fs = require('fs'); -require('exit-on-epipe'); +try { require('exit-on-epipe'); } catch(e) {} function die(msg/*:string*/, ec/*:?number*/)/*:void*/ { console.error(msg); process.exit(ec || 0); } @@ -59,7 +59,14 @@ for(var i = 0; i < args.length; ++i) { case "--hex": case "-x": fmt = "%0.8x"; break; case "--HEX": case "-X": fmt = "%0.8X"; break; case "--format": case "-F": - fmt = ((m!=arg) ? arg.substr(m.length+1) : args[++i])||""; break; + try { + require("printj"); + fmt = ((m!=arg) ? arg.substr(m.length+1) : args[++i])||""; + } catch(e) { + console.error("The `crc-32` module removed the `printj` dependency for formatting"); + console.error("Use the `crc32-cli` module instead:"); + console.error(" $ npx crc32-cli [options] [filename]"); + } break; case "--hex-seed": case "-H": r = 16; /* falls through */ @@ -82,7 +89,15 @@ writable._writev = function(chunks, cb) { cb(); }; writable.on('finish', function() { - console.log(fmt === "" ? crc32 : require("printj").sprintf(fmt, crc32)); + if(fmt === "") console.log(crc32); + else try { console.log(require("printj").sprintf(fmt, crc32)); } catch(e) { + switch(fmt) { + case "%d": console.log(crc32); break; + case "%u": console.log(crc32 >>> 0); break; + case "%0.8x": console.log((crc32 >>> 0).toString(16).padStart(8, "0").toLowerCase()); break; + case "%0.8X": console.log((crc32 >>> 0).toString(16).padStart(8, "0").toUpperCase()); break; + } + } }); if(filename === "-") process.stdin.pipe(writable); diff --git a/bits/01_version.js b/bits/01_version.js index 45bc6f8..d71eb22 100644 --- a/bits/01_version.js +++ b/bits/01_version.js @@ -1 +1 @@ -CRC32.version = '1.2.1'; +CRC32.version = '1.2.2'; diff --git a/crc32.flow.js b/crc32.flow.js index 3a80772..a1f890e 100644 --- a/crc32.flow.js +++ b/crc32.flow.js @@ -25,7 +25,7 @@ var CRC32/*:CRC32Module*/; /*eslint-enable */ /*jshint ignore:end */ }(function(CRC32/*:CRC32Module*/) { -CRC32.version = '1.2.1'; +CRC32.version = '1.2.2'; /*:: type CRC32Type = number; type ABuf = Array | Buffer | Uint8Array; diff --git a/crc32.js b/crc32.js index af85913..c92664a 100644 --- a/crc32.js +++ b/crc32.js @@ -23,7 +23,7 @@ var CRC32; /*eslint-enable */ /*jshint ignore:end */ }(function(CRC32) { -CRC32.version = '1.2.1'; +CRC32.version = '1.2.2'; /*global Int32Array */ function signed_crc_table() { var c = 0, table = new Array(256); diff --git a/crc32c.flow.js b/crc32c.flow.js index ea7872c..5e97c4a 100644 --- a/crc32c.flow.js +++ b/crc32c.flow.js @@ -25,7 +25,7 @@ var CRC32C/*:CRC32Module*/; /*eslint-enable */ /*jshint ignore:end */ }(function(CRC32C/*:CRC32Module*/) { -CRC32C.version = '1.2.1'; +CRC32C.version = '1.2.2'; /*:: type CRC32Type = number; type ABuf = Array | Buffer | Uint8Array; diff --git a/crc32c.js b/crc32c.js index 6247199..447fc8f 100644 --- a/crc32c.js +++ b/crc32c.js @@ -23,7 +23,7 @@ var CRC32C; /*eslint-enable */ /*jshint ignore:end */ }(function(CRC32C) { -CRC32C.version = '1.2.1'; +CRC32C.version = '1.2.2'; /*global Int32Array */ function signed_crc_table() { var c = 0, table = new Array(256); diff --git a/ctest/crc32.js b/ctest/crc32.js index af85913..c92664a 100644 --- a/ctest/crc32.js +++ b/ctest/crc32.js @@ -23,7 +23,7 @@ var CRC32; /*eslint-enable */ /*jshint ignore:end */ }(function(CRC32) { -CRC32.version = '1.2.1'; +CRC32.version = '1.2.2'; /*global Int32Array */ function signed_crc_table() { var c = 0, table = new Array(256); diff --git a/package.json b/package.json index b00267a..a523291 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "crc-32", - "version": "1.2.1", + "version": "1.2.2", "author": "sheetjs", "description": "Pure-JS CRC-32", "keywords": [ "crc", "crc32", "checksum" ], @@ -11,10 +11,10 @@ "types": "types/index.d.ts", "typesVersions": { "*": { "*": ["types/index.d.ts" ] } }, "dependencies": { - "printj": "~1.3.1", - "exit-on-epipe": "~1.0.1" }, "devDependencies": { + "printj": "~1.3.1", + "exit-on-epipe": "~1.0.1", "mocha": "~2.5.3", "blanket": "~1.2.3", "codepage": "~1.10.0", diff --git a/packages/crc32-cli/.npmignore b/packages/crc32-cli/.npmignore new file mode 100644 index 0000000..aa1ec1e --- /dev/null +++ b/packages/crc32-cli/.npmignore @@ -0,0 +1 @@ +*.tgz -- 2.34.1 From 02389a3823bcac7f4e79323b038567f512623efe Mon Sep 17 00:00:00 2001 From: SheetJS Date: Tue, 26 Apr 2022 18:35:26 -0400 Subject: [PATCH 09/11] replace git.io links --- README.md | 2 +- index.html | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 082127a..43ecf2f 100644 --- a/README.md +++ b/README.md @@ -181,7 +181,7 @@ $ crc32 --unsigned ~/Downloads/IE8.Win7.For.Windows.VMware.zip `make perf` will run algorithmic performance tests (which should justify certain decisions in the code). -The [`adler-32` project](http://git.io/adler32) has more performance notes +The [`adler-32` project](https://github.com/SheetJS/js-adler32) has more performance notes ## License diff --git a/index.html b/index.html index bd472b0..d9088cf 100644 --- a/index.html +++ b/index.html @@ -27,8 +27,8 @@ a { text-decoration: none } (text works back to IE6; drag and drop works back to IE10) (This demo loads the entire file at once! For newer browsers, try the large file demo) -Source Code Repo -Issues? Something look weird? Click here and report an issue +Source Code Repo +Issues? Something look weird? Click here and report an issue
Drop a text file to compute the CRC-32 checksum
... or click here to select a file -- 2.34.1 From 3bd21324dbbd9f286aedf77f1eeb161823963c54 Mon Sep 17 00:00:00 2001 From: SheetJS Date: Sat, 13 Aug 2022 00:29:46 -0400 Subject: [PATCH 10/11] ESM build --- Makefile | 11 +++++- README.md | 35 ++++++++++++++++- crc32.mjs | 95 +++++++++++++++++++++++++++++++++++++++++++++++ crc32c.mjs | 95 +++++++++++++++++++++++++++++++++++++++++++++++ misc/00_header.js | 3 ++ misc/99_footer.js | 5 +++ misc/mjs.lst | 6 +++ package.json | 19 +++++++++- 8 files changed, 265 insertions(+), 4 deletions(-) create mode 100644 crc32.mjs create mode 100644 crc32c.mjs create mode 100644 misc/00_header.js create mode 100644 misc/99_footer.js create mode 100644 misc/mjs.lst diff --git a/Makefile b/Makefile index 47df70a..f3d8918 100644 --- a/Makefile +++ b/Makefile @@ -12,10 +12,13 @@ FLOWTARGET=$(LIB).flow.js FLOWTGTS=$(TARGET) $(AUXTARGETS) CLOSURE=/usr/local/lib/node_modules/google-closure-compiler/compiler.jar +ESMJSTGT=crc32.mjs +ESMJSDEPS=$(shell cat misc/mjs.lst) + ## Main Targets .PHONY: all -all: $(TARGET) $(AUXTARGETS) ## Build library and auxiliary scripts +all: $(TARGET) $(AUXTARGETS) $(ESMJSTGT) crc32c.mjs ## Build library and auxiliary scripts $(FLOWTGTS): %.js : %.flow.js node -e 'process.stdout.write(require("fs").readFileSync("$<","utf8").replace(/^[ \t]*\/\*[:#][^*]*\*\/\s*(\n)?/gm,"").replace(/\/\*[:#][^*]*\*\//gm,""))' > $@ @@ -23,6 +26,9 @@ $(FLOWTGTS): %.js : %.flow.js $(FLOWTARGET): $(DEPS) cat $^ | tr -d '\15\32' > $@ +$(ESMJSTGT): $(ESMJSDEPS) + cat $^ | tr -d '\15\32' > $@ + bits/01_version.js: package.json echo "$(ULIB).version = '"`grep version package.json | awk '{gsub(/[^0-9a-z\.-]/,"",$$2); print $$2}'`"';" > $@ @@ -33,6 +39,9 @@ clean: clean-baseline ## Remove targets and build artifacts crc32c.flow.js: crc32.flow.js cat $^ | sed 's/-306674912/-2097792136/g; s/CRC32\([ \/\.]\)/CRC32C\1/g' > $@ +crc32c.mjs: crc32.mjs + cat $^ | sed 's/-306674912/-2097792136/g; s/CRC32\([ \/\.]\)/CRC32C\1/g' > $@ + ## Testing .PHONY: test mocha diff --git a/README.md b/README.md index 43ecf2f..bbff3d9 100644 --- a/README.md +++ b/README.md @@ -28,12 +28,18 @@ checksum for a specified file or standard input. ## Integration -Using NodeJS or a bundler: +Using NodeJS or a bundler with `require`: ```js var CRC32 = require("crc-32"); ``` +Using NodeJS or a bundler with `import`: + +```js +import { bstr, buf, str } from "crc-32"; +``` + In the browser, the `crc32.js` script can be loaded directly: ```html @@ -55,6 +61,12 @@ Using NodeJS or a bundler: var CRC32C = require("crc-32/crc32c"); ``` +Using NodeJS or a bundler with `import`: + +```js +import { bstr, buf, str } from "crc-32/crc32c"; +``` + In the browser, the `crc32c.js` script can be loaded directly: ```html @@ -71,7 +83,7 @@ desirable. To prevent the behavior, define `DO_NOT_EXPORT_CRC`. In all cases, the relevant function takes an argument representing data and an optional second argument representing the starting "seed" (for rolling CRC). -The return value is a signed 32-bit integer. +**The return value is a signed 32-bit integer!** - `CRC32.buf(byte array or buffer[, seed])` assumes the argument is a sequence of 8-bit unsigned integers (nodejs `Buffer`, `Uint8Array` or array of bytes). @@ -130,6 +142,25 @@ crc32 = CRC32.buf(Buffer.from(bstr, "binary"), 0); This does not apply to browser `Buffer` shims, and thus is not implemented in the library directly. +### Signed Integers + +Unconventional for a CRC32 checksum, this library uses signed 32-bit integers. +This is for performance reasons. Standard JS operators can convert between +signed and unsigned 32-bit integers: + +```js +CRC32.str("SheetJS") // -1647298270 (signed) +CRC32.str("SheetJS") >>> 0 // 2647669026 (unsigned) +(CRC32.str("SheetJS")>>>0).toString(16) // "9dd03922" (hex) + +(2647669026 | 0) // -1647298270 +``` + +- `x >>> 0` converts a number value to unsigned 32-bit integer. + +- `x | 0` converts a number value to signed 32-bit integer. + + ## Testing `make test` will run the nodejs-based test. diff --git a/crc32.mjs b/crc32.mjs new file mode 100644 index 0000000..a10f230 --- /dev/null +++ b/crc32.mjs @@ -0,0 +1,95 @@ +/*! crc32.js (C) 2014-present SheetJS -- http://sheetjs.com */ +/* vim: set ts=2: */ +var CRC32 = {}; +CRC32.version = '1.2.2'; +/*:: +type CRC32Type = number; +type ABuf = Array | Buffer | Uint8Array; +type CRC32TableType = Array | Int32Array; +*/ +/*global Int32Array */ +function signed_crc_table()/*:CRC32TableType*/ { + var c = 0, table/*:Array*/ = new Array(256); + + for(var n =0; n != 256; ++n){ + c = n; + c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); + c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); + c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); + c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); + c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); + c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); + c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); + c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1)); + table[n] = c; + } + + return typeof Int32Array !== 'undefined' ? new Int32Array(table) : table; +} + +var T0 = signed_crc_table(); +function slice_by_16_tables(T) { + var c = 0, v = 0, n = 0, table/*:Array*/ = typeof Int32Array !== 'undefined' ? new Int32Array(4096) : new Array(4096) ; + + for(n = 0; n != 256; ++n) table[n] = T[n]; + for(n = 0; n != 256; ++n) { + v = T[n]; + for(c = 256 + n; c < 4096; c += 256) v = table[c] = (v >>> 8) ^ T[v & 0xFF]; + } + var out = []; + for(n = 1; n != 16; ++n) out[n - 1] = typeof Int32Array !== 'undefined' ? table.subarray(n * 256, n * 256 + 256) : table.slice(n * 256, n * 256 + 256); + return out; +} +var TT = slice_by_16_tables(T0); +var T1 = TT[0], T2 = TT[1], T3 = TT[2], T4 = TT[3], T5 = TT[4]; +var T6 = TT[5], T7 = TT[6], T8 = TT[7], T9 = TT[8], Ta = TT[9]; +var Tb = TT[10], Tc = TT[11], Td = TT[12], Te = TT[13], Tf = TT[14]; +function crc32_bstr(bstr/*:string*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { + var C = seed/*:: ? 0 : 0 */ ^ -1; + for(var i = 0, L = bstr.length; i < L;) C = (C>>>8) ^ T0[(C^bstr.charCodeAt(i++))&0xFF]; + return ~C; +} + +function crc32_buf(B/*:ABuf*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { + var C = seed/*:: ? 0 : 0 */ ^ -1, L = B.length - 15, i = 0; + for(; i < L;) C = + Tf[B[i++] ^ (C & 255)] ^ + Te[B[i++] ^ ((C >> 8) & 255)] ^ + Td[B[i++] ^ ((C >> 16) & 255)] ^ + Tc[B[i++] ^ (C >>> 24)] ^ + Tb[B[i++]] ^ Ta[B[i++]] ^ T9[B[i++]] ^ T8[B[i++]] ^ + T7[B[i++]] ^ T6[B[i++]] ^ T5[B[i++]] ^ T4[B[i++]] ^ + T3[B[i++]] ^ T2[B[i++]] ^ T1[B[i++]] ^ T0[B[i++]]; + L += 15; + while(i < L) C = (C>>>8) ^ T0[(C^B[i++])&0xFF]; + return ~C; +} + +function crc32_str(str/*:string*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { + var C = seed/*:: ? 0 : 0 */ ^ -1; + for(var i = 0, L = str.length, c = 0, d = 0; i < L;) { + c = str.charCodeAt(i++); + if(c < 0x80) { + C = (C>>>8) ^ T0[(C^c)&0xFF]; + } else if(c < 0x800) { + C = (C>>>8) ^ T0[(C ^ (192|((c>>6)&31)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|(c&63)))&0xFF]; + } else if(c >= 0xD800 && c < 0xE000) { + c = (c&1023)+64; d = str.charCodeAt(i++)&1023; + C = (C>>>8) ^ T0[(C ^ (240|((c>>8)&7)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|((c>>2)&63)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|((d>>6)&15)|((c&3)<<4)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|(d&63)))&0xFF]; + } else { + C = (C>>>8) ^ T0[(C ^ (224|((c>>12)&15)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|((c>>6)&63)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|(c&63)))&0xFF]; + } + } + return ~C; +} +export const version = CRC32.version; +export const table = T0; +export const bstr = crc32_bstr; +export const buf = crc32_buf; +export const str = crc32_str; diff --git a/crc32c.mjs b/crc32c.mjs new file mode 100644 index 0000000..8316f62 --- /dev/null +++ b/crc32c.mjs @@ -0,0 +1,95 @@ +/*! crc32.js (C) 2014-present SheetJS -- http://sheetjs.com */ +/* vim: set ts=2: */ +var CRC32C = {}; +CRC32C.version = '1.2.2'; +/*:: +type CRC32Type = number; +type ABuf = Array | Buffer | Uint8Array; +type CRC32TableType = Array | Int32Array; +*/ +/*global Int32Array */ +function signed_crc_table()/*:CRC32TableType*/ { + var c = 0, table/*:Array*/ = new Array(256); + + for(var n =0; n != 256; ++n){ + c = n; + c = ((c&1) ? (-2097792136 ^ (c >>> 1)) : (c >>> 1)); + c = ((c&1) ? (-2097792136 ^ (c >>> 1)) : (c >>> 1)); + c = ((c&1) ? (-2097792136 ^ (c >>> 1)) : (c >>> 1)); + c = ((c&1) ? (-2097792136 ^ (c >>> 1)) : (c >>> 1)); + c = ((c&1) ? (-2097792136 ^ (c >>> 1)) : (c >>> 1)); + c = ((c&1) ? (-2097792136 ^ (c >>> 1)) : (c >>> 1)); + c = ((c&1) ? (-2097792136 ^ (c >>> 1)) : (c >>> 1)); + c = ((c&1) ? (-2097792136 ^ (c >>> 1)) : (c >>> 1)); + table[n] = c; + } + + return typeof Int32Array !== 'undefined' ? new Int32Array(table) : table; +} + +var T0 = signed_crc_table(); +function slice_by_16_tables(T) { + var c = 0, v = 0, n = 0, table/*:Array*/ = typeof Int32Array !== 'undefined' ? new Int32Array(4096) : new Array(4096) ; + + for(n = 0; n != 256; ++n) table[n] = T[n]; + for(n = 0; n != 256; ++n) { + v = T[n]; + for(c = 256 + n; c < 4096; c += 256) v = table[c] = (v >>> 8) ^ T[v & 0xFF]; + } + var out = []; + for(n = 1; n != 16; ++n) out[n - 1] = typeof Int32Array !== 'undefined' ? table.subarray(n * 256, n * 256 + 256) : table.slice(n * 256, n * 256 + 256); + return out; +} +var TT = slice_by_16_tables(T0); +var T1 = TT[0], T2 = TT[1], T3 = TT[2], T4 = TT[3], T5 = TT[4]; +var T6 = TT[5], T7 = TT[6], T8 = TT[7], T9 = TT[8], Ta = TT[9]; +var Tb = TT[10], Tc = TT[11], Td = TT[12], Te = TT[13], Tf = TT[14]; +function crc32_bstr(bstr/*:string*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { + var C = seed/*:: ? 0 : 0 */ ^ -1; + for(var i = 0, L = bstr.length; i < L;) C = (C>>>8) ^ T0[(C^bstr.charCodeAt(i++))&0xFF]; + return ~C; +} + +function crc32_buf(B/*:ABuf*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { + var C = seed/*:: ? 0 : 0 */ ^ -1, L = B.length - 15, i = 0; + for(; i < L;) C = + Tf[B[i++] ^ (C & 255)] ^ + Te[B[i++] ^ ((C >> 8) & 255)] ^ + Td[B[i++] ^ ((C >> 16) & 255)] ^ + Tc[B[i++] ^ (C >>> 24)] ^ + Tb[B[i++]] ^ Ta[B[i++]] ^ T9[B[i++]] ^ T8[B[i++]] ^ + T7[B[i++]] ^ T6[B[i++]] ^ T5[B[i++]] ^ T4[B[i++]] ^ + T3[B[i++]] ^ T2[B[i++]] ^ T1[B[i++]] ^ T0[B[i++]]; + L += 15; + while(i < L) C = (C>>>8) ^ T0[(C^B[i++])&0xFF]; + return ~C; +} + +function crc32_str(str/*:string*/, seed/*:?CRC32Type*/)/*:CRC32Type*/ { + var C = seed/*:: ? 0 : 0 */ ^ -1; + for(var i = 0, L = str.length, c = 0, d = 0; i < L;) { + c = str.charCodeAt(i++); + if(c < 0x80) { + C = (C>>>8) ^ T0[(C^c)&0xFF]; + } else if(c < 0x800) { + C = (C>>>8) ^ T0[(C ^ (192|((c>>6)&31)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|(c&63)))&0xFF]; + } else if(c >= 0xD800 && c < 0xE000) { + c = (c&1023)+64; d = str.charCodeAt(i++)&1023; + C = (C>>>8) ^ T0[(C ^ (240|((c>>8)&7)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|((c>>2)&63)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|((d>>6)&15)|((c&3)<<4)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|(d&63)))&0xFF]; + } else { + C = (C>>>8) ^ T0[(C ^ (224|((c>>12)&15)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|((c>>6)&63)))&0xFF]; + C = (C>>>8) ^ T0[(C ^ (128|(c&63)))&0xFF]; + } + } + return ~C; +} +export const version = CRC32C.version; +export const table = T0; +export const bstr = crc32_bstr; +export const buf = crc32_buf; +export const str = crc32_str; diff --git a/misc/00_header.js b/misc/00_header.js new file mode 100644 index 0000000..a172cbd --- /dev/null +++ b/misc/00_header.js @@ -0,0 +1,3 @@ +/*! crc32.js (C) 2014-present SheetJS -- http://sheetjs.com */ +/* vim: set ts=2: */ +var CRC32 = {}; diff --git a/misc/99_footer.js b/misc/99_footer.js new file mode 100644 index 0000000..0f3318d --- /dev/null +++ b/misc/99_footer.js @@ -0,0 +1,5 @@ +export const version = CRC32.version; +export const table = T0; +export const bstr = crc32_bstr; +export const buf = crc32_buf; +export const str = crc32_str; diff --git a/misc/mjs.lst b/misc/mjs.lst new file mode 100644 index 0000000..697323e --- /dev/null +++ b/misc/mjs.lst @@ -0,0 +1,6 @@ +misc/00_header.js +bits/01_version.js +bits/10_types.js +bits/20_crctable.js +bits/40_crc.js +misc/99_footer.js diff --git a/package.json b/package.json index a523291..14bdd82 100644 --- a/package.json +++ b/package.json @@ -8,8 +8,25 @@ "crc32": "bin/crc32.njs" }, "main": "crc32.js", + "module": "crc32.mjs", "types": "types/index.d.ts", "typesVersions": { "*": { "*": ["types/index.d.ts" ] } }, + "exports": { + ".": { + "import": "./crc32.mjs", + "require": "./crc32.js" + }, + "./crc32c": { + "import": "./crc32c.mjs", + "require": "./crc32c.js" + }, + "./crc32.mjs": { + "import": "./crc32.mjs" + }, + "./crc32c.mjs": { + "import": "./crc32c.mjs" + } + }, "dependencies": { }, "devDependencies": { @@ -36,7 +53,7 @@ } }, "homepage": "https://sheetjs.com/", - "files": ["crc32.js", "crc32c.js", "bin/crc32.njs", "LICENSE", "README.md", "types/index.d.ts", "types/*.json"], + "files": ["crc32.js", "crc32c.js", "crc32.mjs", "crc32c.mjs", "bin/crc32.njs", "LICENSE", "README.md", "types/index.d.ts", "types/*.json"], "bugs": { "url": "https://github.com/SheetJS/js-crc32/issues" }, "license": "Apache-2.0", "engines": { "node": ">=0.8" } -- 2.34.1 From 01cafc98c3785ac15fd36c731e35b660add07898 Mon Sep 17 00:00:00 2001 From: SheetJS Date: Sat, 20 Aug 2022 17:30:07 -0400 Subject: [PATCH 11/11] version bump 1.2.3 --- README.md | 19 +++++++------------ bits/01_version.js | 2 +- crc32.flow.js | 2 +- crc32.js | 2 +- crc32.mjs | 2 +- crc32c.flow.js | 2 +- crc32c.js | 2 +- crc32c.mjs | 2 +- package.json | 2 +- 9 files changed, 15 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index bbff3d9..3a29d07 100644 --- a/README.md +++ b/README.md @@ -5,26 +5,21 @@ Emphasis on correctness, performance, and IE6+ support. ## Installation -With [npm](https://www.npmjs.org/package/crc-32): +With a node package manager like `npm`: ```bash -$ npm install crc-32 +$ npm i --save https://cdn.sheetjs.com/crc-32-latest/crc-32-latest.tgz ``` When installed globally, npm installs a script `crc32` that computes the checksum for a specified file or standard input. -
- CDN Availability (click to show) - -| CDN | URL | -|-----------:|:-------------------------------------------| -| `unpkg` | | -| `jsDelivr` | | -| `CDNjs` | | - -
+Hosted versions are available at : +- `crc32.js` (CommonJS): +- `crc32.mjs` (ESM): +- `crc32c.js` (CommonJS): +- `crc32c.mjs` (ESM): ## Integration diff --git a/bits/01_version.js b/bits/01_version.js index d71eb22..d5259a8 100644 --- a/bits/01_version.js +++ b/bits/01_version.js @@ -1 +1 @@ -CRC32.version = '1.2.2'; +CRC32.version = '1.2.3'; diff --git a/crc32.flow.js b/crc32.flow.js index a1f890e..84c127b 100644 --- a/crc32.flow.js +++ b/crc32.flow.js @@ -25,7 +25,7 @@ var CRC32/*:CRC32Module*/; /*eslint-enable */ /*jshint ignore:end */ }(function(CRC32/*:CRC32Module*/) { -CRC32.version = '1.2.2'; +CRC32.version = '1.2.3'; /*:: type CRC32Type = number; type ABuf = Array | Buffer | Uint8Array; diff --git a/crc32.js b/crc32.js index c92664a..8db6285 100644 --- a/crc32.js +++ b/crc32.js @@ -23,7 +23,7 @@ var CRC32; /*eslint-enable */ /*jshint ignore:end */ }(function(CRC32) { -CRC32.version = '1.2.2'; +CRC32.version = '1.2.3'; /*global Int32Array */ function signed_crc_table() { var c = 0, table = new Array(256); diff --git a/crc32.mjs b/crc32.mjs index a10f230..f06d82d 100644 --- a/crc32.mjs +++ b/crc32.mjs @@ -1,7 +1,7 @@ /*! crc32.js (C) 2014-present SheetJS -- http://sheetjs.com */ /* vim: set ts=2: */ var CRC32 = {}; -CRC32.version = '1.2.2'; +CRC32.version = '1.2.3'; /*:: type CRC32Type = number; type ABuf = Array | Buffer | Uint8Array; diff --git a/crc32c.flow.js b/crc32c.flow.js index 5e97c4a..c4712ca 100644 --- a/crc32c.flow.js +++ b/crc32c.flow.js @@ -25,7 +25,7 @@ var CRC32C/*:CRC32Module*/; /*eslint-enable */ /*jshint ignore:end */ }(function(CRC32C/*:CRC32Module*/) { -CRC32C.version = '1.2.2'; +CRC32C.version = '1.2.3'; /*:: type CRC32Type = number; type ABuf = Array | Buffer | Uint8Array; diff --git a/crc32c.js b/crc32c.js index 447fc8f..e39f329 100644 --- a/crc32c.js +++ b/crc32c.js @@ -23,7 +23,7 @@ var CRC32C; /*eslint-enable */ /*jshint ignore:end */ }(function(CRC32C) { -CRC32C.version = '1.2.2'; +CRC32C.version = '1.2.3'; /*global Int32Array */ function signed_crc_table() { var c = 0, table = new Array(256); diff --git a/crc32c.mjs b/crc32c.mjs index 8316f62..7ad6d3c 100644 --- a/crc32c.mjs +++ b/crc32c.mjs @@ -1,7 +1,7 @@ /*! crc32.js (C) 2014-present SheetJS -- http://sheetjs.com */ /* vim: set ts=2: */ var CRC32C = {}; -CRC32C.version = '1.2.2'; +CRC32C.version = '1.2.3'; /*:: type CRC32Type = number; type ABuf = Array | Buffer | Uint8Array; diff --git a/package.json b/package.json index 14bdd82..20acf58 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "crc-32", - "version": "1.2.2", + "version": "1.2.3", "author": "sheetjs", "description": "Pure-JS CRC-32", "keywords": [ "crc", "crc32", "checksum" ], -- 2.34.1