2010-06-11 88 views
1

我有這樣的僞代碼在java中:從字符串爲十六進制的MD5哈希和背部

bytes[] hash = MD5.hash("example"); 

String hexString = toHexString(hash); //This returns something like a0394dbe93f 

bytes[] hexBytes = hexString.getBytes("UTF-8"); 

現在,hexBytes[]hash[]是不同的。

我知道我做錯了什麼,因爲hash.length()是16,而hexBytes.length()是32.也許它與java使用Unicode的字符有關(這裏只是一個瘋狂的猜測)。

不管怎麼說,問題是:如何從hexString獲得原始hash[]數組。

整個代碼是在這裏,如果你想看看它(這是〜40 LOC)http://gist.github.com/434466

代碼的輸出是:

16 
[-24, 32, -69, 74, -70, 90, -41, 76, 90, 111, -15, -84, -95, 102, 65, -10] 
32 
[101, 56, 50, 48, 98, 98, 52, 97, 98, 97, 53, 97, 100, 55, 52, 99, 53, 97, 54, 102, 102, 49, 97, 99, 97, 49, 54, 54, 52, 49, 102, 54] 

非常感謝!

回答

2

您是剛開始的十六進制字符串的字節與hexString.getBytes("UTF-8");,不轉換十六進制數字到他們的字節值。

也就是說,您需要編寫您的toHexString函數的反向。 您的toHexString應該確保格式化值低於10到2位數,例如字節9結束爲「09」而不是「9」。

2

你沒有顯示toHexString,但基本上你需要反向等價物 - 尋找一種叫做fromHexString或類似的方法。

基本上String.getBytes()執行正常編碼(在這種情況下在UTF-8)。您想要將解碼爲文本 - 這是任意二進制數據的文本表示 - 轉換爲byte[]

Apache Commons Codec有適當的方法 - 該API並不理想,但它的工作:

byte[] data = ...; 
String hex = Hex.encodeHexString(data); 
... 

byte[] decoded = (byte[]) Hex.decode(hex); 
+0

代碼是我掛HTTP要點://gist.github .com/434466(儘管名稱不同)。謝謝,我會考慮Apache Commons – 2010-06-11 13:49:02

+0

只是好奇......你爲什麼說API不理想? – 2010-06-11 13:55:58

+0

@Pablo:理想情況下,應該有一個採用 字符串並返回強類型的字節數組的Hex.decode方法。 「Object decode(Object)'簽名很煩人。 – 2010-06-11 14:26:16

1

getBytes()不分析十六進制字符,它處理字符編碼。換句話說,它不會將'0A'變成0x0A,而是變成0x30 0x41,因爲這就是字符'0'和'A'被編碼的方式。您需要在您的函數中使用Integer.parseInt(String, radix)而不是基數== 16。

1

如果你不想使用一個庫,這裏是你怎麼能和我的版本的十六進制解碼器的做到這一點,

byte[] hexBytes = dehexify(hexString); 

public static byte[] dehexify(String hexString) { 
    if (hexString.length()%2 == 1) 
     throw new IllegalArgumentException("Invalid length");  
    int len = hexString.length()/2; 
    byte[] bytes = new byte[len]; 
    for (int i=0; i<len; i++) { 
     int index = i*2; 
     bytes[i] = (byte)Integer.parseInt(hexString.substring(index, index+2), 16); 
    } 
    return bytes; 
} 
相關問題