[转]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小时内删除。
发表评论