關於Java實現的進位制轉化(位運算)
阿新 • • 發佈:2018-11-28
一、需求:
最近在做檔案傳輸的東西,檔案傳輸當然是傳輸很重要,包括編碼格式以及進位制的統一。
簡略的說一下這次做的東西:首先檔案是按照塊來發送的,一塊一塊大的發,但是,傳送的過程是這樣的;
先發送頭部,頭部包括三部分: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相與就是 170000 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 }
三、說明:
位運算是比較凶悍的,計算精簡。但是不容易理解,根據上述的註釋,若有錯誤或者迷惑,歡迎指正。