关于Java实现的进制转化(位运算)
一、需求:
最近在做文件传输的东西,文件传输当然是传输很重要,包括编码格式以及进制的统一。
简略的说一下这次做的东西:首先文件是按照块来发送的,一块一块大的发,但是,发送的过程是这样的;
先发送头部,头部包括三部分:1.一个int类型的文件Id,
2.一个long类型的偏移量,因为是块发,当然需要知道每次发送的起始位置。
3.一个int类型的文件长度。
而我们知道,文件传输可以是文件流的形式。但是是以二进制传输的,所以就牵扯到了int<->二进制和long<->二进制的需求。
二、具体的代码实现:
1 package com.xupt.until; 2 3 public class ByteAndString { 4 5 private static final String hex = "0123456789ABCDEF"; //字符串将由下面找到的对应 6 7 public static String toHex(byte[] buffer) { //类型为byte的数组 有下标 8 StringBuffer result = new StringBuffer(); 9 10 for(int i = 0;i < buffer.length;i++) { 11 byte bv = buffer[i]; 12 result.append(i == 0 ? "" : ' ') 13 /* 这个方法将二进制的形式转换成字符串的“十六进制”。这是前四位 14 右移四位后变成后四位,对应的数字找hex(用下标找)。 15 比如: 16 1010 0010 对应的是先右移四位1010到后四位,与00FF相与就是 17 0000 0000 0000 1010与0000 0000 1111 1111相与是1010对应十进制是10在hex中找 18 因此它是A 19 */ 20 .append(hex.charAt((bv >> 4) & 0x0F)) 21 /*这是后四位和上面的过程一样,只是不用移位*/ 22 .append(hex.charAt(bv & 0x0F)); 23 } 24 return result.toString(); 25 } 26 27 //这是将int类型得转化成二进制类型的,高低低高的形式 28 public static void setIntAt(byte[] buffer,int offset,int value) { 29 //int是4字节的,即有32位,八位八位一处理。 30 //int类型的前八位即高位先右移到最后八位即低位和00FF相与得到其本身的放进buffer的0为即低位,高低 31 buffer[offset + 0] = (byte) ((value >> 24) & 0x00FF); 32 buffer[offset + 1] = (byte) ((value >> 16) & 0x00FF); 33 buffer[offset + 2] = (byte) ((value >> 8) & 0x00FF); 34 buffer[offset + 3] = (byte) (value & 0x00FF); 35 } 36 37 //这是将long的类型转化成二进制的方法 38 public static void setLongAt(byte[] buffer,int offset,long value) { 39 //long是8字节的,即有64位,八位八位一处理。 40 //long类型的前八位即高位先右移到最后八位即低位和00FF相与得到其本身的放进buffer的0为即低位,高低 41 buffer[offset + 0] = (byte) ((value >> 56) & 0x00FF); 42 buffer[offset + 1] = (byte) ((value >> 48) & 0x00FF); 43 buffer[offset + 2] = (byte) ((value >> 40) & 0x00FF); 44 buffer[offset + 3] = (byte) ((value >> 32) & 0x00FF); 45 buffer[offset + 4] = (byte) ((value >> 24) & 0x00FF); 46 buffer[offset + 5] = (byte) ((value >> 16) & 0x00FF); 47 buffer[offset + 6] = (byte) ((value >> 8) & 0x00FF); 48 buffer[offset + 7] = (byte) (value & 0x00FF); 49 } 50 51 //这是将二进制转化成int类型的方法 52 public static int getIntAt(byte[] buffer,int offset) { 53 int value = 0; 54 //第一个value和上面的int类型转化成二进制对应起来, 55 //先将第一个取出来的左移24位与FF000000相与就是这八位,再相或就是原来的前八位 56 value |= buffer[offset + 0] << 24 & 0xFF000000; 57 value |= buffer[offset + 1] << 16 & 0x00FF0000; 58 value |= buffer[offset + 2] << 8 & 0x0000FF00; 59 value |= buffer[offset + 3] & 0x000000FF; 60 61 return value; 62 } 63 64 //这是将二进制转化成long类型的方法 65 public static long getLongAt(byte[] buffer,int offset) { 66 long value = 0; 67 //第一个value和上面的long类型转化成二进制对应起来, 68 //先将第一个取出来的左移64位与FF000000相与就是这八位,再相或就是原来的前八位 69 value |= buffer[offset + 0] << 56 & 0xFF00000000000000L; 70 value |= buffer[offset + 1] << 48 & 0x00FF000000000000L; 71 value |= buffer[offset + 2] << 40 & 0x0000FF0000000000L; 72 value |= buffer[offset + 3] << 32 & 0x000000FF00000000L; 73 value |= buffer[offset + 4] << 24 & 0x00000000FF000000L; 74 value |= buffer[offset + 5] << 16 & 0x0000000000FF0000L; 75 value |= buffer[offset + 6] << 8 & 0x0000000000000FF0L; 76 value |= buffer[offset + 7] & 0x00000000000000FFL; 77 78 return value; 79 } 80 81 }
三、说明:
位运算是比较凶悍的,计算精简。但是不容易理解,根据上述的注释,若有错误或者迷惑,欢迎指正。