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位。 java

同理,相反的轉換也是將兩個16進制字符轉換成一個byte,原理同上。 數組

根據以上原理,咱們就能夠將byte[] 數組轉換爲16進制字符串了,固然也能夠將16進制字符串轉換爲byte[]數組了。 app

 

 

    /** ui

Java代碼   收藏代碼
  1.  * Convert byte[] to hex string.這裏咱們能夠將byte轉換成int,而後利用Integer.toHexString(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 = Integer.toHexString(v);  
  13.         if (hv.length() < 2) {  
  14.             stringBuilder.append(0);  
  15.         }  
  16.         stringBuilder.append(hv);  
  17.     }  
  18.     return stringBuilder.toString();  
  19. }  
  20. /** 
  21.  * Convert hex string to byte[] 
  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 = hexString.toUpperCase();  
  30.     int length = hexString.length() / 2;  
  31.     char[] hexChars = hexString.toCharArray();  
  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 = Integer.toHexString(b[i] & 0xFF);   
  5.      if (hex.length() == 1) {   
  6.        hex = '0' + hex;   
  7.      }   
  8.      System.out.print(hex.toUpperCase() );   
  9.    }   
  10.   
  11. }  

 

java中byte轉換int時爲什麼與0xff進行與運算 spa

在剖析該問題前請看以下代碼 .net

Java代碼   收藏代碼
  1. public static String bytes2HexString(byte[] b) {  
  2.   String ret = "";  
  3.   for (int i = 0; i < b.length; i++) {  
  4.    String hex = Integer.toHexString(b[ i ] & 0xFF);  
  5.    if (hex.length() == 1) {  
  6.     hex = '0' + hex;  
  7.    }  
  8.    ret += hex.toUpperCase();  
  9.   }  
  10.   return ret;  
  11. }  

 
上面是將byte[]轉化十六進制的字符串,注意這裏b[ i ] & 0xFF將一個byte和 0xFF進行了與運算,而後使用Integer.toHexString取得了十六進制字符串,能夠看出
b[ i ] & 0xFF運算後得出的仍然是個int,那麼爲什麼要和 0xFF進行與運算呢?直接 Integer.toHexString(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,其他各位是對原碼取反;

二、補碼:利用溢出,咱們能夠將減法變成加法
       對於十進制數,從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,正零和負零的補碼相同)

Integer.toHexString的參數是int,若是不進行&0xff,那麼當一個byte會轉換成int時,因爲int是32位,而byte只有8位這時會進行補位,
例如補碼11111111的十進制數爲-1轉換爲int時變爲11111111111111111111111111111111好多1啊,呵呵!即0xffffffff可是這個數是不對的,這種補位就會形成偏差。
和0xff相與後,高24比特就會被清0了,結果就對了。

----
Java中的一個byte,其範圍是-128~127的,而Integer.toHexString的參數原本是int,若是不進行&0xff,那麼當一個byte會轉換成int時,對於負數,會作位擴展,舉例來講,一個byte的-1(即0xff),會被轉換成int的-1(即0xffffffff),那麼轉化出的結果就不是咱們想要的了。

而0xff默認是整形,因此,一個byte跟0xff相與會先將那個byte轉化成整形運算,這樣,結果中的高的24個比特就總會被清0,因而結果老是咱們想要的。 內存

相關文章
相關標籤/搜索