我正在构建一个小应用程序,将文本文件中的文本转换为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
解密后的文本文件
뿯붿干酪
番茄
马铃薯
火腿
纱线
答案 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而没有字节顺序标记,你就不会注意到这有多么破碎!)