如上所述,我在Java中遇到UTF-16LE问题。当我运行我的代码时,它通常会正确地加密,解密和打印消息。有时它会丢失两个加密字符,有时会打印出非英语字符,如希腊语等。
这是一个课程,它确实让我的教授感到遗憾,任何帮助都会对错误表示赞赏。
/*This program was written by me for my professors class.
该程序的目的是使用XOR加密来加密消息, 以相同的方式解密它以生成这些方法的码本。* /
import java.security.*;
public class Crypto
{
public static void main(String[] args) throws Exception
{
Crypto c = new Crypto();
byte[]codebook = null;
String message = "";
System.out.println("Generating codebook");
codebook = c.makeCodebook(14);
System.out.println();
System.out.println("Now Encrypting");
System.out.println("This is the contents of the Encrypted Message: ");
message = c.crypt("1234567", codebook);
System.out.println();
System.out.println("Now Decrypting");
System.out.println("This is the contents of the Decrypted Message");
message = c.crypt(message, codebook);
System.out.println();
System.out.println("Your message is: ");
System.out.println(message);
}//publis static void main(String [] args)
//Encrypts or decrypts message against the codebook assuming the appropriate length
public String crypt (String message, byte [] codebook) throws Exception
{
//Take the message and put it into an array of bytes.
//This array of bytes is what will be XORed against the codebook
byte[] cryptedMessage = message.getBytes("UTF-16LE");
byte[] result = new byte[14];
message = "";
System.out.println(message.length());
System.out.println(cryptedMessage.length);
System.out.println(result.length);
//Let's see the contents of encryptedMessage
for(int i = 0; i< cryptedMessage.length; i++)
{
System.out.print(cryptedMessage[i]+" ");
}//for(int i = 0; i< encryptedMessage.length; i++)
System.out.println();
//XOR codebook and encryptedMessage
System.out.println("This is the message using XOR:");
for(int i = 0; i<result.length; i++)
{
//since XOR has return type of an int, we cast it to a byte
result[i] = (byte)(((byte)(codebook[i])) ^ ((byte)(cryptedMessage[i])));
System.out.print(result[i]+" ");
}//while(result[i]!=0)
//output
System.out.println();
//output
System.out.println(message.length());
System.out.println(cryptedMessage.length);
System.out.println(result.length);
return new String(result, "UTF-16LE");
}//public String crypt (String message, byte [] codebook) throws Exception
//Creates truly random numbers and makes a byte array using those truly random numbers
public byte [] makeCodebook (int length) throws Exception
{
SecureRandom SecureRandom = new SecureRandom();//instance of SecureRandom named random
byte[] codebook = null;
codebook = new byte[length];
SecureRandom.nextBytes(codebook);//generate bytes using the byte[]codebook
//output
System.out.println("This is the contents of the codebook: ");
for(int i = 0; i < codebook.length;i++)
{
System.out.print(codebook[i]+" ");
}//for(int i = 0; i < codebook[i];i++)
//output
System.out.println();
return codebook;
}//public byte [] MakeCodebook (int length) throws Exception
}//Public class Crypto
答案 0 :(得分:3)
问题可能是因为XOR
对随机数据偶尔产生的输出在解释为UTF-16LE字节序列时不表示有效的字符集。
不要试图将密文解释为UTF-16LE字符串,而应考虑在生成密文字节后对密文字节进行base64编码并返回生成的base64编码字符串。然后在解密时,对输入字符串进行base64解码以获取密文字节,执行XOR以获取明文字节,然后通过将明文字节解释为UTF-16LE序列,从明文字节创建明文字符串。
已更新,可以回复以下评论,而无需担心空间不足。
正如我所说,你可以对密文字节进行base64编码。这在Java中肯定是可行的。 commons-codec库有方法可以执行,搜索可以找到其他库。如果您不允许使用外部库,那么请将您自己的将任意字节转换为字节的方法保证为某些内容的有效编码。
例如,您可以将密文中的每个字节拆分为高4位和低4位。因此,每个字节将产生一对值,每个值的范围为0-15。然后,您可以通过将'A'
的ASCII代码添加到这些数字,从每个字节生成一个2字节的序列。这不是很有效,但它可以完成这项工作。
答案 1 :(得分:0)
你应该检查你的代码 ArrayIndexOutOfBoundsException错误 如果在下面添加了检查 当我尝试像阿拉伯语这样的非英语角色时,它总是被抛出 // XOR codebook和encryptedMessage System.out.println(“这是使用XOR的消息:”); for(int i = 0; i
//since XOR has return type of an int, we cast it to a byte
if(result.length<=cryptedMessage.length){
result[i] = (byte)(((byte)(codebook[i])) ^ ((byte)(cryptedMessage[i])));
System.out.print(result[i]+" ");
}
}