| /* |
| * 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)); |
| } |
| } |