add crc16

This commit is contained in:
Looly 2020-07-22 09:10:35 +08:00
parent b58f98eb95
commit 62a02fb265
8 changed files with 95 additions and 16 deletions

View File

@ -9,6 +9,7 @@
* 【db 】 增加DbUtil.setReturnGeneratedKeyGlobalissue#I1NM0K@Gitee * 【db 】 增加DbUtil.setReturnGeneratedKeyGlobalissue#I1NM0K@Gitee
* 【core 】 增加DataSize和DataSizeUtilissue#967@Github * 【core 】 增加DataSize和DataSizeUtilissue#967@Github
* 【core 】 ImgUtil增加异常避免空指针issue#I1NKXG@Gitee * 【core 】 ImgUtil增加异常避免空指针issue#I1NKXG@Gitee
* 【core 】 增加CRC16算法若干pr#963@Github
### Bug修复 ### Bug修复
* 【core 】 修复ZipUtil中finish位于循环内的问题issue#961@Github * 【core 】 修复ZipUtil中finish位于循环内的问题issue#961@Github

View File

@ -0,0 +1,32 @@
package cn.hutool.core.io.checksum.crc16;
/**
* CRC16_ANSI
*
* @author looly
* @since 5.3.10
*/
public class CRC16Ansi extends CRC16Checksum{
private static final int wCPoly = 0xa001;
@Override
public void reset() {
this.wCRCin = 0xffff;
}
@Override
public void update(int b) {
int hi = wCRCin >> 8;
hi ^= b;
wCRCin = hi;
for (int i = 0; i < 8; i++) {
int flag = wCRCin & 0x0001;
wCRCin = wCRCin >> 1;
if (flag == 1) {
wCRCin ^= wCPoly;
}
}
}
}

View File

