Home | History | Annotate | Download | only in hash
      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 
     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 
     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 
     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 
     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 
     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
     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    */
     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 
    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