mirror of
https://github.com/AppleCommander/ShrinkItArchive.git
synced 2025-01-03 01:30:42 +00:00
Add CRC16.
This commit is contained in:
parent
68a5b3a5f5
commit
c0c6a6a55a
91
src/com/webcodepro/shrinkit/CRC16.java
Normal file
91
src/com/webcodepro/shrinkit/CRC16.java
Normal file
@ -0,0 +1,91 @@
|
||||
package com.webcodepro.shrinkit;
|
||||
|
||||
import java.util.zip.Checksum;
|
||||
|
||||
/**
|
||||
* Crc16: Calculate 16-bit Cyclic Redundancy Check.
|
||||
* License: GPL, incorporated by reference.
|
||||
*
|
||||
* @author John B. Matthews
|
||||
*/
|
||||
public class CRC16 implements Checksum {
|
||||
|
||||
/** CCITT polynomial: x^16 + x^12 + x^5 + 1 -> 0x1021 (1000000100001) */
|
||||
private static final int poly = 0x1021;
|
||||
private static final int[] table = new int[256];
|
||||
private int value = 0;
|
||||
|
||||
static { // initialize static lookup table
|
||||
for (int i = 0; i < 256; i++) {
|
||||
int crc = i << 8;
|
||||
for (int j = 0; j < 8; j++) {
|
||||
if ((crc & 0x8000) == 0x8000) {
|
||||
crc = (crc << 1) ^ poly;
|
||||
} else {
|
||||
crc = (crc << 1);
|
||||
}
|
||||
}
|
||||
table[i] = crc & 0xffff;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update 16-bit CRC.
|
||||
*
|
||||
* @param crc starting CRC value
|
||||
* @param bytes input byte array
|
||||
* @param off start offset to data
|
||||
* @param len number of bytes to process
|
||||
* @return 16-bit unsigned CRC
|
||||
*/
|
||||
private int update(int crc, byte[] bytes, int off, int len) {
|
||||
for (int i = off; i < (off + len); i++) {
|
||||
byte b = bytes[i];
|
||||
crc = (table[((crc >> 8) & 0xff) ^ b] ^ (crc << 8)) & 0xffff;
|
||||
}
|
||||
return crc;
|
||||
}
|
||||
|
||||
public static int[] getTable() {
|
||||
return table;
|
||||
}
|
||||
|
||||
public long getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
value = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update 16-bit CRC.
|
||||
*
|
||||
* @param b input byte
|
||||
*/
|
||||
public void update(int b) {
|
||||
byte[] ba = { (byte) b };
|
||||
value = update(value, ba, 0, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update 16-bit CRC.
|
||||
*
|
||||
* @param b input byte array
|
||||
*/
|
||||
public void update(byte[] b) {
|
||||
value = update(value, b, 0, b.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update 16-bit CRC.
|
||||
*
|
||||
* @param b input byte array
|
||||
* @param off starting offset to data
|
||||
* @param len number of bytes to process
|
||||
*/
|
||||
public void update(byte[] b, int off, int len) {
|
||||
value = update(value, b, off, len);
|
||||
}
|
||||
|
||||
}
|
33
test_src/com/webcodepro/shrinkit/CRC16Test.java
Normal file
33
test_src/com/webcodepro/shrinkit/CRC16Test.java
Normal file
@ -0,0 +1,33 @@
|
||||
package com.webcodepro.shrinkit;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class CRC16Test extends TestCase {
|
||||
|
||||
public void testTable() {
|
||||
int[] table = CRC16.getTable();
|
||||
assertEquals(0, table[0]);
|
||||
assertEquals(0x1ef0, table[0xff]);
|
||||
System.out.println("CRC16 lookup table:");
|
||||
for (int i = 0; i < 256; i++) {
|
||||
System.out.print(Integer.toHexString(table[i]) + " ");
|
||||
if ((i + 1) % 8 == 0) System.out.println();
|
||||
}
|
||||
}
|
||||
|
||||
public void testUpdate() throws UnsupportedEncodingException {
|
||||
CRC16 crc16 = new CRC16();
|
||||
crc16.update("123456789".getBytes("UTF-8"));
|
||||
assertEquals(0x31c3, crc16.getValue());
|
||||
crc16.update("ABCDEFGHIJKLMNOPQRSTUVWXYZ".getBytes("UTF-8"));
|
||||
assertEquals(0x92cc, crc16.getValue());
|
||||
crc16.update("abcdefghijklmnopqrstuvwxyz".getBytes("UTF-8"));
|
||||
assertEquals(0xfc85, crc16.getValue());
|
||||
crc16.reset();
|
||||
crc16.update("xxx123456789xxx".getBytes("UTF-8"), 3, 9);
|
||||
assertEquals(0x31c3, crc16.getValue());
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user