From 62a02fb2659ecce2ad8eebc98c98d29036f9874a Mon Sep 17 00:00:00 2001 From: Looly Date: Wed, 22 Jul 2020 09:10:35 +0800 Subject: [PATCH] add crc16 --- CHANGELOG.md | 1 + .../core/io/checksum/crc16/CRC16Ansi.java | 32 +++++++++++++++++++ .../io/checksum/crc16/CRC16CCITTFalse.java | 3 +- .../core/io/checksum/crc16/CRC16Checksum.java | 32 ++++++++++++++++++- .../core/io/checksum/crc16/CRC16Modbus.java | 5 +-- .../core/io/checksum/crc16/CRC16USB.java | 3 +- .../core/io/checksum/crc16/CRC16X25.java | 3 +- .../cn/hutool/core/io/checksum/CRC16Test.java | 32 +++++++++++++------ 8 files changed, 95 insertions(+), 16 deletions(-) create mode 100644 hutool-core/src/main/java/cn/hutool/core/io/checksum/crc16/CRC16Ansi.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d75ffb76..9b067a1d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ * 【db 】 增加DbUtil.setReturnGeneratedKeyGlobal(issue#I1NM0K@Gitee) * 【core 】 增加DataSize和DataSizeUtil(issue#967@Github) * 【core 】 ImgUtil增加异常,避免空指针(issue#I1NKXG@Gitee) +* 【core 】 增加CRC16算法若干(pr#963@Github) ### Bug修复 * 【core 】 修复ZipUtil中finish位于循环内的问题(issue#961@Github) diff --git a/hutool-core/src/main/java/cn/hutool/core/io/checksum/crc16/CRC16Ansi.java b/hutool-core/src/main/java/cn/hutool/core/io/checksum/crc16/CRC16Ansi.java new file mode 100644 index 000000000..662a8759d --- /dev/null +++ b/hutool-core/src/main/java/cn/hutool/core/io/checksum/crc16/CRC16Ansi.java @@ -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; + } + } + } +} diff --git a/hutool-core/src/main/java/cn/hutool/core/io/checksum/crc16/CRC16CCITTFalse.java b/hutool-core/src/main/java/cn/hutool/core/io/checksum/crc16/CRC16CCITTFalse.java index 7e24206d7..2e8c56b62 100644 --- a/hutool-core/src/main/java/cn/hutool/core/io/checksum/crc16/CRC16CCITTFalse.java +++ b/hutool-core/src/main/java/cn/hutool/core/io/checksum/crc16/CRC16CCITTFalse.java @@ -10,7 +10,8 @@ public class CRC16CCITTFalse extends CRC16Checksum{ private static final int wCPoly = 0x1021; - public CRC16CCITTFalse(){ + @Override + public void reset() { this.wCRCin = 0xffff; } diff --git a/hutool-core/src/main/java/cn/hutool/core/io/checksum/crc16/CRC16Checksum.java b/hutool-core/src/main/java/cn/hutool/core/io/checksum/crc16/CRC16Checksum.java index 5836cf3a4..126747b59 100644 --- a/hutool-core/src/main/java/cn/hutool/core/io/checksum/crc16/CRC16Checksum.java +++ b/hutool-core/src/main/java/cn/hutool/core/io/checksum/crc16/CRC16Checksum.java @@ -1,5 +1,8 @@ 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.util.zip.Checksum; @@ -16,13 +19,40 @@ public abstract class CRC16Checksum implements Checksum, Serializable { /** * CRC16 Checksum 结果值 */ - protected int wCRCin = 0x0000; + protected int wCRCin; + + public CRC16Checksum(){ + reset(); + } @Override public long getValue() { 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 public void reset() { wCRCin = 0x0000; diff --git a/hutool-core/src/main/java/cn/hutool/core/io/checksum/crc16/CRC16Modbus.java b/hutool-core/src/main/java/cn/hutool/core/io/checksum/crc16/CRC16Modbus.java index 5aabdce76..857f3bf16 100644 --- a/hutool-core/src/main/java/cn/hutool/core/io/checksum/crc16/CRC16Modbus.java +++ b/hutool-core/src/main/java/cn/hutool/core/io/checksum/crc16/CRC16Modbus.java @@ -12,13 +12,14 @@ public class CRC16Modbus extends CRC16Checksum{ private static final int wCPoly = 0xa001; - public CRC16Modbus(){ + @Override + public void reset(){ this.wCRCin = 0xffff; } @Override public void update(int b) { - wCRCin ^= ((int) b & 0x00ff); + wCRCin ^= (b & 0x00ff); for (int j = 0; j < 8; j++) { if ((wCRCin & 0x0001) != 0) { wCRCin >>= 1; diff --git a/hutool-core/src/main/java/cn/hutool/core/io/checksum/crc16/CRC16USB.java b/hutool-core/src/main/java/cn/hutool/core/io/checksum/crc16/CRC16USB.java index 1c6265f34..b9f9503c5 100644 --- a/hutool-core/src/main/java/cn/hutool/core/io/checksum/crc16/CRC16USB.java +++ b/hutool-core/src/main/java/cn/hutool/core/io/checksum/crc16/CRC16USB.java @@ -11,7 +11,8 @@ public class CRC16USB extends CRC16Checksum{ private static final int wCPoly = 0xa001; - public CRC16USB(){ + @Override + public void reset(){ this.wCRCin = 0xFFFF; } diff --git a/hutool-core/src/main/java/cn/hutool/core/io/checksum/crc16/CRC16X25.java b/hutool-core/src/main/java/cn/hutool/core/io/checksum/crc16/CRC16X25.java index 7bf7ff7c6..5c938852d 100644 --- a/hutool-core/src/main/java/cn/hutool/core/io/checksum/crc16/CRC16X25.java +++ b/hutool-core/src/main/java/cn/hutool/core/io/checksum/crc16/CRC16X25.java @@ -11,7 +11,8 @@ public class CRC16X25 extends CRC16Checksum{ private static final int wCPoly = 0x8408; - public CRC16X25(){ + @Override + public void reset(){ this.wCRCin = 0xffff; } diff --git a/hutool-core/src/test/java/cn/hutool/core/io/checksum/CRC16Test.java b/hutool-core/src/test/java/cn/hutool/core/io/checksum/CRC16Test.java index b2dc624b9..71f77437a 100644 --- a/hutool-core/src/test/java/cn/hutool/core/io/checksum/CRC16Test.java +++ b/hutool-core/src/test/java/cn/hutool/core/io/checksum/CRC16Test.java @@ -1,5 +1,6 @@ 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.CRC16CCITTFalse; 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.CRC16X25; import cn.hutool.core.io.checksum.crc16.CRC16XModem; -import cn.hutool.core.util.HexUtil; import org.junit.Assert; import org.junit.Test; @@ -21,62 +21,74 @@ public class CRC16Test { public void ccittTest(){ final CRC16CCITT crc16 = new CRC16CCITT(); crc16.update(data.getBytes()); - Assert.assertEquals("c852", HexUtil.toHex(crc16.getValue())); + Assert.assertEquals("c852", crc16.getHexValue()); } @Test public void ccittFalseTest(){ final CRC16CCITTFalse crc16 = new CRC16CCITTFalse(); crc16.update(data.getBytes()); - Assert.assertEquals("a5e4", HexUtil.toHex(crc16.getValue())); + Assert.assertEquals("a5e4", crc16.getHexValue()); } @Test public void xmodemTest(){ final CRC16XModem crc16 = new CRC16XModem(); crc16.update(data.getBytes()); - Assert.assertEquals("5a8d", HexUtil.toHex(crc16.getValue())); + Assert.assertEquals("5a8d", crc16.getHexValue()); } @Test public void x25Test(){ final CRC16X25 crc16 = new CRC16X25(); crc16.update(data.getBytes()); - Assert.assertEquals("a152", HexUtil.toHex(crc16.getValue())); + Assert.assertEquals("a152", crc16.getHexValue()); } @Test public void modbusTest(){ final CRC16Modbus crc16 = new CRC16Modbus(); crc16.update(data.getBytes()); - Assert.assertEquals("25fb", HexUtil.toHex(crc16.getValue())); + Assert.assertEquals("25fb", crc16.getHexValue()); } @Test public void ibmTest(){ final CRC16IBM crc16 = new CRC16IBM(); crc16.update(data.getBytes()); - Assert.assertEquals("18c", HexUtil.toHex(crc16.getValue())); + Assert.assertEquals("18c", crc16.getHexValue()); } @Test public void maximTest(){ final CRC16Maxim crc16 = new CRC16Maxim(); crc16.update(data.getBytes()); - Assert.assertEquals("fe73", HexUtil.toHex(crc16.getValue())); + Assert.assertEquals("fe73", crc16.getHexValue()); } @Test public void usbTest(){ final CRC16USB crc16 = new CRC16USB(); crc16.update(data.getBytes()); - Assert.assertEquals("da04", HexUtil.toHex(crc16.getValue())); + Assert.assertEquals("da04", crc16.getHexValue()); } @Test public void dnpTest(){ final CRC16DNP crc16 = new CRC16DNP(); 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()); } }