Blame | Last modification | View Log | RSS feed
package com.erggroup.mass.ant.tasks.util;import java.util.zip.*;/*** Checksum calculator for a 16-bit CCITT CRC.** @author bivey*/public class CCITT implements Checksum{protected long checksum;protected long length;private static final long poly = 0x1021; // CCITT Generator polynomial (x16 + x12 +x5 +1)private static long[] table = new long[256]; // Lookup table for fast calculationstatic{// Initialise the lookup tablelong remainder;for( int dividend = 0; dividend < 256; dividend++ ){remainder = (long)dividend;remainder = reflect(remainder,8);remainder <<= 8;for( int bit = 0; bit < 8; bit++ ){if ( (remainder & 0x8000) != 0 ){remainder = ( remainder << 1 ) ^ poly;}else{remainder = ( remainder << 1 );}}remainder = reflect(remainder, 16);table[dividend] = (remainder & 0xFFFF);}}public CCITT(){reset();}/* Returns the current checksum value.** @see java.util.zip.Checksum#getValue()*/public long getValue(){return checksum & 0xFFFF;}/*** Returns the length of data used in calculating the checksum.** @return data length*/public long getLength(){return length;}/* Resets the checksum to its initial value.** @see java.util.zip.Checksum#reset()*/public void reset(){checksum = reflect(0, 16);length = 0;}/* Updates the current checksum with the specified array of bytes.** @see java.util.zip.Checksum#update(byte[], int, int)*/public void update(byte[] b, int off, int len){int count = off + len;for( int i = off; i < count; i++ ){update(b[i]);}}/* Updates the current checksum with the specified byte.** @see java.util.zip.Checksum#update(int)*/public void update(int b){update((byte)(b & 0xFF));}/*** Updates the checksum with the specified byte.** @param b The byte*/public void update(byte b){int index = ((int)(checksum ^ b) & 0xff);checksum >>>= 8;checksum &= 0xFF;checksum ^= (table[index]);length++;}/*** Reflects a value by taking the least significant bits into account** @param value The value which should be reflected* @param bits The number of bits to be reflected* @return The value with the bottom bits reflected.*/private static long reflect(long value, int bits) {long temp = 0L;for( int i = 0; i < bits; i++ ){temp <<= 1L;temp |= (value & 1L);value >>>= 1L;}return (value << bits) | temp;}}