blob: 4619cec18836550b32f19adb6bb93b2e5ed06708 [file] [log] [blame]
/*
* Copyright (C) 2011 The Guava Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.common.hash;
import static com.google.common.base.Charsets.UTF_8;
import java.util.Arrays;
import junit.framework.TestCase;
/**
* Unit tests for {@link Crc32c}. Known test values are from RFC 3720, Section B.4.
*
* @author Patrick Costello
* @author Kurt Alfred Kluever
*/
public class Crc32cHashFunctionTest extends TestCase {
public void testZeros() {
// Test 32 byte array of 0x00.
byte[] zeros = new byte[32];
Arrays.fill(zeros, (byte) 0x00);
assertCrc(0x8a9136aa, zeros);
}
public void testFull() {
// Test 32 byte array of 0xFF.
byte[] fulls = new byte[32];
Arrays.fill(fulls, (byte) 0xFF);
assertCrc(0x62a8ab43, fulls);
}
public void testAscending() {
// Test 32 byte arrays of ascending.
byte[] ascending = new byte[32];
for (int i = 0; i < 32; i++) {
ascending[i] = (byte) i;
}
assertCrc(0x46dd794e, ascending);
}
public void testDescending() {
// Test 32 byte arrays of descending.
byte[] descending = new byte[32];
for (int i = 0; i < 32; i++) {
descending[i] = (byte) (31 - i);
}
assertCrc(0x113fdb5c, descending);
}
public void testScsiReadCommand() {
// Test SCSI read command.
byte[] scsiReadCommand =
new byte[] {
0x01, (byte) 0xc0, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x14, 0x00, 0x00, 0x00,
0x00, 0x00, 0x04, 0x00,
0x00, 0x00, 0x00, 0x14,
0x00, 0x00, 0x00, 0x18,
0x28, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
};
assertCrc(0xd9963a56, scsiReadCommand);
}
// Known values from http://www.evanjones.ca/crc32c.html
public void testSomeOtherKnownValues() {
assertCrc(0x22620404, "The quick brown fox jumps over the lazy dog".getBytes(UTF_8));
assertCrc(0xE3069283, "123456789".getBytes(UTF_8));
assertCrc(0xf3dbd4fe, "1234567890".getBytes(UTF_8));
assertCrc(0xBFE92A83, "23456789".getBytes(UTF_8));
}
/**
* Verifies that the crc of an array of byte data matches the expected value.
*
* @param expectedCrc the expected crc value.
* @param data the data to run the checksum on.
*/
private static void assertCrc(int expectedCrc, byte[] data) {
int actualCrc = Hashing.crc32c().hashBytes(data).asInt();
assertEquals(expectedCrc, actualCrc);
}
// From RFC 3720, Section 12.1, the polynomial generator is 0x11EDC6F41.
// We calculate the constant below by:
// 1. Omitting the most significant bit (because it's always 1). => 0x1EDC6F41
// 2. Flipping the bits of the constant so we can process a byte at a time. => 0x82F63B78
private static final int CRC32C_GENERATOR = 0x1EDC6F41; // 0x11EDC6F41
private static final int CRC32C_GENERATOR_FLIPPED = Integer.reverse(CRC32C_GENERATOR);
public void testCrc32cLookupTable() {
// See Hacker's Delight 2nd Edition, Figure 14-7.
int[] expected = new int[256];
for (int i = 0; i < expected.length; i++) {
int crc = i;
for (int j = 7; j >= 0; j--) {
int mask = -(crc & 1);
crc = ((crc >>> 1) ^ (CRC32C_GENERATOR_FLIPPED & mask));
}
expected[i] = crc;
}
int[] actual = Crc32cHashFunction.Crc32cHasher.CRC_TABLE;
assertTrue(
"Expected: \n" + Arrays.toString(expected) + "\nActual:\n" + Arrays.toString(actual),
Arrays.equals(expected, actual));
}
}