content: /*******************************************************************************
   * Copyright 2014 Trevor Robinson
   * 
   * 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.scurrilous.circe.crc;
  
  import static com.scurrilous.circe.params.CrcParameters.CRC16;
  import static com.scurrilous.circe.params.CrcParameters.CRC16_CCITT;
  import static com.scurrilous.circe.params.CrcParameters.CRC16_XMODEM;
  import static com.scurrilous.circe.params.CrcParameters.CRC32;
  import static com.scurrilous.circe.params.CrcParameters.CRC32C;
  import static com.scurrilous.circe.params.CrcParameters.CRC32_BZIP2;
  import static com.scurrilous.circe.params.CrcParameters.CRC32_POSIX;
  import static com.scurrilous.circe.params.CrcParameters.CRC64;
  import static com.scurrilous.circe.params.CrcParameters.CRC64_XZ;
  import static org.junit.Assert.assertEquals;
  
  import com.scurrilous.circe.IncrementalLongHash;
  import com.scurrilous.circe.HashProvider;
  import com.scurrilous.circe.IncrementalIntHash;
  import com.scurrilous.circe.params.CrcParameters;
  import java.nio.charset.Charset;
  import org.junit.Test;
  
  /**
   * Tests the {@link StandardCrcProvider} with various CRC algorithms. See the <a
   * href="http://reveng.sourceforge.net/crc-catalogue/">Catalogue of parametrised
   * CRC algorithms</a> for more information on these algorithms and others.
   */
  @SuppressWarnings("javadoc")
  public class CRCTest {
  
      private static final HashProvider PROVIDER = new StandardCrcProvider();
      private static final Charset ASCII = Charset.forName("ASCII");
      private static final byte[] DIGITS = "123456789".getBytes(ASCII);
  
      @Test
      public void testCRC3_ROHC() {
          final CrcParameters CRC3_ROHC = new CrcParameters("CRC-3/ROHC", 3, 0x3, 0x7, 0, true);
          assertEquals(0x6, PROVIDER.getIncrementalInt(CRC3_ROHC).calculate(DIGITS));
      }
  
      @Test
      public void testCRC5_EPC() {
          final CrcParameters CRC5_EPC = new CrcParameters("CRC-5/EPC", 5, 0x09, 0x09, 0, false);
          assertEquals(0x00, PROVIDER.getIncrementalInt(CRC5_EPC).calculate(DIGITS));
      }
  
      @Test
      public void testCRC5_USB() {
          final CrcParameters CRC5_USB = new CrcParameters("CRC-5/USB", 5, 0x05, 0x1f, 0x1f, true);
          assertEquals(0x19, PROVIDER.getIncrementalInt(CRC5_USB).calculate(DIGITS));
      }
  
      @Test
      public void testCRC7() {
          final CrcParameters CRC7 = new CrcParameters("CRC-7", 7, 0x09, 0, 0, false);
          assertEquals(0x75, PROVIDER.getIncrementalInt(CRC7).calculate(DIGITS));
      }
  
      @Test
      public void testCRC7ROHC() {
          final CrcParameters CRC7_ROHC = new CrcParameters("CRC-7/ROHC", 7, 0x4f, 0x7f, 0, true);
          assertEquals(0x53, PROVIDER.getIncrementalInt(CRC7_ROHC).calculate(DIGITS));
      }
  
      @Test
      public void testCRC8() {
          final CrcParameters CRC8 = new CrcParameters("CRC-8", 8, 0x07, 0, 0, false);
          assertEquals(0xf4, PROVIDER.getIncrementalInt(CRC8).calculate(DIGITS));
      }
  
      @Test
      public void testCRC10() {
          final CrcParameters CRC10 = new CrcParameters("CRC-10", 10, 0x233, 0, 0, false);
          assertEquals(0x199, PROVIDER.getIncrementalInt(CRC10).calculate(DIGITS));
      }
  
      @Test
      public void testCRC15() {
          final CrcParameters CRC15 = new CrcParameters("CRC-15", 15, 0x4599, 0, 0, false);
          assertEquals(0x059e, PROVIDER.getIncrementalInt(CRC15).calculate(DIGITS));
      }
  
      @Test
      public void testCRC16() {
          assertEquals(0xbb3d, PROVIDER.getIncrementalInt(CRC16).calculate(DIGITS));
      }
  
      @Test
      public void testCRC16_CCITT() {
          assertEquals(0x2189, PROVIDER.getIncrementalInt(CRC16_CCITT).calculate(DIGITS));
      }
  
      @Test
      public void testXMODEM() {
          assertEquals(0x31c3, PROVIDER.getIncrementalInt(CRC16_XMODEM).calculate(DIGITS));
      }
  
      @Test
      public void testCRC24() {
          final CrcParameters CRC24 = new CrcParameters("CRC-24", 24, 0x864cfb, 0xb704ce, 0, false);
          assertEquals(0x21cf02, PROVIDER.getIncrementalInt(CRC24).calculate(DIGITS));
      }
  
      @Test
      public void testCRC32() {
          assertEquals(0xcbf43926, PROVIDER.getIncrementalInt(CRC32).calculate(DIGITS));
      }
  
      @Test
      public void testJavaCRC32() {
          assertEquals(0xcbf43926, PROVIDER.getStatelessInt(CRC32).calculate(DIGITS));
      }
  
      @Test
      public void testBZIP2() {
          assertEquals(0xfc891918, PROVIDER.getIncrementalInt(CRC32_BZIP2).calculate(DIGITS));
      }
  
      @Test
      public void testCRC32C() {
          assertEquals(0xe3069283, PROVIDER.getIncrementalInt(CRC32C).calculate(DIGITS));
      }
  
      @Test
      public void testCRC32D() {
          final CrcParameters CRC32D = new CrcParameters("CRC-32D", 32, 0xa833982b, ~0, ~0, true);
          assertEquals(0x87315576, PROVIDER.getIncrementalInt(CRC32D).calculate(DIGITS));
      }
  
      @Test
      public void testPOSIX() {
          assertEquals(0x765e7680, PROVIDER.getIncrementalInt(CRC32_POSIX).calculate(DIGITS));
      }
  
      @Test
      public void testCRC32Q() {
          final CrcParameters CRC32Q = new CrcParameters("CRC-32Q", 32, 0x814141ab, 0, 0, false);
          assertEquals(0x3010bf7f, PROVIDER.getIncrementalInt(CRC32Q).calculate(DIGITS));
      }
  
      @Test
      public void testCRC64() {
          assertEquals(0x6c40df5f0b497347L, PROVIDER.getIncrementalLong(CRC64).calculate(DIGITS));
      }
  
      @Test
      public void testCRC64_XZ() {
          assertEquals(0x995dc9bbdf1939faL, PROVIDER.getIncrementalLong(CRC64_XZ).calculate(DIGITS));
      }
      
      @Test
      public void testCRC32CIncrementalInt() {
          // reflected
          testIncrementalInt(PROVIDER.getIncrementalInt(CRC32C));
      }
  
      private void testIncrementalInt(IncrementalIntHash hash) {
          final String data = "data";
          final String combined = data + data;
  
          final int dataChecksum = hash.calculate(data.getBytes(ASCII));
          final int combinedChecksum = hash.calculate(combined.getBytes(ASCII));
          final int incrementalChecksum = hash.resume(dataChecksum, data.getBytes(ASCII));
          assertEquals(combinedChecksum, incrementalChecksum);
      }
  
      @Test
      public void testCRC32CIncrementalLong() {
          // reflected
          testIncrementalLong(PROVIDER.getIncrementalLong(CRC32C));
      }
  
      private void testIncrementalLong(IncrementalLongHash hash) {
          final String data = "data";
          final String combined = data + data;
  
          final long dataChecksum = hash.calculate(data.getBytes(ASCII));
          final long combinedChecksum = hash.calculate(combined.getBytes(ASCII));
          final long incrementalChecksum = hash.resume(dataChecksum, data.getBytes(ASCII));
          assertEquals(combinedChecksum, incrementalChecksum);
      }
  }
  