• Java CRC算法大全(复制的)||| 关于Java处理串口二进制数据的问题 byte的范围 一个字节8bits


    前置知识点

    byte的范围[-128~127] 内存里表现为 0x00~0xFF
    刚好是一个8bits的字节

    问题

    byte[] hexData = new byte[] {0x01, 0x03, 0x04, 0x02, 0x1F, 0x01, 0x4E, 0x4B, (byte)0xE9 };
    

    Java先把括号里的识别为int数,然后再自动转换为byte
    这里的int数0xE9,超出了byte的范围[-128~127],所以不会自动转换,必须代码指定强制转换。



    那么问题来了,内存里是这样的
    调试器结果:
    image
    而且打印出来的 (hexData[8]) 也是这样,所以不是调试器的问题,而是Java就是这么识别的。

    解决

    (hexData[8]&0xFF) 即可取出低位

    揭秘

    byte是有符号的,为了方便硬件运算,因此正负转换用了补码

    Java所有数默认都识别为int,0xE9 被识别为 (int)233 超出了byte范围[-128~127]。
    强制转换为byte后发生上溢,溢出了233-127=106,因此结果为 -1+(-128)+106=-23
    -23的十六进制为 FFFFFFFFFFFFFFE9,也就是调试器里的那个数值

    所以正数的时候没错,但负数的时候就需要处理了

    对于 byte[-128,127], 其[0,127]范围的数据和 int 中的 [0,127] 完全一致,不需要 & 0XFF, 只有对于 [-128,-1] 的 byte 数据才需要 & 0XFF.

    详见:对 byte & 0xFF 的理解

    PS: 就算你用 byteArr[i] &= 0xFF 也是徒劳,因为字面量都会被识别为int,字面量一旦大于0x7F(127),强制转换为byte时就上溢变成byte负数了。所以如果你要计算byte,只能放到更大的变量类型,如int里计算,如下CRC大全代码示例,全都是用int处理的

    CRC大全

    首先提供一个在线计算CRC的网站供对比
    http://www.ip33.com/crc.html

    然后提供从CSDN复制过来并修复问题的代码,因为绝大部分人都不知道处理byte是需要取位的,必须使用 hexByte&0xFF
    所以你要么在传入计算之前先 hexByte = hexByte&0xFF
    要么就在校验计算函数里取 hexByte&0xFF ,这里我选择第二种

    /*
     * 代码修改自「Dan淡淡的心」 https://blog.csdn.net/qq_41054313/article/details/90229591 增加了取位data[j]&0xFF
     * 修改者 YuCloud
     */
    
    public class CRC {
    	
    	public static byte crc4_itu(byte[] data, int offset,int length){
    		byte i;
    		byte crc = 0;                // Initial value
    		length += offset;
    		for(int j=offset;j<length;j++) {
    			crc ^= data[j]&0xFF;                 
    			for (i = 0; i < 8; ++i){
    				if ((crc & 1) != 0)
    					crc = (byte) (((crc & 0xff) >> 1 ) ^ 0x0C);// 0x0C = (reverse 0x03)>>(8-4)
    				else
    					crc = (byte) ((crc & 0xff) >> 1);
    			}
    		}
    		return (byte) (crc & 0xf);
    	}
    
    	/******************************************************************************
    	 * Name:    CRC-5/EPC           x5+x3+1
    	 * Poly:    0x09
    	 * Init:    0x09
    	 * Refin:   False
    	 * Refout:  False
    	 * Xorout:  0x00
    	 * Note:
    	 *****************************************************************************/
    	public static byte crc5_epc(byte data[],int offset,int length){
    		byte i;
    		byte crc = 0x48;        // Initial value: 0x48 = 0x09<<(8-5)
    		length += offset;
    		for(int j=offset;j<length;j++) {
    			crc ^= data[j]&0xFF;
    			for ( i = 0; i < 8; i++ ){
    				if ( (crc & 0x80) != 0)
    					crc = (byte) ((crc << 1) ^ 0x48);        // 0x48 = 0x09<<(8-5)
    				else
    					crc <<= 1;
    			}
    		}
    		return (byte) (crc >> 3 & 0x1f);
    	}
    
    	/******************************************************************************
    	 * Name:    CRC-5/ITU           x5+x4+x2+1
    	 * Poly:    0x15
    	 * Init:    0x00
    	 * Refin:   True
    	 * Refout:  True
    	 * Xorout:  0x00
    	 * Note:
    	 *****************************************************************************/
    	public static byte crc5_itu(byte[] data,int offset,int length){
    		byte i;
    		byte crc = 0;                // Initial value
    		length += offset;
    		for(int j=offset;j<length;j++) {
    			crc ^= data[j]&0xFF;                 
    			for (i = 0; i < 8; ++i){
    				if ((crc & 1) == 0)
    					crc = (byte) ((crc&0xff) >> 1);
    				else
    					crc = (byte) (((crc&0xff) >> 1) ^ 0x15);// 0x15 = (reverse 0x15)>>(8-5)
    			}
    		}
    		return (byte) (crc & 0x1f);
    	}
    
    	/******************************************************************************
    	 * Name:    CRC-5/USB           x5+x2+1
    	 * Poly:    0x05
    	 * Init:    0x1F
    	 * Refin:   True
    	 * Refout:  True
    	 * Xorout:  0x1F
    	 * Note:
    	 *****************************************************************************/
    	public static byte crc5_usb(byte[] data,int offset,int length){
    		byte i;
    		byte crc = 0x1F;                // Initial value
    		length += offset;
    		for(int j=offset;j<length;j++) {
    			crc ^= data[j]&0xFF;                 
    			for (i = 0; i < 8; ++i){
    				if ((crc & 1) == 0)
    					crc = (byte) ((crc&0xff) >> 1);
    				else
    					crc = (byte) (((crc&0xff) >> 1) ^ 0x14);// 0x14 = (reverse 0x05)>>(8-5)
    			}
    		}
    		return (byte) (crc ^ 0x1F & 0x1f);
    	}
    
    	/******************************************************************************
    	 * Name:    CRC-6/ITU           x6+x+1
    	 * Poly:    0x03
    	 * Init:    0x00
    	 * Refin:   True
    	 * Refout:  True
    	 * Xorout:  0x00
    	 * Note:
    	 *****************************************************************************/
    	public static byte crc6_itu(byte[] data,int offset,int length){
    		byte i;
    		byte crc = 0;         // Initial value
    		length += offset;
    		for(int j=offset;j<length;j++) {
    			crc ^= data[j]&0xFF;
    			for (i = 0; i < 8; ++i){
    				if ((crc & 1) == 0)
    					crc = (byte) ((crc&0xff) >> 1);
    				else
    					crc = (byte) (((crc&0xff) >> 1) ^ 0x30);// 0x30 = (reverse 0x03)>>(8-6)
    			}
    		}
    		return (byte) (crc & 0x3f);
    	}
    
    	/******************************************************************************
    	 * Name:    CRC-7/MMC           x7+x3+1
    	 * Poly:    0x09
    	 * Init:    0x00
    	 * Refin:   False
    	 * Refout:  False
    	 * Xorout:  0x00
    	 * Use:     MultiMediaCard,SD,ect.
    	 *****************************************************************************/
    	public static byte crc7_mmc(byte[] data,int offset,int length){
    		byte i;
    		byte crc = 0;        // Initial value
    		length += offset;
    		for(int j=offset;j<length;j++) {
    			crc ^= data[j]&0xFF;        // crc ^= *data; data++;
    			for ( i = 0; i < 8; i++ )
    			{
    				if ( (crc & 0x80) ==0)
    					crc <<= 1;
    				else
    					crc = (byte) ((crc << 1) ^ 0x12);        // 0x12 = 0x09<<(8-7)
    			}
    		}
    		return (byte) (crc >> 1 & 0x7f);
    	}
    
    	/******************************************************************************
    	 * Name:    CRC-8               x8+x2+x+1
    	 * Poly:    0x07
    	 * Init:    0x00
    	 * Refin:   False
    	 * Refout:  False
    	 * Xorout:  0x00
    	 * Note:
    	 *****************************************************************************/
    	public static byte crc8(byte[] data,int offset,int length){
    		byte i;
    		byte crc = 0;        // Initial value
    		length += offset;
    		for(int j=offset;j<length;j++) {
    			crc ^= data[j]&0xFF;        
    			for ( i = 0; i < 8; i++ )
    			{
    				if ( (crc & 0x80) == 0)
    					crc <<= 1;
    				else
    					crc = (byte) ((crc << 1) ^ 0x07);
    			}
    		}
    		return crc;
    	}
    
    	/******************************************************************************
    	 * Name:    CRC-8/ITU           x8+x2+x+1
    	 * Poly:    0x07
    	 * Init:    0x00
    	 * Refin:   False
    	 * Refout:  False
    	 * Xorout:  0x55
    	 * Alias:   CRC-8/ATM
    	 *****************************************************************************/
    	public static byte crc8_itu(byte[] data,int offset,int length){
    		byte i;
    		byte crc = 0;        // Initial value
    		length += offset;
    		for(int j=offset;j<length;j++) {
    			crc ^= data[j]&0xFF;        
    			for ( i = 0; i < 8; i++ )
    			{
    				if ( (crc & 0x80) == 0)
    					crc <<= 1;
    				else
    					crc = (byte) ((crc << 1) ^ 0x07);
    			}
    		}
    		return (byte) (crc ^ 0x55);
    	}
    
    	/******************************************************************************
    	 * Name:    CRC-8/ROHC          x8+x2+x+1
    	 * Poly:    0x07
    	 * Init:    0xFF
    	 * Refin:   True
    	 * Refout:  True
    	 * Xorout:  0x00
    	 * Note:
    	 *****************************************************************************/
    	public static byte crc8_rohc(byte[] data,int offset,int length){
    		byte i;
    		byte crc = 0;        // Initial value
    		length += offset;
    		for(int j=offset;j<length;j++) {
    			crc ^= data[j]&0xFF;        
    			for ( i = 0; i < 8; i++ )
    			{
    				if ( (crc & 0x80) == 0)
    					crc = (byte) ((crc&0xff) >> 1);
    				else
    					crc = (byte) (((crc&0xff) >> 1) ^ 0xE0);
    			}
    		}
    		return crc;
    	}
    
    	/******************************************************************************
    	 * Name:    CRC-8/MAXIM         x8+x5+x4+1
    	 * Poly:    0x31
    	 * Init:    0x00
    	 * Refin:   True
    	 * Refout:  True
    	 * Xorout:  0x00
    	 * Alias:   DOW-CRC,CRC-8/IBUTTON
    	 * Use:     Maxim(Dallas)'s some devices,e.g. DS18B20
    	 *****************************************************************************/
    	public static byte crc8_maxim(byte[] data,int offset,int length){
    		byte i;
    		byte crc = 0;        // Initial value
    		length += offset;
    		for(int j=offset;j<length;j++) {
    			crc ^= data[j]&0xFF;        
    			for ( i = 0; i < 8; i++ ){
    				if ( (crc & 1) == 0)
    					crc = (byte) ((crc&0xff) >> 1);
    				else
    					crc = (byte) (((crc&0xff) >> 1) ^ 0x8C);
    			}
    		}
    		return crc;
    	}
    
    	/******************************************************************************
    	 * Name:    CRC-16/IBM          x16+x15+x2+1
    	 * Poly:    0x8005
    	 * Init:    0x0000
    	 * Refin:   True
    	 * Refout:  True
    	 * Xorout:  0x0000
    	 * Alias:   CRC-16,CRC-16/ARC,CRC-16/LHA
    	 *****************************************************************************/
    	public static short crc16_ibm(byte data[],int offset,int length){
    		byte i;
    		short crc = 0;        // Initial value
    		length += offset;
    		for(int j=offset;j<length;j++) {
    			crc ^= data[j]&0xFF;   
    			for (i = 0; i < 8; ++i)
    			{
    				if ((crc & 1) == 0)
    					crc = (short) (crc >> 1);
    				else
    					crc = (short) ((crc >> 1) ^ 0xA001);        // 0xA001 = reverse 0x8005
    			}
    		}
    		return crc;
    	}
    
    	/******************************************************************************
    	 * Name:    CRC-16/MAXIM        x16+x15+x2+1
    	 * Poly:    0x8005
    	 * Init:    0x0000
    	 * Refin:   True
    	 * Refout:  True
    	 * Xorout:  0xFFFF
    	 * Note:
    	 *****************************************************************************/
    	public static short crc16_maxim(byte[] data,int offset,int length){
    		byte i;
    		short crc = 0;        // Initial value
    		length += offset;
    		for(int j=offset;j<length;j++) {
    			crc ^= data[j]&0xFF;
    			for (i = 0; i < 8; ++i){
    				if ((crc & 1) == 0)
    					crc = (short) (crc >> 1);
    				else
    					crc = (short) ((crc >> 1) ^ 0xA001);        // 0xA001 = reverse 0x8005
    			}
    		}
    		return (short) ~crc;    // crc^0xffff
    	}
    
    	/******************************************************************************
    	 * Name:    CRC-16/USB          x16+x15+x2+1
    	 * Poly:    0x8005
    	 * Init:    0xFFFF
    	 * Refin:   True
    	 * Refout:  True
    	 * Xorout:  0xFFFF
    	 * Note:
    	 *****************************************************************************/
    	public static short crc16_usb(byte[] data,int offset,int length){
    		byte i;
    		short crc = (short) 0xffff;        // Initial value
    		length += offset;
    		for(int j=offset;j<length;j++) {
    			crc ^= data[j]&0xFF;            // crc ^= *data; data++;
    			for (i = 0; i < 8; ++i)
    			{
    				if ((crc & 1) == 0)
    					crc = (short) (crc >> 1);
    				else
    					crc = (short) ((crc >> 1) ^ 0xA001);        // 0xA001 = reverse 0x8005
    			}
    		}
    		return (short) ~crc;    // crc^0xffff
    	}
    
    	/******************************************************************************
    	 * Name:    CRC-16/MODBUS       x16+x15+x2+1
    	 * Poly:    0x8005
    	 * Init:    0xFFFF
    	 * Refin:   True
    	 * Refout:  True
    	 * Xorout:  0x0000
    	 * Note:
    	 *****************************************************************************/
    	public static short crc16_modbus(byte[] data,int offset,int length){
    		byte i;
    		short crc = (short) 0xffff;        // Initial value
    		length += offset;
    		for(int j=offset;j<length;j++) {
    			crc ^= data[j]&0xFF;            // crc ^= *data; data++;
    			for (i = 0; i < 8; ++i){
    				if ((crc & 1) == 0)
    					crc = (short) ((crc & 0xffff) >> 1);
    				else
    					crc = (short) (((crc & 0xffff) >> 1) ^ 0xA001);        // 0xA001 = reverse 0x8005
    			}
    		}
    		return crc;
    	}
    
    	/******************************************************************************
    	 * Name:    CRC-16/CCITT        x16+x12+x5+1
    	 * Poly:    0x1021
    	 * Init:    0x0000
    	 * Refin:   True
    	 * Refout:  True
    	 * Xorout:  0x0000
    	 * Alias:   CRC-CCITT,CRC-16/CCITT-TRUE,CRC-16/KERMIT
    	 *****************************************************************************/
    	public static short crc16_ccitt(byte[] data,int offset,int length){
    		byte i;
    		short crc = 0;        // Initial value
    		length += offset;
    		for(int j=offset;j<length;j++) {
    			crc ^= data[j]&0xFF;
    			for (i = 0; i < 8; ++i){
    				if ((crc & 1) != 0)
    					crc = (short) ((crc >> 1) ^ 0x8408);        // 0x8408 = reverse 0x1021
    				else
    					crc = (short) (crc >> 1);
    			}
    		}
    		return crc;
    	}
    
    	/******************************************************************************
    	 * Name:    CRC-16/CCITT-FALSE   x16+x12+x5+1
    	 * Poly:    0x1021
    	 * Init:    0xFFFF
    	 * Refin:   False
    	 * Refout:  False
    	 * Xorout:  0x0000
    	 * Note:
    	 *****************************************************************************/
    	public static short crc16_ccitt_false(byte[] data,int offset,int length){
    		byte i;
    		short crc = (short) 0xffff;        //Initial value
    		length += offset;
    		for(int j=offset;j<length;j++) {
    			crc ^= (short)(data[j]&0xFF) << 8; // crc ^= (uint6_t)(*data)<<8; data++;
    			for (i = 0; i < 8; ++i)
    			{
    				if ( (crc & 0x8000) != 0)
    					crc = (short) ((crc << 1) ^ 0x1021);
    				else
    					crc <<= 1;
    			}
    		}
    		return crc;
    	}
    
    	/******************************************************************************
    	 * Name:    CRC-16/X25          x16+x12+x5+1
    	 * Poly:    0x1021
    	 * Init:    0xFFFF
    	 * Refin:   True
    	 * Refout:  True
    	 * Xorout:  0XFFFF
    	 * Note:
    	 *****************************************************************************/
    	public static short crc16_x25(byte[] data,int offset,int length){
    		byte i;
    		short crc = (short) 0xffff;        // Initial value
    		length += offset;
    		for(int j=offset;j<length;j++) {
    			crc ^= data[j]&0xFF;            
    			for (i = 0; i < 8; ++i)
    			{
    				if ((crc & 1) != 0)
    					crc = (short) ((crc >> 1) ^ 0x8408);        // 0x8408 = reverse 0x1021
    				else
    					crc = (short) (crc >> 1);
    			}
    		}
    		return (short) ~crc;                
    	}
    
    	/******************************************************************************
    	 * Name:    CRC-16/XMODEM       x16+x12+x5+1
    	 * Poly:    0x1021
    	 * Init:    0x0000
    	 * Refin:   False
    	 * Refout:  False
    	 * Xorout:  0x0000
    	 * Alias:   CRC-16/ZMODEM,CRC-16/ACORN
    	 *****************************************************************************/
    	public static short crc16_xmodem(byte[] data, int offset,int length){
    		byte i;
    		short crc = 0;            // Initial value
    		length += offset;
    		for(int j=offset;j<length;j++) {
    			crc ^= ((short)data[j]&0xFF) << 8; 
    			for (i = 0; i < 8; ++i){
    				if ( (crc & 0x8000) != 0)
    					crc = (short) ((crc << 1) ^ 0x1021);
    				else
    					crc <<= 1;
    			}
    		}
    		return crc;
    	}
    
    	/******************************************************************************
    	 * Name:    CRC-16/DNP          x16+x13+x12+x11+x10+x8+x6+x5+x2+1
    	 * Poly:    0x3D65
    	 * Init:    0x0000
    	 * Refin:   True
    	 * Refout:  True
    	 * Xorout:  0xFFFF
    	 * Use:     M-Bus,ect.
    	 *****************************************************************************/
    	public static short crc16_dnp(byte[] data, int offset,int length){
    		byte i;
    		short crc = 0;            // Initial value
    		length += offset;
    		for(int j=offset;j<length;j++) {
    			crc ^= data[j]&0xFF;            
    			for (i = 0; i < 8; ++i){
    				if ((crc & 1) != 0)
    					crc = (short) ((crc >> 1) ^ 0xA6BC);        // 0xA6BC = reverse 0x3D65
    				else
    					crc = (short) (crc >> 1);
    			}
    		}
    		return (short) ~crc;                // crc^Xorout
    	}
    
    	/******************************************************************************
    	 * Name:    CRC-32  x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1
    	 * Poly:    0x4C11DB7
    	 * Init:    0xFFFFFFF
    	 * Refin:   True
    	 * Refout:  True
    	 * Xorout:  0xFFFFFFF
    	 * Alias:   CRC_32/ADCCP
    	 * Use:     WinRAR,ect.
    	 *****************************************************************************/
    	public static int crc32(byte[] data, int offset,int length){
    		byte i;
    		int crc = 0xffffffff;        // Initial value
    		length += offset;
    		for(int j=offset;j<length;j++) {
    			crc ^= data[j]&0xFF;                
    			for (i = 0; i < 8; ++i){
    				if ((crc & 1) != 0)
    					crc = (crc >> 1) ^ 0xEDB88320;// 0xEDB88320= reverse 0x04C11DB7
    				else
    					crc = (crc >> 1);
    			}
    		}
    		return ~crc;
    	}
    
    
    	/******************************************************************************
    	 * Name:    CRC-32/MPEG-2  x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1
    	 * Poly:    0x4C11DB7
    	 * Init:    0xFFFFFFF
    	 * Refin:   False
    	 * Refout:  False
    	 * Xorout:  0x0000000
    	 * Note:
    	 *****************************************************************************/
    	public static int crc32_mpeg_2(byte[] data,int offset, int length){
    		byte i;
    		int crc = 0xffffffff;  // Initial value
    		length += offset;
    		for(int j=offset;j<length;j++) {
    			crc ^= (data[j]&0xFF) << 24;
    			for (i = 0; i < 8; ++i){
    				if ( (crc & 0x80000000) != 0)
    					crc = (crc << 1) ^ 0x04C11DB7;
    				else
    					crc <<= 1;
    			}
    		}
    		return crc;
    	}
    
    }
    
    /*
     * 代码修改自「Dan淡淡的心」 https://blog.csdn.net/qq_41054313/article/details/90229591 增加了取位data[j]&0xFF
     * 修改者 YuCloud
     */
    
    
    --------蓝天上的云_转载请注明出处.
  • 相关阅读:
    鼠标划过出现子菜单
    让dedecms(织梦)的list标签支持weight排序
    win7 64位无法安装网络打印机
    点击外部链接, 让iframe父页面也跟着显示
    C/C++指针(转)
    OO与设计模式的原则、目标 (转)
    页面添加QQ
    Windows Form 中的鼠标事件
    深入浅出C#消息
    初始化列表
  • 原文地址:https://www.cnblogs.com/yucloud/p/Java_byte.html
Copyright © 2020-2023  润新知