• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * CRC64
3  *
4  * Authors: Brett Okken <brett.okken.os@gmail.com>
5  *          Lasse Collin <lasse.collin@tukaani.org>
6  *
7  * This file has been put into the public domain.
8  * You can do whatever you want with this file.
9  */
10 
11 package org.tukaani.xz.check;
12 
13 public class CRC64 extends Check {
14     private static final long[][] TABLE = new long[4][256];
15 
16     static {
17         final long poly64 = 0xC96C5795D7870F42L;
18 
19         for (int s = 0; s < 4; ++s) {
20             for (int b = 0; b < 256; ++b) {
21                 long r = s == 0 ? b : TABLE[s - 1][b];
22                 for (int i = 0; i < 8; ++i) {
23                     if ((r & 1) == 1) {
24                         r = (r >>> 1) ^ poly64;
25                     } else {
26                         r >>>= 1;
27                     }
28                 }
29                 TABLE[s][b] = r;
30             }
31         }
32     }
33 
34     private long crc = -1;
35 
CRC64()36     public CRC64() {
37         size = 8;
38         name = "CRC64";
39     }
40 
41     @Override
update(byte[] buf, int off, int len)42     public void update(byte[] buf, int off, int len) {
43         final int end = off + len;
44         int i = off;
45 
46         for (int end4 = end - 3; i < end4; i += 4) {
47             final int tmp = (int)crc;
48             crc = TABLE[3][(tmp & 0xFF) ^ (buf[i] & 0xFF)] ^
49                   TABLE[2][((tmp >>> 8) & 0xFF) ^ (buf[i + 1] & 0xFF)] ^
50                   (crc >>> 32) ^
51                   TABLE[1][((tmp >>> 16) & 0xFF) ^ (buf[i + 2] & 0xFF)] ^
52                   TABLE[0][((tmp >>> 24) & 0xFF) ^ (buf[i + 3] & 0xFF)];
53         }
54 
55         while (i < end)
56             crc = TABLE[0][(buf[i++] & 0xFF) ^ ((int)crc & 0xFF)] ^
57                   (crc >>> 8);
58     }
59 
60     @Override
finish()61     public byte[] finish() {
62         long value = ~crc;
63         crc = -1;
64 
65         byte[] buf = new byte[8];
66         for (int i = 0; i < buf.length; ++i)
67             buf[i] = (byte)(value >> (i * 8));
68 
69         return buf;
70     }
71 }
72