2011-12-02 45 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编码的文本。