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];