jaroslav@694
|
1 |
/* -*-mode:java; c-basic-offset:2; -*- */
|
jaroslav@694
|
2 |
/*
|
jaroslav@694
|
3 |
Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved.
|
jaroslav@694
|
4 |
|
jaroslav@694
|
5 |
Redistribution and use in source and binary forms, with or without
|
jaroslav@694
|
6 |
modification, are permitted provided that the following conditions are met:
|
jaroslav@694
|
7 |
|
jaroslav@694
|
8 |
1. Redistributions of source code must retain the above copyright notice,
|
jaroslav@694
|
9 |
this list of conditions and the following disclaimer.
|
jaroslav@694
|
10 |
|
jaroslav@694
|
11 |
2. Redistributions in binary form must reproduce the above copyright
|
jaroslav@694
|
12 |
notice, this list of conditions and the following disclaimer in
|
jaroslav@694
|
13 |
the documentation and/or other materials provided with the distribution.
|
jaroslav@694
|
14 |
|
jaroslav@694
|
15 |
3. The names of the authors may not be used to endorse or promote products
|
jaroslav@694
|
16 |
derived from this software without specific prior written permission.
|
jaroslav@694
|
17 |
|
jaroslav@694
|
18 |
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
jaroslav@694
|
19 |
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
jaroslav@694
|
20 |
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
jaroslav@694
|
21 |
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
jaroslav@694
|
22 |
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
jaroslav@694
|
23 |
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
jaroslav@694
|
24 |
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
jaroslav@694
|
25 |
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
jaroslav@694
|
26 |
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
jaroslav@694
|
27 |
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
jaroslav@694
|
28 |
*/
|
jaroslav@694
|
29 |
/*
|
jaroslav@694
|
30 |
* This program is based on zlib-1.1.3, so all credit should go authors
|
jaroslav@694
|
31 |
* Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
|
jaroslav@694
|
32 |
* and contributors of zlib.
|
jaroslav@694
|
33 |
*/
|
jaroslav@694
|
34 |
|
jaroslav@694
|
35 |
package org.apidesign.bck2brwsr.emul.zip;
|
jaroslav@694
|
36 |
|
jaroslav@1549
|
37 |
|
jaroslav@694
|
38 |
|
jaroslav@694
|
39 |
final class CRC32 implements Checksum {
|
jaroslav@694
|
40 |
|
jaroslav@694
|
41 |
/*
|
jaroslav@694
|
42 |
* The following logic has come from RFC1952.
|
jaroslav@694
|
43 |
*/
|
jaroslav@694
|
44 |
private int v = 0;
|
jaroslav@694
|
45 |
private static int[] crc_table = null;
|
jaroslav@694
|
46 |
static {
|
jaroslav@694
|
47 |
crc_table = new int[256];
|
jaroslav@694
|
48 |
for (int n = 0; n < 256; n++) {
|
jaroslav@694
|
49 |
int c = n;
|
jaroslav@694
|
50 |
for (int k = 8; --k >= 0; ) {
|
jaroslav@694
|
51 |
if ((c & 1) != 0)
|
jaroslav@694
|
52 |
c = 0xedb88320 ^ (c >>> 1);
|
jaroslav@694
|
53 |
else
|
jaroslav@694
|
54 |
c = c >>> 1;
|
jaroslav@694
|
55 |
}
|
jaroslav@694
|
56 |
crc_table[n] = c;
|
jaroslav@694
|
57 |
}
|
jaroslav@694
|
58 |
}
|
jaroslav@694
|
59 |
|
jaroslav@694
|
60 |
public void update (byte[] buf, int index, int len) {
|
jaroslav@694
|
61 |
int c = ~v;
|
jaroslav@694
|
62 |
while (--len >= 0)
|
jaroslav@694
|
63 |
c = crc_table[(c^buf[index++])&0xff]^(c >>> 8);
|
jaroslav@694
|
64 |
v = ~c;
|
jaroslav@694
|
65 |
}
|
jaroslav@694
|
66 |
|
jaroslav@694
|
67 |
public void reset(){
|
jaroslav@694
|
68 |
v = 0;
|
jaroslav@694
|
69 |
}
|
jaroslav@694
|
70 |
|
jaroslav@694
|
71 |
public void reset(long vv){
|
jaroslav@694
|
72 |
v = (int)(vv&0xffffffffL);
|
jaroslav@694
|
73 |
}
|
jaroslav@694
|
74 |
|
jaroslav@694
|
75 |
public long getValue(){
|
jaroslav@694
|
76 |
return (long)(v&0xffffffffL);
|
jaroslav@694
|
77 |
}
|
jaroslav@694
|
78 |
|
jaroslav@694
|
79 |
// The following logic has come from zlib.1.2.
|
jaroslav@694
|
80 |
private static final int GF2_DIM = 32;
|
jaroslav@694
|
81 |
static long combine(long crc1, long crc2, long len2){
|
jaroslav@694
|
82 |
long row;
|
jaroslav@694
|
83 |
long[] even = new long[GF2_DIM];
|
jaroslav@694
|
84 |
long[] odd = new long[GF2_DIM];
|
jaroslav@694
|
85 |
|
jaroslav@694
|
86 |
// degenerate case (also disallow negative lengths)
|
jaroslav@694
|
87 |
if (len2 <= 0)
|
jaroslav@694
|
88 |
return crc1;
|
jaroslav@694
|
89 |
|
jaroslav@694
|
90 |
// put operator for one zero bit in odd
|
jaroslav@694
|
91 |
odd[0] = 0xedb88320L; // CRC-32 polynomial
|
jaroslav@694
|
92 |
row = 1;
|
jaroslav@694
|
93 |
for (int n = 1; n < GF2_DIM; n++) {
|
jaroslav@694
|
94 |
odd[n] = row;
|
jaroslav@694
|
95 |
row <<= 1;
|
jaroslav@694
|
96 |
}
|
jaroslav@694
|
97 |
|
jaroslav@694
|
98 |
// put operator for two zero bits in even
|
jaroslav@694
|
99 |
gf2_matrix_square(even, odd);
|
jaroslav@694
|
100 |
|
jaroslav@694
|
101 |
// put operator for four zero bits in odd
|
jaroslav@694
|
102 |
gf2_matrix_square(odd, even);
|
jaroslav@694
|
103 |
|
jaroslav@694
|
104 |
// apply len2 zeros to crc1 (first square will put the operator for one
|
jaroslav@694
|
105 |
// zero byte, eight zero bits, in even)
|
jaroslav@694
|
106 |
do {
|
jaroslav@694
|
107 |
// apply zeros operator for this bit of len2
|
jaroslav@694
|
108 |
gf2_matrix_square(even, odd);
|
jaroslav@694
|
109 |
if ((len2 & 1)!=0)
|
jaroslav@694
|
110 |
crc1 = gf2_matrix_times(even, crc1);
|
jaroslav@694
|
111 |
len2 >>= 1;
|
jaroslav@694
|
112 |
|
jaroslav@694
|
113 |
// if no more bits set, then done
|
jaroslav@694
|
114 |
if (len2 == 0)
|
jaroslav@694
|
115 |
break;
|
jaroslav@694
|
116 |
|
jaroslav@694
|
117 |
// another iteration of the loop with odd and even swapped
|
jaroslav@694
|
118 |
gf2_matrix_square(odd, even);
|
jaroslav@694
|
119 |
if ((len2 & 1)!=0)
|
jaroslav@694
|
120 |
crc1 = gf2_matrix_times(odd, crc1);
|
jaroslav@694
|
121 |
len2 >>= 1;
|
jaroslav@694
|
122 |
|
jaroslav@694
|
123 |
// if no more bits set, then done
|
jaroslav@694
|
124 |
} while (len2 != 0);
|
jaroslav@694
|
125 |
|
jaroslav@694
|
126 |
/* return combined crc */
|
jaroslav@694
|
127 |
crc1 ^= crc2;
|
jaroslav@694
|
128 |
return crc1;
|
jaroslav@694
|
129 |
}
|
jaroslav@694
|
130 |
|
jaroslav@694
|
131 |
private static long gf2_matrix_times(long[] mat, long vec){
|
jaroslav@694
|
132 |
long sum = 0;
|
jaroslav@694
|
133 |
int index = 0;
|
jaroslav@694
|
134 |
while (vec!=0) {
|
jaroslav@694
|
135 |
if ((vec & 1)!=0)
|
jaroslav@694
|
136 |
sum ^= mat[index];
|
jaroslav@694
|
137 |
vec >>= 1;
|
jaroslav@694
|
138 |
index++;
|
jaroslav@694
|
139 |
}
|
jaroslav@694
|
140 |
return sum;
|
jaroslav@694
|
141 |
}
|
jaroslav@694
|
142 |
|
jaroslav@694
|
143 |
static final void gf2_matrix_square(long[] square, long[] mat) {
|
jaroslav@694
|
144 |
for (int n = 0; n < GF2_DIM; n++)
|
jaroslav@694
|
145 |
square[n] = gf2_matrix_times(mat, mat[n]);
|
jaroslav@694
|
146 |
}
|
jaroslav@694
|
147 |
|
jaroslav@694
|
148 |
/*
|
jaroslav@694
|
149 |
private java.util.zip.CRC32 crc32 = new java.util.zip.CRC32();
|
jaroslav@694
|
150 |
|
jaroslav@694
|
151 |
public void update(byte[] buf, int index, int len){
|
jaroslav@694
|
152 |
if(buf==null) {crc32.reset();}
|
jaroslav@694
|
153 |
else{crc32.update(buf, index, len);}
|
jaroslav@694
|
154 |
}
|
jaroslav@694
|
155 |
public void reset(){
|
jaroslav@694
|
156 |
crc32.reset();
|
jaroslav@694
|
157 |
}
|
jaroslav@694
|
158 |
public void reset(long init){
|
jaroslav@694
|
159 |
if(init==0L){
|
jaroslav@694
|
160 |
crc32.reset();
|
jaroslav@694
|
161 |
}
|
jaroslav@694
|
162 |
else{
|
jaroslav@694
|
163 |
System.err.println("unsupported operation");
|
jaroslav@694
|
164 |
}
|
jaroslav@694
|
165 |
}
|
jaroslav@694
|
166 |
public long getValue(){
|
jaroslav@694
|
167 |
return crc32.getValue();
|
jaroslav@694
|
168 |
}
|
jaroslav@694
|
169 |
*/
|
jaroslav@694
|
170 |
public CRC32 copy(){
|
jaroslav@694
|
171 |
CRC32 foo = new CRC32();
|
jaroslav@694
|
172 |
foo.v = this.v;
|
jaroslav@694
|
173 |
return foo;
|
jaroslav@694
|
174 |
}
|
jaroslav@694
|
175 |
|
jaroslav@694
|
176 |
public static int[] getCRC32Table(){
|
jaroslav@694
|
177 |
int[] tmp = new int[crc_table.length];
|
jaroslav@1555
|
178 |
FastJar.arraycopy(crc_table, 0, tmp, 0, tmp.length);
|
jaroslav@694
|
179 |
return tmp;
|
jaroslav@694
|
180 |
}
|
jaroslav@694
|
181 |
}
|