blob: 10e9cc316662f87bedb5bf3cdb0b377dab5cd842 [file] [log] [blame]
/*******************************************************************************
* 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.params;
import com.scurrilous.circe.HashParameters;
/**
* Hash parameters used to define a <a
* href="http://en.wikipedia.org/wiki/Cyclic_redundancy_check">cyclic redundancy
* check</a> (CRC). Includes some commonly used sets of parameters.
*/
public class CrcParameters implements HashParameters {
private final String name;
private final int bitWidth;
private final long polynomial;
private final long initial;
private final long xorOut;
private final boolean reflected;
/**
* Constructs a {@link CrcParameters} with the given parameters.
*
* @param name the canonical name of the CRC function
* @param bitWidth the width of the CRC function
* @param polynomial the polynomial in binary form (non-reflected)
* @param initial the initial value of the CRC register
* @param xorOut a value XOR'ed with the CRC when it is read
* @param reflected indicates whether the CRC is reflected (LSB-first)
* @throws IllegalArgumentException if the width is less than 1 or greater
* than 64
*/
public CrcParameters(String name, int bitWidth, long polynomial, long initial, long xorOut,
boolean reflected) {
if (bitWidth < 1 || bitWidth > 64)
throw new IllegalArgumentException();
this.name = name;
this.bitWidth = bitWidth;
final long mask = bitWidth < 64 ? (1L << bitWidth) - 1 : ~0L;
this.polynomial = polynomial & mask;
this.initial = initial & mask;
this.xorOut = xorOut & mask;
this.reflected = reflected;
}
@Override
public String algorithm() {
return name;
}
/**
* Returns the width in bits of the CRC function. The width is also the
* position of the implicit set bit at the top of the polynomial.
*
* @return the CRC width in bits
*/
public int bitWidth() {
return bitWidth;
}
/**
* Returns the binary form of polynomial that defines the CRC function (with
* the implicit top bit omitted). For instance, the CRC-16 polynomial
* x<sup>16</sup> + x<sup>15</sup> + x<sup>2</sup> + 1 is represented as
* {@code 1000 0000 0000 0101} ({@code 0x8005}).
*
* @return the CRC polynomial
*/
public long polynomial() {
return polynomial;
}
/**
* Returns the initial value of the CRC register.
*
* @return the CRC initial value
*/
public long initial() {
return initial;
}
/**
* Returns the value XOR'ed with the CRC register when it is read to
* determine the output value.
*
* @return the final XOR value
*/
public long xorOut() {
return xorOut;
}
/**
* Returns whether the CRC function is "reflected". Reflected CRCs process
* data LSB-first, whereas "normal" CRCs are MSB-first.
*
* @return whether the CRC function is reflected
*/
public boolean reflected() {
return reflected;
}
/**
* Returns whether this object matches the given CRC parameters.
*
* @param bitWidth the width of the CRC function
* @param polynomial the polynomial in binary form (non-reflected)
* @param initial the initial value of the CRC register
* @param xorOut a value XOR'ed with the CRC when it is read
* @param reflected indicates whether the CRC is reflected (LSB-first)
* @return true if all parameters match exactly, false otherwise
*/
public boolean match(int bitWidth, long polynomial, long initial, long xorOut, boolean reflected) {
return bitWidth == this.bitWidth && polynomial == this.polynomial &&
initial == this.initial && xorOut == this.xorOut && reflected == this.reflected;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null || getClass() != obj.getClass())
return false;
final CrcParameters other = (CrcParameters) obj;
return bitWidth == other.bitWidth && polynomial == other.polynomial &&
initial == other.initial && xorOut == other.xorOut && reflected == other.reflected;
}
@Override
public int hashCode() {
return (int) (polynomial ^ (polynomial >>> 32) ^ initial ^ (initial >>> 32) ^ xorOut ^ (xorOut >>> 32)) ^
(reflected ? ~0 : 0);
}
/**
* Parameters for CRC-16, used in the ARC and LHA compression utilities.
*/
public static final CrcParameters CRC16 = new CrcParameters("CRC-16", 16, 0x8005, 0, 0, true);
/**
* Parameters for CRC-16/CCITT, used in the Kermit protocol.
*/
public static final CrcParameters CRC16_CCITT = new CrcParameters("CRC-16/CCITT", 16, 0x1021,
0, 0, true);
/**
* Parameters for CRC-16/XMODEM, used in the XMODEM protocol.
*/
public static final CrcParameters CRC16_XMODEM = new CrcParameters("CRC-16/XMODEM", 16, 0x1021,
0, 0, false);
/**
* Parameters for CRC-32, used in Ethernet, SATA, PKZIP, ZMODEM, etc.
*/
public static final CrcParameters CRC32 = new CrcParameters("CRC-32", 32, 0x04c11db7, ~0, ~0,
true);
/**
* Parameters for CRC-32/BZIP2, used in BZIP2.
*/
public static final CrcParameters CRC32_BZIP2 = new CrcParameters("CRC-32/BZIP2", 32,
0x04c11db7, ~0, ~0, false);
/**
* Parameters for CRC-32C, used in iSCSI and SCTP.
*/
public static final CrcParameters CRC32C = new CrcParameters("CRC-32C", 32, 0x1edc6f41, ~0, ~0,
true);
/**
* Parameters for CRC-32/MPEG-2, used in MPEG-2.
*/
public static final CrcParameters CRC32_MPEG2 = new CrcParameters("CRC-32/MPEG-2", 32,
0x04c11db7, ~0, 0, false);
/**
* Parameters for CRC-32/POSIX, used in the {@code cksum} utility.
*/
public static final CrcParameters CRC32_POSIX = new CrcParameters("CRC-32/POSIX", 32,
0x04c11db7, 0, ~0, false);
/**
* Parameters for CRC-64, used in the ECMA-182 standard for DLT-1 tapes.
*/
public static final CrcParameters CRC64 = new CrcParameters("CRC-64", 64, 0x42f0e1eba9ea3693L,
0L, 0L, false);
/**
* Parameters for CRC-64/XZ, used in the {@code .xz} file format.
*/
public static final CrcParameters CRC64_XZ = new CrcParameters("CRC-64/XZ", 64,
0x42f0e1eba9ea3693L, ~0L, ~0L, true);
}