2009-06-25 36 views
4

最近,我開始尋找MD5哈希(在Java中),並同時我發現算法和方法來幫助我實現這個目標,我在想,它是如何實際工作。有人可以解釋從字節數組到十六進制字符串的轉換嗎?

原因之一,我發現從this URL如下:

private static String convertToHex(byte[] data) { 
    StringBuffer buf = new StringBuffer(); 
    for (int i = 0; i < data.length; i++) { 
     int halfbyte = (data[i] >>> 4) & 0x0F; 
     int two_halfs = 0; 
     do { 
      if ((0 <= halfbyte) && (halfbyte <= 9)) 
       buf.append((char) ('0' + halfbyte)); 
      else 
       buf.append((char) ('a' + (halfbyte - 10))); 
       halfbyte = data[i] & 0x0F; 
      } while(two_halfs++ < 1); 
     } 
    return buf.toString(); 
} 

我還沒有發現任何需要使用位移位在Java中,所以我上有點生疏。有人足以說明(簡單地說)上述代碼如何轉換? 「>>>」?

我還發現在計算器上其他解決方案,比如herehere,它使用的BigInteger代替:

爲什麼這項工作過了,哪條路更有效?

感謝您的時間。

回答

10
private static String convertToHex(byte[] data) { 
    StringBuffer buf = new StringBuffer(); 
    for (int i = 0; i < data.length; i++) { 

截至這一點...只是基本建立並開始循環要經過所有的字節數組中

 int halfbyte = (data[i] >>> 4) & 0x0F; 

字節時轉換爲十六進制是根據什麼基數二十六進制數字或8個二進制數字,你看它英寸以上語句將高4位向下(>>>是無符號右移位)和邏輯與運算其與0000 1111使得結果等於該字節的高4位的整數(第一十六進制數字)。

說23是一個輸入,這是二進制0001 0111。這種轉變使得和邏輯與覆羽這0000 0001

 int two_halfs = 0; 
     do { 

這只是樹立DO/while循環運行兩次

  if ((0 <= halfbyte) && (halfbyte <= 9)) 
       buf.append((char) ('0' + halfbyte)); 
      else 
       buf.append((char) ('a' + (halfbyte - 10))); 

這裏,我們顯示實際十六進制數字,基本上只是使用零或一個字符作爲起點並移動到正確的字符。第一個if語句覆蓋了所有的數字0-9,第二個覆蓋所有數字10-15(十六進制AF)

同樣,使用十進制我們的例子0000 0001等於1,我們陷入的上如果阻塞並將'0'字符加1以得到字符'1',則將其附加到字符串並繼續。

   halfbyte = data[i] & 0x0F; 

現在我們將整數設置爲等於來自字節和重複的低位。

同樣,如果我們的投入是23 ...在邏輯與成爲0000111之後的0001 0111,十進制爲7。重複與上述相同的邏輯並顯示字符'7'。

  } while(two_halfs++ < 1); 

現在我們繼續前進到數組中的下一個字節並重復。

 } 
    return buf.toString(); 
} 

要回答你的下一個問題,Java API已經有一個內置到BigInteger的基本轉換實用程序。請參閱toString(int radix)文檔。

不知道Java API使用的實現,我不能肯定地說,但我敢打賭,Java實現比您發佈的第一個稍微簡單的算法更有效。

+1

+1爲努力和擊敗我。我唯一要添加的是對按位操作文檔的引用:http://www.j2ee.me/docs/books/tutorial/java/nutsandbolts/op3.html – Welbog 2009-06-25 11:25:45

+0

感謝您的解釋 – 2009-06-25 11:28:00

1

有關bitshifting檢查出的答案在SO以下問題進行徹底的解釋 What are bitwise shift (bit-shift) operators and how do they work?

他似乎試圖一個單字節轉換成數小於16,通過這樣做,他可以輕鬆地確定至極caracther該字節與碼

if ((0 <= halfbyte) && (halfbyte <= 9)) 
       buf.append((char) ('0' + halfbyte)); 
      else 
       buf.append((char) ('a' + (halfbyte - 10))); 

這是一個簡單的回答表示,但即時通訊不是亮無論如何= d

2

要回答這個位:

爲什麼這項工作太

事實並非如此。至少,不像循環版本那樣。新的BigInteger(...)。toString(16)不會顯示前一個版本的前導零。通常對於寫出一個字節數組(特別是表示類似哈希的數組)的東西,你會需要一個固定長度的輸出,所以如果你想使用該版本,你必須適當地填充它。

0

這些東西,你不用自己來寫,因爲它已經被寫入Apache的公地編解碼器:

import org.apache.commons.codec.binary.Hex; 
... 
Hex.encodeHexString(byte[] array) 

有在Hex類多了很多有用的方法。