Browse Source

add crc16

Looly 5 years ago
parent
commit
62a02fb265

+ 1 - 0
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)

+ 32 - 0
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;
+			}
+		}
+	}
+}

+ 2 - 1
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;
 	}
 

+ 31 - 1
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;

+ 3 - 2
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;

+ 2 - 1
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;
 	}
 

+ 2 - 1
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;
 	}
 

+ 22 - 10
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());
 	}
 }