在与硬件设备通信的时候,硬件传回来的数据经常是
十六进制
的,
在 0-100 的范围内 Java会自动转换成十进制的数字
出来,
但如果包含
abc这些字符自动转换就有问题
了,可能变成
负数
了。
设备传送的数据是:A5 5A 26 08 36 36 36 36 36 36 36 36 01 00 01 00 01 00 01 00 02 01 70 01 05 01 00 01 00 01 3E 01 05 01 05 02 04 06 98 5A A5
Java转为10进制是:byte[] bytes = {-17,-65,-67,90,38,8,54,54,54,54,54,54,54,54,1,0,1,0,1,0,1,0,2,1,112,1,5,1,0,1,0,1,62,1,5,1,5,2,23,49,-17,-65,-67,90,-17,-65,-67}
十六进制(Hex)与字节(byte)的概念
十六进制(Hex):计算机中数据的一种表示方法,它由0-9,A-F组成,字母不区分大小写。与10进制的对应关系是:0-9对应0-9;A-F对应10-15。
1个字节(byte)= 8位(bit)
“字节数组(byte数组)” 里面全部是 “字节 (byte)”,就是每一个“字节 (byte)” 都可以用二进制、十六进制、十进制来表示,如下:
二进制:00010110 —> 0*2^8 + 0*2^7 + 0*2^6 + 1*2^5 + 0*2^4 + 1*2^3 + 1*2^2 + 0*2^1 + 0*2^0 = 22
十六进制:0x16 —> 1*16^1 + 6*16^0 = 22
十进制:22
所以下面三者等价:
二进制:byte [] aa = { 00010110, 01010010, 10111000 };
十六进制:byte [] aa = { 0x16, 0x52, 0xB8 };
十进制:byte [] aa = { 22, 82, 184 };
在Eclipse断点调试的时候,看到的
“ 字节数组(byte数组)”
的内容都是用
“ 十进制 ”
表示的
。
有时会看到
“负数 ”
,因为 “ 字节数组(byte数组)”
中
超过127的数
都会 以负数的形式显示
。
我们知道Java 读取的方式只支持 “ 字节数组(byte数组)”,而 “字节(byte)” 是8位,所以
不能超过127
,
如果超过就会溢出
,
以负数的形式显示
。
转换原理:
每个二进制位有两种状态,分别为0,1
因此,两个二进制位有4种状态,分别为:00,01,10,11
三个二进制位有8种状态,分别为000,001,010,011,100,101,110,111
四个二进制位有十六种状态,0000,0001......1110,1111. 即十六进制
一个十六进制数(Hex),正好为4个二进制位。一个字节(byte)为8个二进制位。
因此,一个字节可表示为两个十六进制数字。
因此,我们可以将一个byte用两个Hex表示,同理,我们也可以将两个Hex转换为一个byte。
经常看到java中对byte数组的不同定义,粗略整理的一下:1个字节(byte)= 8位(bit)“字节数组(byte数组)” 里面全部是 “字节 (byte)”,就是每一个“字节 (byte)” 都可以用二进制、十六进制、十进制来表示,如下:二进制:00010110 —> 0*2^8 + 0*2^7 + 0*2^6 + 1*2^5 + 0*2^4 + 1*2^3 + 1*2^2 + 0*2^1 + 0*2^0 = 2216进制:0x16 —> 1*16^1 + 6*16^...
问题
原因:
byte
是一个符号保存的,第一位是符号位。1000 0000代表的数就是-1,所以正数最大为127,负数最小为-128.而二进制流中的数据是无符号的8位二进制,转成
byte
的时候被当成有符号的二进制来转换,所以需要与上0xff,0xff默认被当成int类型的32位无符号整数,与上原来的数高位取0变成8位无符号数。
1000 0000变...
在研究编码时,无意中发现
java
中输出编码后的字节数据的值有的是
负值
,比如utf-8编码后的字节数据,通过遍历,打印都是
负值
,
java
中字节
byte
有负数的现象让我产生了兴趣,在此探讨一下。
关于编码的字节有负数的现象,可以参考这篇博客:
http://blog.csdn.net/csdn_ds/article/details/79077483
下面我用
java
中的数据流去说说这个现象。
其实用简单的语言来说,接收数据的异或校验相当于解密,发送时候的校验位相当于加密;
官方解释是:其他数据信息传递中为保证数据传递正确可靠,在数据帧中常加载异或校验位(个人理解怕传输过程中出现数据丢失损坏的情况,所以加校验保证了数据的准确性)
言归正传
java
中怎么异或校验
1、发送数据
byte
[] rece = new
byte
[6];
rece[0] = 0x55;
代码如下:/// <summary> ///
字符串
转
16进制
字节
数组
/// </summary> /// <param name=”hexString”></param> /// <returns></returns> private static
byte
[] strToToHex
Byte
(string hexString) { hexString = hexString.Replace(” “, “”); if ((hexString.Length % 2) != 0) hexString += ” “;
byte
[] return
Byte
s = new
byte
[hexString.