0

如上所述,我在 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
4

2 回答 2

3

问题可能是因为XOR当解释为 UTF-16LE 字节序列时,针对随机数据的 ing 偶尔会产生不表达有效字符集的输出。

与其尝试将密文解释为 UTF-16LE 字符串,不如考虑在生成密文字节后仅对它们进行 base64 编码并返回生成的 base64 编码字符串。然后在解密时,对输入字符串进行 base64 解码以取回密文字节,执行 XOR 以获取您的明文字节,然后通过将明文字节解释为 UTF-16LE 序列从明文字节创建明文字符串。


更新以回复下面的评论,而不必担心空间不足。

正如我所说,您可以对密文字节进行 base64 编码。这在 Java 中当然是可行的。commons-codec 库有方法可以做到这一点,搜索会找到其他方法。如果您不允许使用外部库,请使用您自己的方法将任意字节转换为字节,以保证是某种有效的编码。

例如,您可以将密文中的每个字节分成高 4 位和低 4 位。因此,每个字节将产生一对值,每个值的范围为 0-15。'A'然后,您可以通过将 ASCII 代码添加到这些数字来从每个字节生成一个 2 字节序列。这不是很有效,但它可以完成工作。

于 2012-05-14T16:16:42.137 回答
0

如果语句在下面添加检查,您应该检查您的代码是否有 ArrayIndexOutOfBoundsException 错误,并且当我尝试像阿拉伯语这样的非英文字符时,它总是抛出 //XOR codebook 和 encryptedMessage System.out.println("This is the message using XOR:"); for(int i = 0; 我

            //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]+" ");
            }
        }
于 2012-05-14T16:49:14.517 回答