Java xOr解密在整个文本文件中将正确的字母替换为错误的字母

Java xOr解密在整个文本文件中将正确的字母替换为错误的字母,java,binary,readfile,xor,writefile,Java,Binary,Readfile,Xor,Writefile,Java:我使用键盘上任意两个ASCII字符的密钥加密和解密文本文件。我让它们正常工作,除非我将加密文件读取为字符串进行解密。它用不同的错误字母替换某些特定字母,但并非所有正确字母都被替换。例如,一些t被s取代。我还看到当我使用不同的钥匙时,一些b被e替换 我已经检查了我的加密/解密算法。我复制并粘贴加密的文本文件到我的代码中,然后再次运行算法,结果非常完美。替换字母的唯一时间是从要解密的文本文件中读取加密算法时 public static String readFileToString(str

Java:我使用键盘上任意两个ASCII字符的密钥加密和解密文本文件。我让它们正常工作,除非我将加密文件读取为字符串进行解密。它用不同的错误字母替换某些特定字母,但并非所有正确字母都被替换。例如,一些t被s取代。我还看到当我使用不同的钥匙时,一些b被e替换

我已经检查了我的加密/解密算法。我复制并粘贴加密的文本文件到我的代码中,然后再次运行算法,结果非常完美。替换字母的唯一时间是从要解密的文本文件中读取加密算法时

public static String readFileToString(string filePath) {
    StringBuilder builder = new StringBuilder();
    try (Stream<String> stream = Files.get(filePath), StandardCharsets.UTF_8)){
        stream.forEach(s->builder.append(s).append("\n");
    }
    catch(IOException e){
        e.printStackTrace();
    }
    return builder.toString();
}

public static void writeFile(String crypt) throws IOException {
    Scanner sc = new Scanner(System.in);
    System.out.println("New file name: ");
    String fileName = sc.nextLine();
    String writtenString = crypt;
    String userHome = System.getProperty("user.home");
    File textFile = new File(userHome, fileName + ".txt");
    BufferedWriter out = new BufferedWriter(new FileWriter(textFile));
    out.write(writtenString);
    out.close();

//Converts string and key into binary characters for 1-to-1 xOr to prevent any possible translation errors.
public static String crypt(String input, String key) throws UnsupportedEncodingException {
    if (input.length() % 2 == 1) {
        input = input + " ";
    }
    int n = input.length() / 2;
    key = new String(new char[n]).replace("\0", key);
    byte[] a = input.getBytes();
    byte[] c = key.getBytes();
    StringBuilder binaryBuilder = new StringBuilder();
    StringBuilder binaryKeyBuilder = new StringBuilder();
    //Creates a StringBuilder of bits using the file text
    for(byte b: a) {
        int value = b;
        for(int i = 0; i < 8; i++) {
            binaryBuilder.append((value & 128) == 0 ? 0 : 1);
            value <<= 1;
        }
        binaryBuilder.append(' ');
    }
    //Converts binary StringBuilder to String
    String binary = binaryBuilder.toString();
    //Creates a StringBuilder of bits using the provided key
    for(byte d: c) {
        int keyValue = d;
        for(int j = 0; j < 8; j++) {
            binaryKeyBuilder.append((keyValue & 128) == 0 ? 0 : 1);
            keyValue <<= 1;
        }
        binaryKeyBuilder.append(' ');
    }
    //Converts binaryKey StringBuilder to String
    String binaryKey = binaryKeyBuilder.toString();
    //Creates StringBuilder of bits using the provided key
    StringBuilder xOr = new StringBuilder();
    for(int q = 0; q < binary.length();q++) {
        xOr.append(binary.charAt(q) ^ binaryKey.charAt(q));
    }
    String xOrResult = xOr.toString();
    String cryptedString = "";
    char next;
    //Iterates through binary string to convert to ASCII characters 8 bits at a time.
    for(int k = 0; k <= xOrResult.length()-8; k+=9) {
        next = (char)Integer.parseInt(xOrResult.substring(k,k+8), 2);
        cryptedString += next;
    }
    return cryptedString;
}
公共静态字符串readFileToString(字符串文件路径){
StringBuilder=新的StringBuilder();
try(Stream=Files.get(filePath),StandardCharsets.UTF_8)){
stream.forEach->builder.append.append(“\n”);
}
捕获(IOE异常){
e、 printStackTrace();
}
返回builder.toString();
}
公共静态void writeFile(字符串加密)引发IOException{
扫描仪sc=新的扫描仪(System.in);
System.out.println(“新文件名:”);
字符串文件名=sc.nextLine();
String writtenString=crypt;
字符串userHome=System.getProperty(“user.home”);
File textFile=新文件(userHome,fileName+“.txt”);
BufferedWriter out=新的BufferedWriter(新的文件写入程序(textFile));
out.write(writeString);
out.close();
//将字符串和键转换为1对1异或的二进制字符,以防止任何可能的翻译错误。
公共静态字符串加密(字符串输入,字符串键)引发UnsupportedEncodingException{
if(input.length()%2==1){
输入=输入+“”;
}
int n=input.length()/2;
key=新字符串(新字符[n])。替换(“\0”,key);
字节[]a=input.getBytes();
字节[]c=key.getBytes();
StringBuilder binaryBuilder=新的StringBuilder();
StringBuilder binaryKeyBuilder=新StringBuilder();
//使用文件文本创建位的StringBuilder
for(字节b:a){
int值=b;
对于(int i=0;i<8;i++){
追加((值&128)==0?0:1);

value我将使用二进制文件来加密文本。它将使您免于处理UTF-8编码/解码一些不寻常的代码点。例如,当您对“t”和“t”进行异或时,您将获得代码为0的字符

您还可以获得意外的新行字符。实际上,您可以将所有字符替换为
'\n'
,但还有其他选项-
'\r'
,甚至是序列中的两个字符
“\r\n”
。所有字符都将在代码中替换为'\n',解密后会导致错误

这里发生了什么:

二进制ASCII(或UTF-8)
t
的代码是
01110100
,而
y
的代码是
01111001
。当键中的字符
y
与文本中的字符
t
相遇时,您会得到
0111010100 xor 01111001=00001101=0x0D='\r'
。这个字符会写入文件。当您逐行读取该文件时,这个
'\r'
is作为行分隔符跳过。您将其替换为行中的
'\n'=00001010

stream.forEach(s->builder.append(s).append("\n");

当解密该文本时,我们得到
00001010(\n)xor 011110001(y)=011110011(s)
,我将使用二进制文件进行加密文本。它将使您不必处理UTF-8编码/解码一些不寻常的代码点。例如,当xor“t”和“t”时,您将获得代码为0的字符

您还可以获得意外的新行字符。实际上,您可以将所有字符替换为
'\n'
,但还有其他选项-
'\r'
,甚至是序列中的两个字符
“\r\n”
。所有字符都将在代码中替换为'\n',解密后会导致错误

这里发生了什么:

二进制ASCII(或UTF-8)
t
的代码是
01110100
,而
y
的代码是
01111001
。当键中的字符
y
与文本中的字符
t
相遇时,您会得到
0111010100 xor 01111001=00001101=0x0D='\r'
。这个字符会写入文件。当您逐行读取该文件时,这个
'\r'
is作为行分隔符跳过。您将其替换为行中的
'\n'=00001010

stream.forEach(s->builder.append(s).append("\n");

解密该文本时,我们得到
00001010(\n)xor 01111001(y)=011110011(s)

从您问题中的代码来看,没有加密/解密。我不认为我需要显示它,因为它在不读取或写入文件的情况下工作,但我要补充一点,如果您只显示问题代码的一部分,您希望人们如何帮助调试您的代码?任何阅读标题的读者都希望看到加密/说明代码…从你问题中的代码来看,没有加密/解密。我不认为我需要显示它,因为它在不读取或写入文件的情况下工作,但我要补充一点,如果你只显示问题代码的一部分,你希望人们如何帮助调试你的代码?任何阅读标题的读者都希望看到加密/说明代码…你呢是否要保存加密文本,使其在文本文件中以二进制形式显示?因为需要显示的加密文本文件是ASCII字符。好吧,至少要将整个文件作为单个字符串读取,而不将其拆分为行。请看以下内容,例如:是否要保存加密文本,使其在文本文件中以二进制形式显示?Bec因为需要显示的加密文本文件是ASCII字符。好吧,至少要将整个文件作为一个字符串读取,而不要将其拆分为行。例如: