Subversion Repositories DevTools

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1695 bivey 1
package com.erggroup.mass.ant.tasks.util;
2
 
3
import java.util.zip.*;
4
 
5
/**
6
 * Checksum calculator for a 16-bit CCITT CRC.
7
 * 
8
 * @author bivey
9
 */
10
public class CCITT implements Checksum
11
{
12
	protected long checksum;
13
	protected long length;
14
	private static final long poly = 0x1021;	// CCITT Generator polynomial (x16 + x12 +x5 +1)
15
	private static long[] table = new long[256]; // Lookup table for fast calculation
16
	static
17
	{
18
		// Initialise the lookup table
19
		long remainder;
20
		for( int dividend = 0; dividend < 256; dividend++ )
21
		{
22
			remainder = (long)dividend;
23
			remainder = reflect(remainder,8);
24
			remainder <<= 8;
25
 
26
			for( int bit = 0; bit < 8; bit++ )
27
			{
28
				if ( (remainder & 0x8000) != 0 )
29
				{
30
					remainder = ( remainder << 1 ) ^ poly;
31
				}
32
				else
33
				{
34
					remainder = ( remainder << 1 );
35
				}
36
			}
37
			remainder = reflect(remainder, 16);
38
			table[dividend] = (remainder & 0xFFFF);
39
		}
40
	}
41
 
42
	public CCITT()
43
	{
44
		reset();
45
	}
46
 
47
	/* Returns the current checksum value.
48
	 * 
49
	 * @see java.util.zip.Checksum#getValue()
50
	 */
51
	public long getValue()
52
	{
53
		return checksum & 0xFFFF;
54
	}
55
 
56
	/**
57
	 * Returns the length of data used in calculating the checksum.
58
	 * 
59
	 * @return data length
60
	 */
61
	public long getLength()
62
	{
63
		return length;
64
	}
65
 
66
	/* Resets the checksum to its initial value.
67
	 * 
68
	 * @see java.util.zip.Checksum#reset()
69
	 */
70
	public void reset()
71
	{
72
		checksum = reflect(0, 16);
73
		length = 0;
74
	}
75
 
76
	/* Updates the current checksum with the specified array of bytes.
77
	 * 
78
	 * @see java.util.zip.Checksum#update(byte[], int, int)
79
	 */
80
	public void update(byte[] b, int off, int len)
81
	{
82
		int count = off + len;
83
		for( int i = off; i < count; i++ )
84
		{
85
			update(b[i]);
86
		}
87
	}
88
 
89
	/* Updates the current checksum with the specified byte.
90
	 * 
91
	 * @see java.util.zip.Checksum#update(int)
92
	 */
93
	public void update(int b)
94
	{
95
		update((byte)(b & 0xFF));
96
	}
97
 
98
	/**
99
	 * Updates the checksum with the specified byte.
100
	 * 
101
	 * @param b The byte
102
	 */
103
	public void update(byte b)
104
	{
105
		int index = ((int)(checksum ^ b) & 0xff);
106
		checksum >>>= 8;
107
		checksum &= 0xFF;
108
		checksum ^= (table[index]);
109
        length++;
110
	}
111
 
112
    /**
113
     * Reflects a value by taking the least significant bits into account
114
     *
115
     * @param value The value which should be reflected
116
     * @param bits The number of bits to be reflected
117
     * @return The value with the bottom bits reflected.
118
     */
119
    private static long reflect(long value, int bits) {
120
        long temp = 0L;
121
        for( int i = 0; i < bits; i++ ) 
122
        {
123
            temp <<= 1L;
124
            temp |= (value & 1L);
125
            value >>>= 1L;
126
        }
127
        return (value << bits) | temp;
128
    }
129
}