Java int转byte数组
int 转 byte[] 低字节在前(低字节序)
1 public static byte[] toLH(int n) {
2 byte[] b = new byte[4];
3 b[0] = (byte) (n & 0xff);
4 b[1] = (byte) (n >> 8 & 0xff);
5 b[2] = (byte) (n >> 16 & 0xff);
6 b[3] = (byte) (n >> 24 & 0xff);
7 return b;
8 }
int 转 byte[] 高字节在前(高字节序)
1 public static byte[] toHH(int n) {
2 byte[] b = new byte[4];
3 b[3] = (byte) (n & 0xff);
4 b[2] = (byte) (n >> 8 & 0xff);
5 b[1] = (byte) (n >> 16 & 0xff);
6 b[0] = (byte) (n >> 24 & 0xff);
7 return b;
8 }
byte[] 转 int 低字节在前(低字节序)
1 public int toInt(byte[] b){
2 int res = 0;
3 for(int i=0;i<b.length;i++){
4 res += (b[i] & 0xff) << (i*8);
5 }
6 return res;
7 }
byte[] 转 int 高字节在前(高字节序)
1 public static int toInt(byte[] b){
2 int res = 0;
3 for(int i=0;i<b.length;i++){
4 res += (b[i] & 0xff) << ((3-i)*8);
5 }
6 return res;
7 }
Java中使用Integer.toHexString把byte转换十六进制的一些注意事项
String hexStr = Integer.toHexString((digest[i] & 0xFF | 0xFFFFFF00)).substring(6)
java中的二进制存的是补码,我们先了解二进制的一些知识吧
1.举例学习
byte b =-12;
b的二进制原码:10001100(第一位为符号位,整数为0,负数为1)
b的二进制反码:11110011(正数的反码就是原码,负数的反码是符号位不变,然后原码取反,取反是指,1变0,0变1)
b的二进制补码:1111 0011(反码)+ 1 = 11110100(反码+1),正数的反码就是原码。
2.Integer.toHexString(int i)的问题
假设byte b= -12,调用Integer.toHexString(b)获取b的十六进制字符串
b的补码1111 0100
toHexString是接收int类型的,当传进一个byte类型,会发生类型转换,当byte 转换int时, b的二进制是由8位变成32位,高24位全部补1,1111111111111111111111111110100(这正是int类型的-12的补码,你可以反推出它的原码)
然而byte 类型的-12的补码却是
1111 0100
它们不一样,得出的十六进制字符串不可能是对的,我火了
3.b & 0xFF的作用
假设byte b= -12
0xFF的二进制码是:0000 0000 0000 0000 0000 0000 1111 1111
当byte 转换int时的补码:1111 1111 1111 1111 1111 1111 1111 0100
它们进行&运算得到的二进制码:0000 0000 0000 0000 0000 0000 1111 0100 如果把前面的零去掉,1111 0100正是byte 类型的-12的补码
4.b & 0xFF的隐藏bug
假设byte b= 1
0xFF的二进制码是:0000 0000 0000 0000 0000 0000 1111 1111
当byte 转换int时的补码:1111 1111 1111 1111 1111 1111 0000 0001
它们进行&运算得到的二进制码:0000 0000 0000 0000 0000 0000 0000 0001 ,得到的十六制字符串为“1”,而byte是8位的,对应于十六进制,应该取两位,即“01”,当b<16时,b & 0xFF只获得一个字符,需要补零,你可以判断,当得到的十六制字符串的长度为1时,补上一个0,也可以b & 0xFF | 0xFFFFFF00
5.至于b & 0xFF | 0xFFFFFF00
假设byte b= -12
0xFFFFFF00的二进制码是:1111 1111 1111 1111 1111 1111 0000 0000
b & 0xFF的补码:0000 0000 0000 0000 0000 0000 1111 0100
它们进行|运算得到的二进制码:111 1111 1111 1111 1111 1111 1111 0100,在十六进制中,1位代表二进制的4位,转换成十六进制的字符串是fffffff4,f4是我需要的所以substring(6)
6.可以使用String.format(“%02x”,digest[i] & 0xFF)可能更好
7.总结
b & 0xFF是为了保证当byte 转换int时依旧保留byte的补码,这样才能正确的得到属于byte类型的十六进制字符串,| 0xFFFFFF00是为了获取后2位十六进制字符串