1 /*
   2  * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 /**
  24  * @test @summary Check that CRC-32C returns the expected CRC value for the
  25  * string 123456789
  26  * http://reveng.sourceforge.net/crc-catalogue/all.htm#crc.cat.crc-32c
  27  */
  28 import java.nio.ByteBuffer;
  29 import java.nio.ByteOrder;
  30 import java.nio.charset.StandardCharsets;
  31 import java.util.zip.CRC32C;
  32 
  33 public class CheckCRC32C {
  34 
  35     private final static byte[] BYTES_123456789 = "123456789".getBytes(StandardCharsets.US_ASCII);
  36     private final static long EXPECTED_CRC = 0xE3069283L;
  37 
  38     public static void main(String[] args) {
  39         testBytes();
  40         testByteArray();
  41         testByteBuffer();
  42         testDirectByteBuffer();
  43         testByteArrayOffset();
  44         testDirectByteBufferOffset();
  45         testLittleEndianDirectByteBufferOffset();
  46         testWrappedByteBufferOffset();
  47         testLittleEndianWrappedByteBufferOffset();
  48     }
  49 
  50     private static void testBytes() {
  51         CRC32C crc32c = new CRC32C();
  52         for (byte bits : BYTES_123456789) {
  53             crc32c.update(bits);
  54         }
  55         checkChecksum(crc32c);
  56     }
  57 
  58     private static void testByteArray() {
  59         CRC32C crc32c = new CRC32C();
  60         crc32c.update(BYTES_123456789);
  61         checkChecksum(crc32c);
  62     }
  63 
  64     private static void testByteBuffer() {
  65         CRC32C crc32c = new CRC32C();
  66         ByteBuffer bb = ByteBuffer.wrap(BYTES_123456789);
  67         crc32c.update(bb);
  68         checkChecksum(crc32c);
  69     }
  70 
  71     private static void testDirectByteBuffer() {
  72         CRC32C crc32c = new CRC32C();
  73         ByteBuffer bb = ByteBuffer.allocateDirect(BYTES_123456789.length);
  74         bb.put(BYTES_123456789);
  75         bb.rewind();
  76         crc32c.update(bb);
  77         checkChecksum(crc32c);
  78     }
  79 
  80     private static void checkChecksum(CRC32C crc) {
  81         if (crc.getValue() != EXPECTED_CRC) {
  82             throw new RuntimeException("Calculated CRC32C result was invalid."
  83                     + " Expected " + Long.toHexString(EXPECTED_CRC)
  84                     + ", but got " + Long.toHexString(crc.getValue()) + ".");
  85         }
  86     }
  87 
  88     private static void testByteArrayOffset() {
  89         byte[] unaligned_bytes_123456789 = new byte[BYTES_123456789.length + 64];
  90         for (int i = 0; i < unaligned_bytes_123456789.length - BYTES_123456789.length; i++) {
  91             CRC32C crc = new CRC32C();
  92             System.arraycopy(BYTES_123456789, 0, unaligned_bytes_123456789, i, BYTES_123456789.length);
  93             crc.update(unaligned_bytes_123456789, i, BYTES_123456789.length);
  94             if (crc.getValue() != EXPECTED_CRC) {
  95                 throw new RuntimeException("Calculated CRC32C result was invalid. Array offset "
  96                         + i + ". Expected: " + Long.toHexString(EXPECTED_CRC) + ", Got: "
  97                         + Long.toHexString(crc.getValue()));
  98             }
  99         }
 100     }
 101 
 102     private static void testDirectByteBufferOffset() {
 103         byte[] unaligned_bytes_123456789 = new byte[BYTES_123456789.length + 64];
 104         for (int i = 0; i < unaligned_bytes_123456789.length - BYTES_123456789.length; i++) {
 105             CRC32C crc = new CRC32C();
 106             ByteBuffer bb = ByteBuffer.allocateDirect(unaligned_bytes_123456789.length);
 107             System.arraycopy(BYTES_123456789, 0, unaligned_bytes_123456789, i, BYTES_123456789.length);
 108             bb.put(unaligned_bytes_123456789);
 109             bb.position(i);
 110             bb.limit(i + BYTES_123456789.length);
 111             crc.update(bb);
 112             if (crc.getValue() != EXPECTED_CRC) {
 113                 throw new RuntimeException("Calculated CRC32C result was invalid. Array offset "
 114                         + i + ". Expected: " + Long.toHexString(EXPECTED_CRC) + ", Got: "
 115                         + Long.toHexString(crc.getValue()));
 116             }
 117         }
 118     }
 119 
 120     private static void testLittleEndianDirectByteBufferOffset() {
 121         byte[] unaligned_bytes_123456789 = new byte[BYTES_123456789.length + 64];
 122         for (int i = 0; i < unaligned_bytes_123456789.length - BYTES_123456789.length; i++) {
 123             CRC32C crc = new CRC32C();
 124             ByteBuffer bb = ByteBuffer.allocateDirect(unaligned_bytes_123456789.length);
 125             bb.order(ByteOrder.LITTLE_ENDIAN);
 126             System.arraycopy(BYTES_123456789, 0, unaligned_bytes_123456789, i, BYTES_123456789.length);
 127             bb.put(unaligned_bytes_123456789);
 128             bb.position(i);
 129             bb.limit(i + BYTES_123456789.length);
 130             crc.update(bb);
 131             if (crc.getValue() != EXPECTED_CRC) {
 132                 throw new RuntimeException("Calculated CRC32C result was invalid. Array offset "
 133                         + i + ". Expected: " + Long.toHexString(EXPECTED_CRC) + ", Got: "
 134                         + Long.toHexString(crc.getValue()));
 135             }
 136         }
 137     }
 138 
 139     private static void testWrappedByteBufferOffset() {
 140         byte[] unaligned_bytes_123456789 = new byte[BYTES_123456789.length + 64];
 141         for (int i = 0; i < unaligned_bytes_123456789.length - BYTES_123456789.length; i++) {
 142             CRC32C crc = new CRC32C();
 143             System.arraycopy(BYTES_123456789, 0, unaligned_bytes_123456789, i, BYTES_123456789.length);
 144             ByteBuffer bb = ByteBuffer.wrap(unaligned_bytes_123456789);
 145             bb.position(i);
 146             bb.limit(i + BYTES_123456789.length);
 147             crc.update(bb);
 148             if (crc.getValue() != EXPECTED_CRC) {
 149                 throw new RuntimeException("Calculated CRC32C result was invalid. Array offset "
 150                         + i + ". Expected: " + Long.toHexString(EXPECTED_CRC) + ", Got: "
 151                         + Long.toHexString(crc.getValue()));
 152             }
 153         }
 154     }
 155 
 156     private static void testLittleEndianWrappedByteBufferOffset() {
 157         byte[] unaligned_bytes_123456789 = new byte[BYTES_123456789.length + 64];
 158         for (int i = 0; i < unaligned_bytes_123456789.length - BYTES_123456789.length; i++) {
 159             CRC32C crc = new CRC32C();
 160             System.arraycopy(BYTES_123456789, 0, unaligned_bytes_123456789, i, BYTES_123456789.length);
 161             ByteBuffer bb = ByteBuffer.wrap(unaligned_bytes_123456789);
 162             bb.order(ByteOrder.LITTLE_ENDIAN);
 163             bb.position(i);
 164             bb.limit(i + BYTES_123456789.length);
 165             crc.update(bb);
 166             if (crc.getValue() != EXPECTED_CRC) {
 167                 throw new RuntimeException("Calculated CRC32C result was invalid. Array offset "
 168                         + i + ". Expected: " + Long.toHexString(EXPECTED_CRC) + ", Got: "
 169                         + Long.toHexString(crc.getValue()));
 170             }
 171         }
 172     }
 173 }