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