2011-12-02 92 views
1

我正在實施一個Cipher Block Chaining學校工作和問題要求的方法採取String並返回另一String。起初,我認爲這很奇怪,並且變量會更加適合,但仍然實施了一種方法。基本上,這裏是代碼:Java字節[]到字符串和UTF-8

static public String encode(String message) { 
    byte[] dataMessage = message.getBytes(); 
    ByteArrayOutputStream out = new ByteArrayOutputStream(); 

    byte last = (byte) (Math.random() * 256); 
    byte cur; 
    out.write(last); 

    for (byte b : data) { 
     cur = (byte) (b^last); 
     System.out.println("Encode '" + (char) b + "' = " + b + "^" + last + " > " + cur); 
     out.write(cur); 
     last = cur; 
    } 

    System.out.println("**ENCODED BYTES = " + Arrays.toString(out.toByteArray())); 
    System.out.println("**ENCODED STR = " + Arrays.toString(out.toString().getBytes())); 

    return out.toString(); 
} 

decode方法的工作原理類似。有些時候,方法會吐出像

Encode 'H' = 72^109 > 37 
Encode 'e' = 101^37 > 64 
Encode 'l' = 108^64 > 44 
Encode 'l' = 108^44 > 64 
Encode 'o' = 111^64 > 47 
**ENCODED BYTES = [109, 37, 64, 44, 64, 47] 
**ENCODED STR = [109, 37, 64, 44, 64, 47] 

結果,但有時也會吐的東西像

Encode 'H' = 72^-63 > -119 
Encode 'e' = 101^-119 > -20 
Encode 'l' = 108^-20 > -128 
Encode 'l' = 108^-128 > -20 
Encode 'o' = 111^-20 > -125 
**ENCODED BYTES = [-63, -119, -20, -128, -20, -125] 
**ENCODED STR = [-17, -65, -67, -17, -65, -67, -17, -65, -67, -17, -65, -67] 

我相信,這已經是與UTF-8(該系統的默認編碼),但我不夠熟悉究竟是爲什麼這樣的字符串會返回給定的字節。

回答

3

您不能採取任意字節序列並假定它是有效的UTF-8編碼字符串。因此,我懷疑toString方法(如documented,)會用平臺默認字符集的默認替換字符串替換格式錯誤的輸入和不可映射字符序列。

因此,您不應該將純粹的二進制數據轉換爲像這樣的字符串。使用像Hex或Base64這樣的編碼將字節轉換爲可打印的字符串,反之亦然。

Apache commons-codec有一個Base64工具類。

+0

是的,它替換每個字符序列(它們中的四個,UTF-8具有自同步屬性,使其跳過看起來像下一個多字節字符的開頭)被替換爲U + FFFD REPLACEMENT CHARACTER在UTF8中:0xef 0xbf 0xbd)。 – ninjalj

+0

是的,這是我認爲會發生的事情(關於替換角色)。然後我將使用Base64實現。 –

0

此:

out.toString().getBytes() 

不是做你的期望。它接受加密的字節並將這些字節解釋爲UTF-8編碼的字符串。然後它將該字符串中的字符轉換回字節。

你不能只是取任意的字節(在這種情況下,加密的數據),然後處理它,就好像它是UTF-8編碼的文本。