xOr 解密在整个文本文件中用错误的字母替换正确的字母
xOr decryption replaces correct letter with wrong letter throughout the whole text file
Java: 我正在使用键盘上任意两个 ASCII 字符的密钥对文本文件进行加密和解密。我让它们正常工作,除非我将加密文件读取为字符串进行解密。它用不同的错误字母替换了一些特定的字母,但并不是所有的正确字母都被替换了。例如,一些 t 被 s 替换。当我使用不同的密钥时,我还看到一些 b 被 e 替换了。
我已经查看了我的 encrypted/decryption 算法。我将加密的文本文件复制并粘贴到我的代码中,然后再次 运行 算法,结果很完美。唯一一次替换字母是在从要解密的文本文件中读取加密算法时。
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("[=10=]", 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;
}
当我使用密钥时 "ty"
"Four score and seven years ago our fathers brought forth on this" 是正确的措辞。
但是,我得到:"Four score and seven years ago our fashers broughs forth on this"
我会使用二进制文件来加密文本。它将使您免于处理 UTF-8 encoding/decoding 一些不寻常的代码点。例如 - 当您对 't' 和 't' 进行异或运算时,您会得到代码为 0.
的字符
您还可能会收到意想不到的换行符。您实际上将它们全部替换为 '\n'
,但还有其他选项 - '\r'
,甚至是序列中的两个字符 "\r\n"
。在你的代码中都会被'\n'替换,导致解密后出错。
这里发生了什么:
t
的二进制 ASCII(或 UTF-8)代码是 01110100
,y
是 01111001
。当键中的字符 y
遇到文本中的字符 t
时,您将得到 01110100 xor 01111001 = 00001101 = 0x0D = '\r'
。该字符被写入文件。当您逐行读取该文件时,此 '\r'
作为行分隔符被跳过。您将其替换为 '\n'=00001010
行
stream.forEach(s->builder.append(s).append("\n");
解密该文本时,我们得到 00001010 (\n) xor 01111001 (y) = 01110011 (s)
。
Java: 我正在使用键盘上任意两个 ASCII 字符的密钥对文本文件进行加密和解密。我让它们正常工作,除非我将加密文件读取为字符串进行解密。它用不同的错误字母替换了一些特定的字母,但并不是所有的正确字母都被替换了。例如,一些 t 被 s 替换。当我使用不同的密钥时,我还看到一些 b 被 e 替换了。
我已经查看了我的 encrypted/decryption 算法。我将加密的文本文件复制并粘贴到我的代码中,然后再次 运行 算法,结果很完美。唯一一次替换字母是在从要解密的文本文件中读取加密算法时。
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("[=10=]", 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;
}
当我使用密钥时 "ty"
"Four score and seven years ago our fathers brought forth on this" 是正确的措辞。 但是,我得到:"Four score and seven years ago our fashers broughs forth on this"
我会使用二进制文件来加密文本。它将使您免于处理 UTF-8 encoding/decoding 一些不寻常的代码点。例如 - 当您对 't' 和 't' 进行异或运算时,您会得到代码为 0.
的字符您还可能会收到意想不到的换行符。您实际上将它们全部替换为 '\n'
,但还有其他选项 - '\r'
,甚至是序列中的两个字符 "\r\n"
。在你的代码中都会被'\n'替换,导致解密后出错。
这里发生了什么:
t
的二进制 ASCII(或 UTF-8)代码是 01110100
,y
是 01111001
。当键中的字符 y
遇到文本中的字符 t
时,您将得到 01110100 xor 01111001 = 00001101 = 0x0D = '\r'
。该字符被写入文件。当您逐行读取该文件时,此 '\r'
作为行分隔符被跳过。您将其替换为 '\n'=00001010
行
stream.forEach(s->builder.append(s).append("\n");
解密该文本时,我们得到 00001010 (\n) xor 01111001 (y) = 01110011 (s)
。