@ -10,7 +10,8 @@ public class CRC16CCITTFalse extends CRC16Checksum{
private static final int wCPoly = 0x1021; private static final int wCPoly = 0x1021;
public CRC16CCITTFalse(){ @Override
public void reset() {
this.wCRCin = 0xffff; this.wCRCin = 0xffff;
} }

View File

@ -1,5 +1,8 @@
package cn.hutool.core.io.checksum.crc16; package cn.hutool.core.io.checksum.crc16;
import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.StrUtil;
import java.io.Serializable; import java.io.Serializable;
import java.util.zip.Checksum; import java.util.zip.Checksum;
@ -16,13 +19,40 @@ public abstract class CRC16Checksum implements Checksum, Serializable {
/** /**
* CRC16 Checksum 结果值 * CRC16 Checksum 结果值
*/ */
protected int wCRCin = 0x0000; protected int wCRCin;
public CRC16Checksum(){
reset();
}
@Override @Override
public long getValue() { public long getValue() {
return wCRCin; return wCRCin;
} }
/**
* 获取16进制的CRC16值
*
* @return 16进制的CRC16值
*/
public String getHexValue(){
return getHexValue(false);
}
/**
* 获取16进制的CRC16值
* @param isPadding 不足4位时是否填充0以满足位数
* @return 16进制的CRC16值4位
*/
public String getHexValue(boolean isPadding){
String hex = HexUtil.toHex(getValue());
if(isPadding){
hex = StrUtil.padAfter(hex, 4, '0');
}
return hex;
}
@Override @Override
public void reset() { public void reset() {
wCRCin = 0x0000; wCRCin = 0x0000;

View File

@ -12,13 +12,14 @@ public class CRC16Modbus extends CRC16Checksum{
private static final int wCPoly = 0xa001; private static final int wCPoly = 0xa001;
public CRC16Modbus(){ @Override
public void reset(){
this.wCRCin = 0xffff; this.wCRCin = 0xffff;
} }
@Override @Override
public void update(int b) { public void update(int b) {
wCRCin ^= ((int) b & 0x00ff); wCRCin ^= (b & 0x00ff);
for (int j = 0; j < 8; j++) { for (int j = 0; j < 8; j++) {
if ((wCRCin & 0x0001) != 0) { if ((wCRCin & 0x0001) != 0) {
wCRCin >>= 1; wCRCin >>= 1;

View File

@ -11,7 +11,8 @@ public class CRC16USB extends CRC16Checksum{
private static final int wCPoly = 0xa001; private static final int wCPoly = 0xa001;
public CRC16USB(){ @Override
public void reset(){
this.wCRCin = 0xFFFF; this.wCRCin = 0xFFFF;
} }

View File

@ -11,7 +11,8 @@ public class CRC16X25 extends CRC16Checksum{
private static final int wCPoly = 0x8408; private static final int wCPoly = 0x8408;
public CRC16X25(){ @Override
public void reset(){
this.wCRCin = 0xffff; this.wCRCin = 0xffff;
} }

View File

@ -1,5 +1,6 @@
package cn.hutool.core.io.checksum; package cn.hutool.core.io.checksum;
import cn.hutool.core.io.checksum.crc16.CRC16Ansi;
import cn.hutool.core.io.checksum.crc16.CRC16CCITT; import cn.hutool.core.io.checksum.crc16.CRC16CCITT;
import cn.hutool.core.io.checksum.crc16.CRC16CCITTFalse; import cn.hutool.core.io.checksum.crc16.CRC16CCITTFalse;
import cn.hutool.core.io.checksum.crc16.CRC16DNP; import cn.hutool.core.io.checksum.crc16.CRC16DNP;
@ -9,7 +10,6 @@ import cn.hutool.core.io.checksum.crc16.CRC16Modbus;
import cn.hutool.core.io.checksum.crc16.CRC16USB; import cn.hutool.core.io.checksum.crc16.CRC16USB;
import cn.hutool.core.io.checksum.crc16.CRC16X25; import cn.hutool.core.io.checksum.crc16.CRC16X25;
import cn.hutool.core.io.checksum.crc16.CRC16XModem; import cn.hutool.core.io.checksum.crc16.CRC16XModem;
import cn.hutool.core.util.HexUtil;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
@ -21,62 +21,74 @@ public class CRC16Test {
public void ccittTest(){ public void ccittTest(){
final CRC16CCITT crc16 = new CRC16CCITT(); final CRC16CCITT crc16 = new CRC16CCITT();
crc16.update(data.getBytes()); crc16.update(data.getBytes());
Assert.assertEquals("c852", HexUtil.toHex(crc16.getValue())); Assert.assertEquals("c852", crc16.getHexValue());
} }
@Test @Test
public void ccittFalseTest(){ public void ccittFalseTest(){
final CRC16CCITTFalse crc16 = new CRC16CCITTFalse(); final CRC16CCITTFalse crc16 = new CRC16CCITTFalse();
crc16.update(data.getBytes()); crc16.update(data.getBytes());
Assert.assertEquals("a5e4", HexUtil.toHex(crc16.getValue())); Assert.assertEquals("a5e4", crc16.getHexValue());
} }
@Test @Test
public void xmodemTest(){ public void xmodemTest(){
final CRC16XModem crc16 = new CRC16XModem(); final CRC16XModem crc16 = new CRC16XModem();
crc16.update(data.getBytes()); crc16.update(data.getBytes());
Assert.assertEquals("5a8d", HexUtil.toHex(crc16.getValue())); Assert.assertEquals("5a8d", crc16.getHexValue());
} }
@Test @Test
public void x25Test(){ public void x25Test(){
final CRC16X25 crc16 = new CRC16X25(); final CRC16X25 crc16 = new CRC16X25();
crc16.update(data.getBytes()); crc16.update(data.getBytes());
Assert.assertEquals("a152", HexUtil.toHex(crc16.getValue())); Assert.assertEquals("a152", crc16.getHexValue());
} }
@Test @Test
public void modbusTest(){ public void modbusTest(){
final CRC16Modbus crc16 = new CRC16Modbus(); final CRC16Modbus crc16 = new CRC16Modbus();
crc16.update(data.getBytes()); crc16.update(data.getBytes());
Assert.assertEquals("25fb", HexUtil.toHex(crc16.getValue())); Assert.assertEquals("25fb", crc16.getHexValue());
} }
@Test @Test
public void ibmTest(){ public void ibmTest(){
final CRC16IBM crc16 = new CRC16IBM(); final CRC16IBM crc16 = new CRC16IBM();
crc16.update(data.getBytes()); crc16.update(data.getBytes());
Assert.assertEquals("18c", HexUtil.toHex(crc16.getValue())); Assert.assertEquals("18c", crc16.getHexValue());
} }
@Test @Test
public void maximTest(){ public void maximTest(){
final CRC16Maxim crc16 = new CRC16Maxim(); final CRC16Maxim crc16 = new CRC16Maxim();
crc16.update(data.getBytes()); crc16.update(data.getBytes());
Assert.assertEquals("fe73", HexUtil.toHex(crc16.getValue())); Assert.assertEquals("fe73", crc16.getHexValue());
} }
@Test @Test
public void usbTest(){ public void usbTest(){
final CRC16USB crc16 = new CRC16USB(); final CRC16USB crc16 = new CRC16USB();
crc16.update(data.getBytes()); crc16.update(data.getBytes());
Assert.assertEquals("da04", HexUtil.toHex(crc16.getValue())); Assert.assertEquals("da04", crc16.getHexValue());
} }
@Test @Test
public void dnpTest(){ public void dnpTest(){
final CRC16DNP crc16 = new CRC16DNP(); final CRC16DNP crc16 = new CRC16DNP();
crc16.update(data.getBytes()); crc16.update(data.getBytes());
Assert.assertEquals("3d1a", HexUtil.toHex(crc16.getValue())); Assert.assertEquals("3d1a", crc16.getHexValue());
}
@Test
public void ansiTest(){
final CRC16Ansi crc16 = new CRC16Ansi();
crc16.update(data.getBytes());
Assert.assertEquals("1e00", crc16.getHexValue());
crc16.reset();
String str2 = "QN=20160801085857223;ST=32;CN=1062;PW=100000;MN=010000A8900016F000169DC0;Flag=5;CP=&&RtdInterval=30&&";
crc16.update(str2.getBytes());
Assert.assertEquals("1c80", crc16.getHexValue());
} }
} }