一直很少用到用到byte和int的转换,今天做加密的时候在网上找了一段函数
private static byte[] hex2byte(String strhex) {
if (strhex == null) {
return null;
}
int l = strhex.length();
if (l % 2 == 1) {
return null;
}
byte[] b = new byte[l / 2];
for (int i = 0; i != l / 2; i++) {
b[i] = (byte) Integer.parseInt(strhex.substring(i * 2, i * 2 + 2), 16);
}
return b;
}
private static String byte2hex(byte[] b) {
String hs = "";
String stmp = "";
for (int n = 0; n < b.length; n++) {
stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
if (stmp.length() == 1) {
hs = hs + "0" + stmp;
} else {
hs = hs + stmp;
}
}
return hs.toUpperCase();
}
对& 0XFF不解,于是仔细的想了一下,原来是这样的。
在java里byte是有符号的,也就是在-128~127之间的,由于16进制字符转换为的int是在0-255,
b[i] = (byte) Integer.parseInt(strhex.substring(i * 2, i * 2 + 2), 16);这一句就会对int进行截断
ep.
System.out.println(Integer.toBinaryString(234)); //11101010
byte b = (byte)234;//b=-22
这里有这么一句stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
由于上面对hex2byte的时候对int进行了截断,因此这里要先将-22还原成234然后再调用toHexString
上面的234转换成byte变成-22了,为什么& 0XFF可以还原呢?
其实
int型的 -22就是11111111111111111111111111101010
而234 00000000000000000000000011101010
这个时候& 00000000000000000000000011111111正好就将-22变为了234
结论:
这里,如果一个数的范围大于了11111111,那么转换成byte后高位就丢失掉了,也就无法准确还原,在[00000000,11111111]范围内,
对于大于等于10000000的数,截断后最高位的1被当作了负号,因此值发生了变化。要想将其还原为截断前的,只需要将其第8位以上的1全部变为0就可以了,也就是&0XFF。
对于小于10000000的数,转换为byte后,数值不变。由于其第8位以上都是0,所以&0XFF对其无影响。
因此,一个[0,255]的int转换为byte后,再&0XFF可以还原到原来的int数值