version bump 0.3.0: cleanup and flow
This commit is contained in:
parent
5cc2f712b1
commit
6cdecfeb22
17
.flowconfig
Normal file
17
.flowconfig
Normal file
@ -0,0 +1,17 @@
|
||||
[ignore]
|
||||
.*/node_modules/.*
|
||||
.*/dist/.*
|
||||
.*/test.js
|
||||
.*/crc32.js
|
||||
|
||||
.*/bits/.*
|
||||
.*/ctest/.*
|
||||
.*/misc/.*
|
||||
.*/perf/.*
|
||||
|
||||
[include]
|
||||
crc32.flow.js
|
||||
|
||||
[libs]
|
||||
|
||||
[options]
|
4
.jshintrc
Normal file
4
.jshintrc
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"bitwise": false,
|
||||
"curly": false
|
||||
}
|
33
Makefile
33
Makefile
@ -1,10 +1,20 @@
|
||||
LIB=crc32
|
||||
REQS=
|
||||
ADDONS=
|
||||
AUXTARGETS=
|
||||
|
||||
ULIB=$(shell echo $(LIB) | tr a-z A-Z)
|
||||
DEPS=$(sort $(wildcard bits/*.js))
|
||||
TARGET=$(LIB).js
|
||||
|
||||
$(TARGET): $(DEPS)
|
||||
.PHONY: all
|
||||
all: $(TARGET) $(AUXTARGETS)
|
||||
|
||||
$(TARGET) $(AUXTARGETS): %.js : %.flow.js
|
||||
node -e 'process.stdout.write(require("fs").readFileSync("$<","utf8").replace(/^\s*\/\*:[^*]*\*\/\s*(\n)?/gm,"").replace(/\/\*:[^*]*\*\//gm,""))' > $@
|
||||
|
||||
$(LIB).flow.js: $(DEPS)
|
||||
cat $^ | tr -d '\15\32' > $@
|
||||
cp -f $@ ctest/
|
||||
|
||||
bits/01_version.js: package.json
|
||||
echo "CRC32.version = '"`grep version package.json | awk '{gsub(/[^0-9a-z\.-]/,"",$$2); print $$2}'`"';" > $@
|
||||
@ -15,18 +25,23 @@ clean:
|
||||
|
||||
.PHONY: test mocha
|
||||
test mocha: test.js
|
||||
mocha -R spec
|
||||
mocha -R spec -t 20000
|
||||
|
||||
.PHONY: ctest
|
||||
ctest:
|
||||
cat misc/*.js > ctest/fixtures.js
|
||||
cp -f test.js ctest/test.js
|
||||
cp -f $(TARGET) ctest/
|
||||
cp -f $(TARGET) ctest/
|
||||
|
||||
.PHONY: lint
|
||||
lint: $(TARGET)
|
||||
jshint --show-non-errors $(TARGET)
|
||||
jscs $(TARGET)
|
||||
lint: $(TARGET) $(AUXTARGETS)
|
||||
jshint --show-non-errors $(TARGET) $(AUXTARGETS)
|
||||
jshint --show-non-errors package.json
|
||||
jscs $(TARGET) $(AUXTARGETS)
|
||||
|
||||
.PHONY: flow
|
||||
flow: lint
|
||||
flow check --all --show-all-errors
|
||||
|
||||
.PHONY: cov cov-spin
|
||||
cov: misc/coverage.html
|
||||
@ -39,11 +54,11 @@ $(COVFMT): cov_%:
|
||||
FMTS=$* make cov
|
||||
|
||||
misc/coverage.html: $(TARGET) test.js
|
||||
mocha --require blanket -R html-cov > $@
|
||||
mocha --require blanket -R html-cov -t 20000 > $@
|
||||
|
||||
.PHONY: coveralls coveralls-spin
|
||||
coveralls:
|
||||
mocha --require blanket --reporter mocha-lcov-reporter | ./node_modules/coveralls/bin/coveralls.js
|
||||
mocha --require blanket --reporter mocha-lcov-reporter -t 20000 | ./node_modules/coveralls/bin/coveralls.js
|
||||
|
||||
coveralls-spin:
|
||||
make coveralls & bash misc/spin.sh $$!
|
||||
|
64
README.md
64
README.md
@ -5,59 +5,61 @@ Emphasis on correctness and performance.
|
||||
|
||||
## Installation
|
||||
|
||||
In [nodejs](https://www.npmjs.org/package/crc-32):
|
||||
With [npm](https://www.npmjs.org/package/crc-32):
|
||||
|
||||
npm install crc-32
|
||||
$ npm install crc-32
|
||||
|
||||
In the browser:
|
||||
|
||||
<script lang="javascript" src="crc32.js"></script>
|
||||
<script src="crc32.js"></script>
|
||||
|
||||
The browser exposes a variable CRC32
|
||||
The script will manipulate `module.exports` if available (e.g. in a CommonJS
|
||||
`require` context). This is not always desirable. To prevent the behavior,
|
||||
define `DO_NOT_EXPORT_CRC`
|
||||
|
||||
## Usage
|
||||
|
||||
- `CRC32.buf(byte array or buffer)` assumes the argument is a set of 8 bit
|
||||
unsigned integers (e.g. nodejs `Buffer` or simple array of ints)
|
||||
In all cases, the relevant function takes a single argument representing data.
|
||||
|
||||
The return value is a signed 32-bit integer.
|
||||
|
||||
- `CRC32.buf(byte array or buffer)` assumes the argument is a set of 8-bit
|
||||
unsigned integers (e.g. nodejs `Buffer` or simple array of ints).
|
||||
|
||||
- `CRC32.bstr(binary string)` interprets the argument as a binary string where
|
||||
the `i`-th byte is `str.charCodeAt(i)`
|
||||
the `i`-th byte is the low byte of the UCS-2 char: `str.charCodeAt(i) & 0xFF`
|
||||
|
||||
- `CRC32.str(string)` interprets the argument as a standard JS string
|
||||
|
||||
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
|
||||
|
||||
> [CRC32.str("\u2603"), CRC32.str("\u0003")] // [ -1743909036, 1259060791 ]
|
||||
> [CRC32.bstr("\u2603"), CRC32.bstr("\u0003")] // [ 1259060791, 1259060791 ]
|
||||
> [CRC32.buf([0x2603]), CRC32.buf([0x0003])] // [ 1259060791, 1259060791 ]
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
`make test` will run the nodejs-based test. To run the in-browser tests, run a
|
||||
local server and go to the `ctest` directory. To update the browser artifacts,
|
||||
run `make ctest`.
|
||||
`make test` will run the node-based tests.
|
||||
|
||||
## Performance
|
||||
|
||||
`make perf` will run algorithmic performance tests (which should justify certain
|
||||
decisions in the code).
|
||||
|
||||
`make perf-all` compares the performance of various crc-32 algorithms that
|
||||
implement the correct form (note that the SSE intrinsic is designed for the
|
||||
CRC32C checksum and uses a different polynomial).
|
||||
|
||||
Unexpected code patterns were based on performance testing in node and browser:
|
||||
|
||||
- [Loop unrolling helps!](http://jsperf.com/crc32-table/2)
|
||||
|
||||
## In the future ...
|
||||
|
||||
- Specifying an arbitrary initial CRC value
|
||||
|
||||
- Supporting different polynomials (e.g. CRC32C)
|
||||
To run the in-browser tests, run a local server and go to the `ctest` directory.
|
||||
To update the browser artifacts, run `make ctest`.
|
||||
|
||||
## License
|
||||
|
||||
Please consult the attached LICENSE file for details. All rights not explicitly
|
||||
granted by the Apache 2.0 license are reserved by the Original Author.
|
||||
|
||||
## Badges
|
||||
|
||||
[![Build Status](https://travis-ci.org/SheetJS/js-crc32.svg?branch=master)](https://travis-ci.org/SheetJS/js-crc32)
|
||||
|
||||
[![Coverage Status](https://img.shields.io/coveralls/SheetJS/js-crc32/master.svg)](https://coveralls.io/r/SheetJS/js-crc32?branch=master)
|
||||
|
||||
[![githalytics.com alpha](https://cruel-carlota.pagodabox.com/ee0e89f8b1d5b861ffbf264b8ce329a6 "githalytics.com")](http://githalytics.com/SheetJS/js-crc32)
|
||||
[![Coverage Status](http://img.shields.io/coveralls/SheetJS/js-crc32/master.svg)](https://coveralls.io/r/SheetJS/js-crc32?branch=master)
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-crc32?pixel)](https://github.com/SheetJS/js-crc32)
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* crc32.js (C) 2014 SheetJS -- http://sheetjs.com */
|
||||
/* vim: set ts=2: */
|
||||
var CRC32 = {};
|
||||
/*:: declare var DO_NOT_EXPORT_CRC: any; */
|
||||
(function(CRC32) {
|
||||
|
@ -1 +1 @@
|
||||
CRC32.version = '0.2.2';
|
||||
CRC32.version = '0.3.0';
|
||||
|
5
bits/10_types.js
Normal file
5
bits/10_types.js
Normal file
@ -0,0 +1,5 @@
|
||||
/*::
|
||||
type CRC32Type = number;
|
||||
type ABuf = Array<number> | Buffer;
|
||||
type CRC32TableType = Array<number> | Int32Array;
|
||||
*/
|
@ -1,6 +1,6 @@
|
||||
/* see perf/crc32table.js */
|
||||
function signed_crc_table() {
|
||||
var c, table = new Array(256);
|
||||
function signed_crc_table()/*:CRC32TableType*/ {
|
||||
var c = 0, table/*:Array<number>*/ = new Array(256);
|
||||
|
||||
for(var n =0; n != 256; ++n){
|
||||
c = n;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* charCodeAt is the best approach for binary strings */
|
||||
var use_buffer = typeof Buffer !== 'undefined';
|
||||
function crc32_bstr(bstr) {
|
||||
if(bstr.length > 32768) if(use_buffer) return crc32_buf_8(Buffer(bstr));
|
||||
function crc32_bstr(bstr/*:string*/)/*:CRC32Type*/ {
|
||||
if(bstr.length > 32768) if(use_buffer) return crc32_buf_8(new Buffer(bstr));
|
||||
var crc = -1, L = bstr.length - 1;
|
||||
for(var i = 0; i < L;) {
|
||||
crc = table[(crc ^ bstr.charCodeAt(i++)) & 0xFF] ^ (crc >>> 8);
|
||||
@ -11,7 +11,7 @@ function crc32_bstr(bstr) {
|
||||
return crc ^ -1;
|
||||
}
|
||||
|
||||
function crc32_buf(buf) {
|
||||
function crc32_buf(buf/*:ABuf*/)/*:CRC32Type*/ {
|
||||
if(buf.length > 10000) return crc32_buf_8(buf);
|
||||
for(var crc = -1, i = 0, L=buf.length-3; i < L;) {
|
||||
crc = (crc >>> 8) ^ table[(crc^buf[i++])&0xFF];
|
||||
@ -23,7 +23,7 @@ function crc32_buf(buf) {
|
||||
return crc ^ -1;
|
||||
}
|
||||
|
||||
function crc32_buf_8(buf) {
|
||||
function crc32_buf_8(buf/*:ABuf*/)/*:CRC32Type*/ {
|
||||
for(var crc = -1, i = 0, L=buf.length-7; i < L;) {
|
||||
crc = (crc >>> 8) ^ table[(crc^buf[i++])&0xFF];
|
||||
crc = (crc >>> 8) ^ table[(crc^buf[i++])&0xFF];
|
||||
@ -39,7 +39,7 @@ function crc32_buf_8(buf) {
|
||||
}
|
||||
|
||||
/* much much faster to intertwine utf8 and crc */
|
||||
function crc32_str(str) {
|
||||
function crc32_str(str/*:string*/)/*:CRC32Type*/ {
|
||||
for(var crc = -1, i = 0, L=str.length, c, d; i < L;) {
|
||||
c = str.charCodeAt(i++);
|
||||
if(c < 0x80) {
|
||||
|
100
crc32.flow.js
Normal file
100
crc32.flow.js
Normal file
@ -0,0 +1,100 @@
|
||||
/* crc32.js (C) 2014 SheetJS -- http://sheetjs.com */
|
||||
/* vim: set ts=2: */
|
||||
var CRC32 = {};
|
||||
/*:: declare var DO_NOT_EXPORT_CRC: any; */
|
||||
(function(CRC32) {
|
||||
CRC32.version = '0.3.0';
|
||||
/*::
|
||||
type CRC32Type = number;
|
||||
type ABuf = Array<number> | Buffer;
|
||||
type CRC32TableType = Array<number> | Int32Array;
|
||||
*/
|
||||
/* see perf/crc32table.js */
|
||||
function signed_crc_table()/*:CRC32TableType*/ {
|
||||
var c = 0, table/*:Array<number>*/ = 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 table = signed_crc_table();
|
||||
/* charCodeAt is the best approach for binary strings */
|
||||
var use_buffer = typeof Buffer !== 'undefined';
|
||||
function crc32_bstr(bstr/*:string*/)/*:CRC32Type*/ {
|
||||
if(bstr.length > 32768) if(use_buffer) return crc32_buf_8(new Buffer(bstr));
|
||||
var crc = -1, L = bstr.length - 1;
|
||||
for(var i = 0; i < L;) {
|
||||
crc = table[(crc ^ bstr.charCodeAt(i++)) & 0xFF] ^ (crc >>> 8);
|
||||
crc = table[(crc ^ bstr.charCodeAt(i++)) & 0xFF] ^ (crc >>> 8);
|
||||
}
|
||||
if(i === L) crc = (crc >>> 8) ^ table[(crc ^ bstr.charCodeAt(i)) & 0xFF];
|
||||
return crc ^ -1;
|
||||
}
|
||||
|
||||
function crc32_buf(buf/*:ABuf*/)/*:CRC32Type*/ {
|
||||
if(buf.length > 10000) return crc32_buf_8(buf);
|
||||
for(var crc = -1, i = 0, L=buf.length-3; i < L;) {
|
||||
crc = (crc >>> 8) ^ table[(crc^buf[i++])&0xFF];
|
||||
crc = (crc >>> 8) ^ table[(crc^buf[i++])&0xFF];
|
||||
crc = (crc >>> 8) ^ table[(crc^buf[i++])&0xFF];
|
||||
crc = (crc >>> 8) ^ table[(crc^buf[i++])&0xFF];
|
||||
}
|
||||
while(i < L+3) crc = (crc >>> 8) ^ table[(crc^buf[i++])&0xFF];
|
||||
return crc ^ -1;
|
||||
}
|
||||
|
||||
function crc32_buf_8(buf/*:ABuf*/)/*:CRC32Type*/ {
|
||||
for(var crc = -1, i = 0, L=buf.length-7; i < L;) {
|
||||
crc = (crc >>> 8) ^ table[(crc^buf[i++])&0xFF];
|
||||
crc = (crc >>> 8) ^ table[(crc^buf[i++])&0xFF];
|
||||
crc = (crc >>> 8) ^ table[(crc^buf[i++])&0xFF];
|
||||
crc = (crc >>> 8) ^ table[(crc^buf[i++])&0xFF];
|
||||
crc = (crc >>> 8) ^ table[(crc^buf[i++])&0xFF];
|
||||
crc = (crc >>> 8) ^ table[(crc^buf[i++])&0xFF];
|
||||
crc = (crc >>> 8) ^ table[(crc^buf[i++])&0xFF];
|
||||
crc = (crc >>> 8) ^ table[(crc^buf[i++])&0xFF];
|
||||
}
|
||||
while(i < L+7) crc = (crc >>> 8) ^ table[(crc^buf[i++])&0xFF];
|
||||
return crc ^ -1;
|
||||
}
|
||||
|
||||
/* much much faster to intertwine utf8 and crc */
|
||||
function crc32_str(str/*:string*/)/*:CRC32Type*/ {
|
||||
for(var crc = -1, i = 0, L=str.length, c, d; i < L;) {
|
||||
c = str.charCodeAt(i++);
|
||||
if(c < 0x80) {
|
||||
crc = (crc >>> 8) ^ table[(crc ^ c) & 0xFF];
|
||||
} else if(c < 0x800) {
|
||||
crc = (crc >>> 8) ^ table[(crc ^ (192|((c>>6)&31))) & 0xFF];
|
||||
crc = (crc >>> 8) ^ table[(crc ^ (128|(c&63))) & 0xFF];
|
||||
} else if(c >= 0xD800 && c < 0xE000) {
|
||||
c = (c&1023)+64; d = str.charCodeAt(i++) & 1023;
|
||||
crc = (crc >>> 8) ^ table[(crc ^ (240|((c>>8)&7))) & 0xFF];
|
||||
crc = (crc >>> 8) ^ table[(crc ^ (128|((c>>2)&63))) & 0xFF];
|
||||
crc = (crc >>> 8) ^ table[(crc ^ (128|((d>>6)&15)|(c&3))) & 0xFF];
|
||||
crc = (crc >>> 8) ^ table[(crc ^ (128|(d&63))) & 0xFF];
|
||||
} else {
|
||||
crc = (crc >>> 8) ^ table[(crc ^ (224|((c>>12)&15))) & 0xFF];
|
||||
crc = (crc >>> 8) ^ table[(crc ^ (128|((c>>6)&63))) & 0xFF];
|
||||
crc = (crc >>> 8) ^ table[(crc ^ (128|(c&63))) & 0xFF];
|
||||
}
|
||||
}
|
||||
return crc ^ -1;
|
||||
}
|
||||
CRC32.table = table;
|
||||
CRC32.bstr = crc32_bstr;
|
||||
CRC32.buf = crc32_buf;
|
||||
CRC32.str = crc32_str;
|
||||
})(typeof exports !== "undefined" && typeof DO_NOT_EXPORT_CRC === 'undefined' ? exports : CRC32);
|
6
crc32.js
6
crc32.js
@ -2,10 +2,10 @@
|
||||
/* vim: set ts=2: */
|
||||
var CRC32 = {};
|
||||
(function(CRC32) {
|
||||
CRC32.version = '0.2.2';
|
||||
CRC32.version = '0.3.0';
|
||||
/* see perf/crc32table.js */
|
||||
function signed_crc_table() {
|
||||
var c, table = new Array(256);
|
||||
var c = 0, table = new Array(256);
|
||||
|
||||
for(var n =0; n != 256; ++n){
|
||||
c = n;
|
||||
@ -27,7 +27,7 @@ var table = signed_crc_table();
|
||||
/* charCodeAt is the best approach for binary strings */
|
||||
var use_buffer = typeof Buffer !== 'undefined';
|
||||
function crc32_bstr(bstr) {
|
||||
if(bstr.length > 32768) if(use_buffer) return crc32_buf_8(Buffer(bstr));
|
||||
if(bstr.length > 32768) if(use_buffer) return crc32_buf_8(new Buffer(bstr));
|
||||
var crc = -1, L = bstr.length - 1;
|
||||
for(var i = 0; i < L;) {
|
||||
crc = table[(crc ^ bstr.charCodeAt(i++)) & 0xFF] ^ (crc >>> 8);
|
||||
|
@ -2,10 +2,10 @@
|
||||
/* vim: set ts=2: */
|
||||
var CRC32 = {};
|
||||
(function(CRC32) {
|
||||
CRC32.version = '0.2.2';
|
||||
CRC32.version = '0.3.0';
|
||||
/* see perf/crc32table.js */
|
||||
function signed_crc_table() {
|
||||
var c, table = new Array(256);
|
||||
var c = 0, table = new Array(256);
|
||||
|
||||
for(var n =0; n != 256; ++n){
|
||||
c = n;
|
||||
@ -27,7 +27,7 @@ var table = signed_crc_table();
|
||||
/* charCodeAt is the best approach for binary strings */
|
||||
var use_buffer = typeof Buffer !== 'undefined';
|
||||
function crc32_bstr(bstr) {
|
||||
if(bstr.length > 32768) if(use_buffer) return crc32_buf_8(Buffer(bstr));
|
||||
if(bstr.length > 32768) if(use_buffer) return crc32_buf_8(new Buffer(bstr));
|
||||
var crc = -1, L = bstr.length - 1;
|
||||
for(var i = 0; i < L;) {
|
||||
crc = table[(crc ^ bstr.charCodeAt(i++)) & 0xFF] ^ (crc >>> 8);
|
||||
|
@ -1,15 +1,13 @@
|
||||
{
|
||||
"name": "crc-32",
|
||||
"version": "0.2.2",
|
||||
"version": "0.3.0",
|
||||
"author": "sheetjs",
|
||||
"description": "Pure-JS CRC-32",
|
||||
"keywords": [ "crc32", "checksum", "crc" ],
|
||||
"main": "./crc32",
|
||||
"devDependencies": {
|
||||
"mocha":"",
|
||||
"xlsjs":"",
|
||||
"uglify-js":"",
|
||||
"codepage":""
|
||||
"uglify-js":""
|
||||
},
|
||||
"repository": { "type":"git", "url":"git://github.com/SheetJS/js-crc32.git" },
|
||||
"scripts": {
|
||||
|
Loading…
Reference in New Issue
Block a user