[转]Java中byte与16进制字符串的互相转换
本⽂转⾃:
Java中byte⽤⼆进制表⽰占⽤8位,⽽我们知道16进制的每个字符需要⽤4位⼆进制位来表⽰(23 + 22 + 21 + 20 = 15),所以我们就可以把每个byte转换成两个相应的16进制字符,即把byte的⾼4位和低4位分别转换成相应的16进制字符H和L,并组合起来得到byte转换到16进制字符串的结果new String(H) + new String(L)。即byte⽤⼗六进制表⽰只占2位。
同理,相反的转换也是将两个16进制字符转换成⼀个byte,原理同上。
根据以上原理,我们就可以将byte[] 数组转换为16进制字符串了,当然也可以将16进制字符串转换为byte[]数组了。
/**
Java代码
1.  * Convert byte[] to hex string.这⾥我们可以将byte转换成int,然后利⽤HexString(int)来转换成16进制字符串。
2.  * @param src byte[] data
3.  * @return hex string
4.  */
5. public static String bytesToHexString(byte[] src){
6.    StringBuilder stringBuilder = new StringBuilder("");
7.    if (src == null || src.length <= 0) {
8.        return null;
9.    }
10.    for (int i = 0; i < src.length; i++) {
11.        int v = src[i] & 0xFF;
12.        String hv = HexString(v);
13.        if (hv.length() < 2) {
14.            stringBuilder.append(0);
15.        }
16.        stringBuilder.append(hv);
17.    }
18.    String();
19. }
20. /**
21.  * Convert hex string to byte[]
java数组字符串转数组22.  * @param hexString the hex string
23.  * @return byte[]
24.  */
25. public static byte[] hexStringToBytes(String hexString) {
26.    if (hexString == null || hexString.equals("")) {
27.        return null;
28.    }
29.    hexString = UpperCase();
30.    int length = hexString.length() / 2;
31.    char[] hexChars = CharArray();
32.    byte[] d = new byte[length];
33.    for (int i = 0; i < length; i++) {
34.        int pos = i * 2;
35.        d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
36.    }
37.    return d;
38. }
39. /**
40.  * Convert char to byte
41.  * @param c char
42.  * @return byte
43.  */
44.  private byte charToByte(char c) {
45.    return (byte) "0123456789ABCDEF".indexOf(c);
46. }
Java代码
1. //将指定byte数组以16进制的形式打印到控制台
2. public static void printHexString( byte[] b) {
3.    for (int i = 0; i < b.length; i++) {
4.      String hex = HexString(b[i] & 0xFF);
5.      if (hex.length() == 1) {
6.        hex = '0' + hex;
7.      }
8.      System.out.UpperCase() );
9.    }
10.
11. }
java中byte转换int时为何与0xff进⾏与运算
在剖析该问题前请看如下代码
Java代码
1. public static String bytes2HexString(byte[] b) {
2.  String ret = "";
3.  for (int i = 0; i < b.length; i++) {
4.    String hex = HexString(b[ i ] & 0xFF);
5.    if (hex.length() == 1) {
6.    hex = '0' + hex;
7.    }
8.    ret += UpperCase();
9.  }
10.  return ret;
11. }
上⾯是将byte[]转化⼗六进制的字符串,注意这⾥b[ i ] & 0xFF将⼀个byte和 0xFF进⾏了与运算,然后使⽤HexString取得了⼗六进制字符串,可以看出
b[ i ] & 0xFF运算后得出的仍然是个int,那么为何要和 0xFF进⾏与运算呢?直接 HexString(b[ i ]);,将byte强转为int不⾏吗?答案是不⾏的.
其原因在于:
1.byte的⼤⼩为8bits⽽int的⼤⼩为32bits
2.java的⼆进制采⽤的是补码形式
在这⾥先温习下计算机基础理论
byte是⼀个字节保存的,有8个位,即8个0、1。
8位的第⼀个位是符号位,
也就是说0000 0001代表的是数字1
1000 0000代表的就是-1
所以正数最⼤位0111 1111,也就是数字127
负数最⼤为1111 1111,也就是数字-128
上⾯说的是⼆进制原码,但是在java中采⽤的是补码的形式,下⾯介绍下什么是补码
1、反码:
⼀个数如果是正,则它的反码与原码相同;
⼀个数如果是负,则符号位为1,其余各位是对原码取反;
2、补码:利⽤溢出,我们可以将减法变成加法
对于⼗进制数,从9得到5可⽤减法:
9-4=5    因为4+6=10,我们可以将6作为4的补数
改写为加法:
9+6=15(去掉⾼位1,也就是减10)得到5.
对于⼗六进制数,从c到5可⽤减法:
c-7=5    因为7+9=16 将9作为7的补数
改写为加法:
c+9=15(去掉⾼位1,也就是减16)得到5.
在计算机中,如果我们⽤1个字节表⽰⼀个数,⼀个字节有8位,超过8位就进1,在内存中情况为(100000000),进位1被丢弃。
⑴⼀个数为正,则它的原码、反码、补码相同
⑵⼀个数为负,刚符号位为1,其余各位是对原码取反,然后整个数加1
- 1的原码为                10000001
- 1的反码为                11111110
+ 1
- 1的补码为                11111111
0的原码为                00000000
0的反码为                11111111(正零和负零的反码相同)
+1
0的补码为              100000000(舍掉打头的1,正零和负零的补码相同)
例如补码11111111的⼗进制数为-1转换为int时变为11111111111111111111111111111111好多1啊,呵呵!即0xffffffff但是这个数是不对的,这种补位就会造成误差。
和0xff相与后,⾼24⽐特就会被清0了,结果就对了。
----
Java中的⼀个byte,其范围是-128~127的,⽽HexString的参数本来是int,如果不进⾏&0xff,那么当⼀个byte会转换成int时,对于负数,会做位扩展,举例来说,⼀个byte的-1(即0xff),会被转换成int的-1(即0xffffffff),那么转化出的结果就不是我们想要的了。
⽽0xff默认是整形,所以,⼀个byte跟0xff相与会先将那个byte转化成整形运算,这样,结果中的⾼的24个⽐特就总会被清0,于是结果总是我们想要的。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。