Base64.Decoder返回外来字符

时间:2018-04-12 22:16:00

标签: java utf-8 decoder encoder-decoder

我正在构建一个小应用程序,将文本文件中的文本转换为Base64,然后恢复正常。解码后的文本总是在第一行的开头返回一些中文字符。

public EncryptionEngine(File appFile){
    this.appFile= appFile;
}


public void encrypt(){

    try {
        byte[] fileText = Files.readAllBytes(appFile.toPath());// get file text as bytes

        Base64.Encoder encoder = Base64.getEncoder();
        PrintWriter writer = new PrintWriter(appFile);

        writer.print("");//erase old, readable text
        writer.print(encoder.encodeToString(fileText));// insert encoded text
        writer.close();


    } catch (IOException e) {

        e.printStackTrace();
    }

}

public void deycrpt(){

    try {
        byte[] fileText = Files.readAllBytes(appFile.toPath());

        String s = new String (fileText, StandardCharsets.UTF_8);//String s = new String (fileText);


        Base64.Decoder decoder = Base64.getDecoder();
        byte[] decodedByteArray = decoder.decode(s);

        PrintWriter writer = new PrintWriter(appFile);
        writer.print("");
        writer.print(new String (decodedByteArray,StandardCharsets.UTF_8)); //writer.print(new String (decodedByteArray));
        writer.close();


    } catch (IOException e) {

        e.printStackTrace();
    }



}

加密前的文本文件:(

干酪

番茄

马铃薯

火腿

纱线

加密后的文本文件() // 5jAGgAZQBlAHMAZQANAAoAdABvAG0AYQB0AG8AZQBzAA0ACgBwAG8AdABhAHQAbwBlAHMADQAKAGgAYQBtAHMADQAKAHkAYQBtAHMA

解密后的文本文件

뿯붿干酪

番茄

马铃薯

火腿

纱线

Before encrypt() :

After decrypt() :

2 个答案:

答案 0 :(得分:1)

您的加密和解密功能不会做出相同的假设。加密Base64编码任何文件,除了表明该文件是文本文件的变量名称和注释之外,它是正常的。它不一定是。

decrypt将Base64编码的数据反转回字节,然后" overprocesses"通过假设字节是用UTF-8进行文本编码然后解码然后在将它们写入文件之前重新编码它们。如果假设是真的,那就只是一个NOP;在你的情况下,它显然不正确,它会破坏数据。

也许你这样做是因为你试图使用PrintWriter。在Java(和.NET)中,多个流和文件I / O类经常令人困惑 - 特别是考虑到它们长达数十年的演变。有时会有一个完全符合您的需求,但很难找到;其他时候,没有。而且,有时候像Apache Commons这样的常用库填补了这个空白。

所以,只需将字节写入文件即可。在这个直接问题byte[] to file in Java的答案中解释了许多现代和历史选项。这是Files.write的一个:

Files.write(appFile.toPath(), decodedByteArray, StandardOpenOption.CREATE);

注意:虽然Base64可能在几百年前被认为是加密(和破解),但它并不是为了这个目的。如此称呼它有点危险(并且令人困惑)。

答案 1 :(得分:0)

您的输入文件是UTF-16,而不是UTF-8。它以{end}字节顺序标记FF FE开头。 StandardCharsets.UTF_16会正确处理此问题。 (或者,将文本编辑器设置为UTF-8而不是UTF-16。)

当您将fffe解码为UTF-8时,您有两个替换字符"��",一个用于UTF-8中无效的两个字节中的每一个。然后当您打印出来时,每个替换字符'�'在UTF-8中被编码为ef bf bd。然后你将结果解释为UTF-16,将它们分成两组,将其读作efbf bdef bfbd。文件的其余部分一直是UTF-16,但空字节将安全地往返。

(如果文件是ascii文本编码为UTF-16而没有字节顺序标记,你就不会注意到这有多么破碎!)