jaroslav@694: /* -*-mode:java; c-basic-offset:2; -*- */ jaroslav@694: /* jaroslav@694: Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. jaroslav@694: jaroslav@694: Redistribution and use in source and binary forms, with or without jaroslav@694: modification, are permitted provided that the following conditions are met: jaroslav@694: jaroslav@694: 1. Redistributions of source code must retain the above copyright notice, jaroslav@694: this list of conditions and the following disclaimer. jaroslav@694: jaroslav@694: 2. Redistributions in binary form must reproduce the above copyright jaroslav@694: notice, this list of conditions and the following disclaimer in jaroslav@694: the documentation and/or other materials provided with the distribution. jaroslav@694: jaroslav@694: 3. The names of the authors may not be used to endorse or promote products jaroslav@694: derived from this software without specific prior written permission. jaroslav@694: jaroslav@694: THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, jaroslav@694: INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND jaroslav@694: FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, jaroslav@694: INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, jaroslav@694: INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT jaroslav@694: LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, jaroslav@694: OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF jaroslav@694: LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING jaroslav@694: NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, jaroslav@694: EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. jaroslav@694: */ jaroslav@694: /* jaroslav@694: * This program is based on zlib-1.1.3, so all credit should go authors jaroslav@694: * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) jaroslav@694: * and contributors of zlib. jaroslav@694: */ jaroslav@694: jaroslav@694: package org.apidesign.bck2brwsr.emul.zip; jaroslav@694: jaroslav@694: import org.apidesign.bck2brwsr.emul.lang.System; jaroslav@694: jaroslav@694: final class CRC32 implements Checksum { jaroslav@694: jaroslav@694: /* jaroslav@694: * The following logic has come from RFC1952. jaroslav@694: */ jaroslav@694: private int v = 0; jaroslav@694: private static int[] crc_table = null; jaroslav@694: static { jaroslav@694: crc_table = new int[256]; jaroslav@694: for (int n = 0; n < 256; n++) { jaroslav@694: int c = n; jaroslav@694: for (int k = 8; --k >= 0; ) { jaroslav@694: if ((c & 1) != 0) jaroslav@694: c = 0xedb88320 ^ (c >>> 1); jaroslav@694: else jaroslav@694: c = c >>> 1; jaroslav@694: } jaroslav@694: crc_table[n] = c; jaroslav@694: } jaroslav@694: } jaroslav@694: jaroslav@694: public void update (byte[] buf, int index, int len) { jaroslav@694: int c = ~v; jaroslav@694: while (--len >= 0) jaroslav@694: c = crc_table[(c^buf[index++])&0xff]^(c >>> 8); jaroslav@694: v = ~c; jaroslav@694: } jaroslav@694: jaroslav@694: public void reset(){ jaroslav@694: v = 0; jaroslav@694: } jaroslav@694: jaroslav@694: public void reset(long vv){ jaroslav@694: v = (int)(vv&0xffffffffL); jaroslav@694: } jaroslav@694: jaroslav@694: public long getValue(){ jaroslav@694: return (long)(v&0xffffffffL); jaroslav@694: } jaroslav@694: jaroslav@694: // The following logic has come from zlib.1.2. jaroslav@694: private static final int GF2_DIM = 32; jaroslav@694: static long combine(long crc1, long crc2, long len2){ jaroslav@694: long row; jaroslav@694: long[] even = new long[GF2_DIM]; jaroslav@694: long[] odd = new long[GF2_DIM]; jaroslav@694: jaroslav@694: // degenerate case (also disallow negative lengths) jaroslav@694: if (len2 <= 0) jaroslav@694: return crc1; jaroslav@694: jaroslav@694: // put operator for one zero bit in odd jaroslav@694: odd[0] = 0xedb88320L; // CRC-32 polynomial jaroslav@694: row = 1; jaroslav@694: for (int n = 1; n < GF2_DIM; n++) { jaroslav@694: odd[n] = row; jaroslav@694: row <<= 1; jaroslav@694: } jaroslav@694: jaroslav@694: // put operator for two zero bits in even jaroslav@694: gf2_matrix_square(even, odd); jaroslav@694: jaroslav@694: // put operator for four zero bits in odd jaroslav@694: gf2_matrix_square(odd, even); jaroslav@694: jaroslav@694: // apply len2 zeros to crc1 (first square will put the operator for one jaroslav@694: // zero byte, eight zero bits, in even) jaroslav@694: do { jaroslav@694: // apply zeros operator for this bit of len2 jaroslav@694: gf2_matrix_square(even, odd); jaroslav@694: if ((len2 & 1)!=0) jaroslav@694: crc1 = gf2_matrix_times(even, crc1); jaroslav@694: len2 >>= 1; jaroslav@694: jaroslav@694: // if no more bits set, then done jaroslav@694: if (len2 == 0) jaroslav@694: break; jaroslav@694: jaroslav@694: // another iteration of the loop with odd and even swapped jaroslav@694: gf2_matrix_square(odd, even); jaroslav@694: if ((len2 & 1)!=0) jaroslav@694: crc1 = gf2_matrix_times(odd, crc1); jaroslav@694: len2 >>= 1; jaroslav@694: jaroslav@694: // if no more bits set, then done jaroslav@694: } while (len2 != 0); jaroslav@694: jaroslav@694: /* return combined crc */ jaroslav@694: crc1 ^= crc2; jaroslav@694: return crc1; jaroslav@694: } jaroslav@694: jaroslav@694: private static long gf2_matrix_times(long[] mat, long vec){ jaroslav@694: long sum = 0; jaroslav@694: int index = 0; jaroslav@694: while (vec!=0) { jaroslav@694: if ((vec & 1)!=0) jaroslav@694: sum ^= mat[index]; jaroslav@694: vec >>= 1; jaroslav@694: index++; jaroslav@694: } jaroslav@694: return sum; jaroslav@694: } jaroslav@694: jaroslav@694: static final void gf2_matrix_square(long[] square, long[] mat) { jaroslav@694: for (int n = 0; n < GF2_DIM; n++) jaroslav@694: square[n] = gf2_matrix_times(mat, mat[n]); jaroslav@694: } jaroslav@694: jaroslav@694: /* jaroslav@694: private java.util.zip.CRC32 crc32 = new java.util.zip.CRC32(); jaroslav@694: jaroslav@694: public void update(byte[] buf, int index, int len){ jaroslav@694: if(buf==null) {crc32.reset();} jaroslav@694: else{crc32.update(buf, index, len);} jaroslav@694: } jaroslav@694: public void reset(){ jaroslav@694: crc32.reset(); jaroslav@694: } jaroslav@694: public void reset(long init){ jaroslav@694: if(init==0L){ jaroslav@694: crc32.reset(); jaroslav@694: } jaroslav@694: else{ jaroslav@694: System.err.println("unsupported operation"); jaroslav@694: } jaroslav@694: } jaroslav@694: public long getValue(){ jaroslav@694: return crc32.getValue(); jaroslav@694: } jaroslav@694: */ jaroslav@694: public CRC32 copy(){ jaroslav@694: CRC32 foo = new CRC32(); jaroslav@694: foo.v = this.v; jaroslav@694: return foo; jaroslav@694: } jaroslav@694: jaroslav@694: public static int[] getCRC32Table(){ jaroslav@694: int[] tmp = new int[crc_table.length]; jaroslav@694: System.arraycopy(crc_table, 0, tmp, 0, tmp.length); jaroslav@694: return tmp; jaroslav@694: } jaroslav@694: }