1 /*
2  * Copyright (C) 2011 The Guava Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5  * in compliance with the License. You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the License
10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11  * or implied. See the License for the specific language governing permissions and limitations under
12  * the License.
13  */
14 
15 package com.google.common.hash;
16 
17 import static com.google.common.base.Charsets.UTF_8;
18 
19 import java.util.Arrays;
20 import junit.framework.TestCase;
21 
22 /**
23  * Unit tests for {@link Crc32c}. Known test values are from RFC 3720, Section B.4.
24  *
25  * @author Patrick Costello
26  * @author Kurt Alfred Kluever
27  */
28 public class Crc32cHashFunctionTest extends TestCase {
29 
testZeros()30   public void testZeros() {
31     // Test 32 byte array of 0x00.
32     byte[] zeros = new byte[32];
33     Arrays.fill(zeros, (byte) 0x00);
34     assertCrc(0x8a9136aa, zeros);
35   }
36 
testFull()37   public void testFull() {
38     // Test 32 byte array of 0xFF.
39     byte[] fulls = new byte[32];
40     Arrays.fill(fulls, (byte) 0xFF);
41     assertCrc(0x62a8ab43, fulls);
42   }
43 
testAscending()44   public void testAscending() {
45     // Test 32 byte arrays of ascending.
46     byte[] ascending = new byte[32];
47     for (int i = 0; i < 32; i++) {
48       ascending[i] = (byte) i;
49     }
50     assertCrc(0x46dd794e, ascending);
51   }
52 
testDescending()53   public void testDescending() {
54     // Test 32 byte arrays of descending.
55     byte[] descending = new byte[32];
56     for (int i = 0; i < 32; i++) {
57       descending[i] = (byte) (31 - i);
58     }
59     assertCrc(0x113fdb5c, descending);
60   }
61 
testScsiReadCommand()62   public void testScsiReadCommand() {
63     // Test SCSI read command.
64     byte[] scsiReadCommand =
65         new byte[] {
66           0x01, (byte) 0xc0, 0x00, 0x00,
67           0x00, 0x00, 0x00, 0x00,
68           0x00, 0x00, 0x00, 0x00,
69           0x00, 0x00, 0x00, 0x00,
70           0x14, 0x00, 0x00, 0x00,
71           0x00, 0x00, 0x04, 0x00,
72           0x00, 0x00, 0x00, 0x14,
73           0x00, 0x00, 0x00, 0x18,
74           0x28, 0x00, 0x00, 0x00,
75           0x00, 0x00, 0x00, 0x00,
76           0x02, 0x00, 0x00, 0x00,
77           0x00, 0x00, 0x00, 0x00
78         };
79     assertCrc(0xd9963a56, scsiReadCommand);
80   }
81 
82   // Known values from http://www.evanjones.ca/crc32c.html
testSomeOtherKnownValues()83   public void testSomeOtherKnownValues() {
84     assertCrc(0x22620404, "The quick brown fox jumps over the lazy dog".getBytes(UTF_8));
85     assertCrc(0xE3069283, "123456789".getBytes(UTF_8));
86     assertCrc(0xf3dbd4fe, "1234567890".getBytes(UTF_8));
87     assertCrc(0xBFE92A83, "23456789".getBytes(UTF_8));
88   }
89 
90   /**
91    * Verifies that the crc of an array of byte data matches the expected value.
92    *
93    * @param expectedCrc the expected crc value.
94    * @param data the data to run the checksum on.
95    */
assertCrc(int expectedCrc, byte[] data)96   private static void assertCrc(int expectedCrc, byte[] data) {
97     int actualCrc = Hashing.crc32c().hashBytes(data).asInt();
98     assertEquals(expectedCrc, actualCrc);
99   }
100 
101   // From RFC 3720, Section 12.1, the polynomial generator is 0x11EDC6F41.
102   // We calculate the constant below by:
103   //   1. Omitting the most significant bit (because it's always 1). => 0x1EDC6F41
104   //   2. Flipping the bits of the constant so we can process a byte at a time. => 0x82F63B78
105   private static final int CRC32C_GENERATOR = 0x1EDC6F41; // 0x11EDC6F41
106   private static final int CRC32C_GENERATOR_FLIPPED = Integer.reverse(CRC32C_GENERATOR);
107 
testCrc32cLookupTable()108   public void testCrc32cLookupTable() {
109     // See Hacker's Delight 2nd Edition, Figure 14-7.
110     int[] expected = new int[256];
111     for (int i = 0; i < expected.length; i++) {
112       int crc = i;
113       for (int j = 7; j >= 0; j--) {
114         int mask = -(crc & 1);
115         crc = ((crc >>> 1) ^ (CRC32C_GENERATOR_FLIPPED & mask));
116       }
117       expected[i] = crc;
118     }
119 
120     int[] actual = Crc32cHashFunction.Crc32cHasher.CRC_TABLE;
121     assertTrue(
122         "Expected: \n" + Arrays.toString(expected) + "\nActual:\n" + Arrays.toString(actual),
123         Arrays.equals(expected, actual));
124   }
125 }
126