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 junit.framework.TestCase; 20 21 import java.util.Arrays; 22 23 /** 24 * Unit tests for {@link Crc32c}. Known test values are from RFC 3720, Section B.4. 25 * 26 * @author Patrick Costello 27 * @author Kurt Alfred Kluever 28 */ 29 public class Crc32cHashFunctionTest extends TestCase { 30 testZeros()31 public void testZeros() { 32 // Test 32 byte array of 0x00. 33 byte[] zeros = new byte[32]; 34 Arrays.fill(zeros, (byte) 0x00); 35 assertCrc(0x8a9136aa, zeros); 36 } 37 testFull()38 public void testFull() { 39 // Test 32 byte array of 0xFF. 40 byte[] fulls = new byte[32]; 41 Arrays.fill(fulls, (byte) 0xFF); 42 assertCrc(0x62a8ab43, fulls); 43 } 44 testAscending()45 public void testAscending() { 46 // Test 32 byte arrays of ascending. 47 byte[] ascending = new byte[32]; 48 for (int i = 0; i < 32; i++) { 49 ascending[i] = (byte) i; 50 } 51 assertCrc(0x46dd794e, ascending); 52 } 53 testDescending()54 public void testDescending() { 55 // Test 32 byte arrays of descending. 56 byte[] descending = new byte[32]; 57 for (int i = 0; i < 32; i++) { 58 descending[i] = (byte) (31 - i); 59 } 60 assertCrc(0x113fdb5c, descending); 61 } 62 testScsiReadCommad()63 public void testScsiReadCommad() { 64 // Test SCSI read command. 65 byte[] scsiReadCommand = 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 assertCrc(0xd9963a56, scsiReadCommand); 79 } 80 81 // Known values from http://www.evanjones.ca/crc32c.html testSomeOtherKnownValues()82 public void testSomeOtherKnownValues() { 83 assertCrc(0x22620404, "The quick brown fox jumps over the lazy dog".getBytes(UTF_8)); 84 assertCrc(0xE3069283, "123456789".getBytes(UTF_8)); 85 assertCrc(0xf3dbd4fe, "1234567890".getBytes(UTF_8)); 86 assertCrc(0xBFE92A83, "23456789".getBytes(UTF_8)); 87 } 88 89 /** 90 * Verfies that the crc of an array of byte data matches the expected value. 91 * 92 * @param expectedCrc the expected crc value. 93 * @param data the data to run the checksum on. 94 */ assertCrc(int expectedCrc, byte[] data)95 private static void assertCrc(int expectedCrc, byte[] data) { 96 int actualCrc = Hashing.crc32c().hashBytes(data).asInt(); 97 assertEquals(expectedCrc, actualCrc); 98 } 99 100 // From RFC 3720, Section 12.1, the polynomial generator is 0x11EDC6F41. 101 // We calculate the constant below by: 102 // 1. Omitting the most significant bit (because it's always 1). => 0x1EDC6F41 103 // 2. Flipping the bits of the constant so we can process a byte at a time. => 0x82F63B78 104 private static final int CRC32C_GENERATOR = 0x1EDC6F41; // 0x11EDC6F41 105 private static final int CRC32C_GENERATOR_FLIPPED = Integer.reverse(CRC32C_GENERATOR); 106 testCrc32cLookupTable()107 public void testCrc32cLookupTable() { 108 // See Hacker's Delight 2nd Edition, Figure 14-7. 109 int[] expected = new int[256]; 110 for (int i = 0; i < expected.length; i++) { 111 int crc = i; 112 for (int j = 7; j >= 0; j--) { 113 int mask = -(crc & 1); 114 crc = ((crc >>> 1) ^ (CRC32C_GENERATOR_FLIPPED & mask)); 115 } 116 expected[i] = crc; 117 } 118 119 int[] actual = Crc32cHashFunction.Crc32cHasher.CRC_TABLE; 120 assertTrue( 121 "Expected: \n" + Arrays.toString(expected) + "\nActual:\n" + Arrays.toString(actual), 122 Arrays.equals(expected, actual)); 123 } 124 } 125