Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
SheetJSDev committed Jun 16, 2014
0 parents commit 35003c5
Show file tree
Hide file tree
Showing 29 changed files with 6,981 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
@@ -0,0 +1,2 @@
node_modules
misc/coverage.html
6 changes: 6 additions & 0 deletions .jscs.json
@@ -0,0 +1,6 @@
{
"requireCommaBeforeLineBreak": true,
"disallowTrailingWhitespace": true,
"disallowTrailingComma": true
}

11 changes: 11 additions & 0 deletions .travis.yml
@@ -0,0 +1,11 @@
language: node_js
node_js:
- "0.11"
- "0.10"
- "0.8"
before_install:
- "npm install -g mocha"
- "npm install blanket"
- "npm install coveralls mocha-lcov-reporter"
after_success:
- "make coveralls-spin"
14 changes: 14 additions & 0 deletions LICENSE
@@ -0,0 +1,14 @@
Copyright (C) 2014 SheetJS

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

53 changes: 53 additions & 0 deletions Makefile
@@ -0,0 +1,53 @@
LIB=crc32
DEPS=$(sort $(wildcard bits/*.js))
TARGET=$(LIB).js

$(TARGET): $(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}'`"';" > $@

.PHONY: clean
clean:
rm -f $(TARGET)

.PHONY: test mocha
test mocha: test.js
mocha -R spec

.PHONY: ctest
ctest:
cat misc/*.js > ctest/fixtures.js
cp -f test.js ctest/test.js
cp -f $(TARGET) ctest/

.PHONY: lint
lint: $(TARGET)
jshint --show-non-errors $(TARGET)
jscs $(TARGET)

.PHONY: cov cov-spin
cov: misc/coverage.html
cov-spin:
make cov & bash misc/spin.sh $$!

COVFMT=$(patsubst %,cov_%,$(FMT))
.PHONY: $(COVFMT)
$(COVFMT): cov_%:
FMTS=$* make cov

misc/coverage.html: $(TARGET) test.js
mocha --require blanket -R html-cov > $@

.PHONY: coveralls coveralls-spin
coveralls:
mocha --require blanket --reporter mocha-lcov-reporter | ./node_modules/coveralls/bin/coveralls.js

coveralls-spin:
make coveralls & bash misc/spin.sh $$!

.PHONY: perf
perf:
bash perf/perf.sh
54 changes: 54 additions & 0 deletions README.md
@@ -0,0 +1,54 @@
# crc32

Standard CRC-32 algorithm implementation in JS (for the browser and nodejs).
Emphasis on correctness and performance.

## Installation

In [nodejs](https://www.npmjs.org/package/crc-32):

npm install crc-32

In the browser:

<script lang="javascript" src="crc32.js"></script>

The browser exposes a variable CRC32

## 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)

- `CRC32.bstr(binary string)` interprets the argument as a binary string where
the `i`-th byte is `str.charCodeAt(i)`

- `CRC32.str(string)` interprets the argument as a standard JS string

## 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`.

## Performance

`make perf` will run performance tests.

## In the future ...

- Specifying an arbitrary initial CRC value

- Supporting different polynomials (e.g. CRC32C)

## 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.

[![Build Status](https://travis-ci.org/SheetJS/js-crc32.png?branch=master)](https://travis-ci.org/SheetJS/js-crc32)

[![Coverage Status](https://coveralls.io/repos/SheetJS/js-crc32/badge.png?branch=master)](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)

4 changes: 4 additions & 0 deletions bits/00_header.js
@@ -0,0 +1,4 @@
/* crc32.js (C) 2014 SheetJS -- http://sheetjs.com */
/* vim: set ts=2: */
var CRC32 = {};
(function(CRC32) {
1 change: 1 addition & 0 deletions bits/01_version.js
@@ -0,0 +1 @@
CRC32.version = '0.1.0';
21 changes: 21 additions & 0 deletions bits/20_crctable.js
@@ -0,0 +1,21 @@
/* see perf/crc32table.js */
function signed_crc_table() {
var c, table = 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 table;
}

var table = signed_crc_table();
40 changes: 40 additions & 0 deletions bits/40_crc.js
@@ -0,0 +1,40 @@
/* charCodeAt is the best approach for binary strings */
function crc32_bstr(bstr) {
for(var crc = -1, i = 0, L=bstr.length-1; i < L;) {
crc = (crc >>> 8) ^ table[(crc ^ bstr.charCodeAt(i++)) & 0xFF];
crc = (crc >>> 8) ^ table[(crc ^ bstr.charCodeAt(i++)) & 0xFF];
}
if(i === L) crc = (crc >>> 8) ^ table[(crc ^ bstr.charCodeAt(i++)) & 0xFF];
return crc ^ -1;
}

function crc32_buf(buf) {
for(var crc = -1, i = 0; i != buf.length; ++i) {
crc = (crc >>> 8) ^ table[(crc ^ buf[i]) & 0xFF];
}
return crc ^ -1;
}

/* much much faster to intertwine utf8 and crc */
function crc32_str(str) {
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;
}
4 changes: 4 additions & 0 deletions bits/90_exports.js
@@ -0,0 +1,4 @@
CRC32.table = table;
CRC32.bstr = crc32_bstr;
CRC32.buf = crc32_buf;
CRC32.str = crc32_str;
1 change: 1 addition & 0 deletions bits/99_footer.js
@@ -0,0 +1 @@
})(typeof exports !== "undefined" && typeof DO_NOT_EXPORT_CRC === 'undefined' ? exports : CRC32);
71 changes: 71 additions & 0 deletions crc32.js
@@ -0,0 +1,71 @@
/* crc32.js (C) 2014 SheetJS -- http://sheetjs.com */
/* vim: set ts=2: */
var CRC32 = {};
(function(CRC32) {
CRC32.version = '0.1.0';
/* see perf/crc32table.js */
function signed_crc_table() {
var c, table = 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 table;
}

var table = signed_crc_table();
/* charCodeAt is the best approach for binary strings */
function crc32_bstr(bstr) {
for(var crc = -1, i = 0, L=bstr.length-1; i < L;) {
crc = (crc >>> 8) ^ table[(crc ^ bstr.charCodeAt(i++)) & 0xFF];
crc = (crc >>> 8) ^ table[(crc ^ bstr.charCodeAt(i++)) & 0xFF];
}
if(i === L) crc = (crc >>> 8) ^ table[(crc ^ bstr.charCodeAt(i++)) & 0xFF];
return crc ^ -1;
}

function crc32_buf(buf) {
for(var crc = -1, i = 0; i != buf.length; ++i) {
crc = (crc >>> 8) ^ table[(crc ^ buf[i]) & 0xFF];
}
return crc ^ -1;
}

/* much much faster to intertwine utf8 and crc */
function crc32_str(str) {
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);
71 changes: 71 additions & 0 deletions ctest/crc32.js
@@ -0,0 +1,71 @@
/* crc32.js (C) 2014 SheetJS -- http://sheetjs.com */
/* vim: set ts=2: */
var CRC32 = {};
(function(CRC32) {
CRC32.version = '0.1.0';
/* see perf/crc32table.js */
function signed_crc_table() {
var c, table = 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 table;
}

var table = signed_crc_table();
/* charCodeAt is the best approach for binary strings */
function crc32_bstr(bstr) {
for(var crc = -1, i = 0, L=bstr.length-1; i < L;) {
crc = (crc >>> 8) ^ table[(crc ^ bstr.charCodeAt(i++)) & 0xFF];
crc = (crc >>> 8) ^ table[(crc ^ bstr.charCodeAt(i++)) & 0xFF];
}
if(i === L) crc = (crc >>> 8) ^ table[(crc ^ bstr.charCodeAt(i++)) & 0xFF];
return crc ^ -1;
}

function crc32_buf(buf) {
for(var crc = -1, i = 0; i != buf.length; ++i) {
crc = (crc >>> 8) ^ table[(crc ^ buf[i]) & 0xFF];
}
return crc ^ -1;
}

/* much much faster to intertwine utf8 and crc */
function crc32_str(str) {
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);
2 changes: 2 additions & 0 deletions ctest/fakeassert.js
@@ -0,0 +1,2 @@
var assert = {};
assert.equal = function(x,y) { if(x !== y) throw x + " !== " + y; };

0 comments on commit 35003c5

Please sign in to comment.