我的XOR加密的java类实现出错了

时间:2012-01-17 22:43:05

标签: java encryption xor

我是java新手,但我对C ++和C#非常流利,尤其是C#。我知道如何在C#和C ++中进行xor加密。问题是我用Java编写的实现xor加密的算法似乎产生了错误的结果。结果通常是一堆空格,我确信这是错误的。这是下面的课程:

public final class Encrypter {

    public static String EncryptString(String input, String key)
    {


        int length;
        int index = 0, index2 = 0;
        byte[] ibytes = input.getBytes();
        byte[] kbytes = key.getBytes();
        length = kbytes.length;
        char[] output = new char[ibytes.length]; 
        for(byte b : ibytes)
        {
            if (index == length)
            {
                index = 0;

            }
            int val = (b ^ kbytes[index]);
            output[index2] = (char)val;
            index++;
            index2++;
        }


        return new String(output);
    }
    public static String DecryptString(String input, String key)
    {
        int length;
        int index = 0, index2 = 0;
        byte[] ibytes = input.getBytes();
        byte[] kbytes = key.getBytes();
        length = kbytes.length;
        char[] output = new char[ibytes.length]; 
        for(byte b : ibytes)
        {
            if (index == length)
            {
                index = 0;

            }
            int val = (b ^ kbytes[index]);
            output[index2] = (char)val;
            index++;
            index2++;
        }


        return new String(output);
    }
}

2 个答案:

答案 0 :(得分:2)

Java中的字符串是Unicode - 并且Unicode字符串不是像ASCII字符串那样的字节的通用持有者。

您正在使用字符串并将其转换为字节而不指定所需的字符编码,因此您将获得平台默认编码 - 可能是US-ASCII,UTF-8或其中一个Windows代码页。

然后,您将对这些字节执行算术/逻辑运算。 (我没看过你在这里做什么 - 你说你知道算法。)

最后,您将获取这些转换后的字节并尝试将它们转换回字符串 - 即返回字符。同样,你还没有指定字符编码(但你会得到与将字符转换为字节相同的结果,所以没关系),但最重要的是......

除非您的平台默认编码每个字符使用一个字节(例如US-ASCII),否则您生成的所有字节序列都不代表有效字符。

因此,有两条建议来自:

  1. 不要将字符串用作字节的通用持有者
  2. 在字节和字符之间进行转换时,始终指定字符编码。
  3. 在这种情况下,如果您专门提供US-ASCII作为编码,则可能会取得更大成功。编辑:这最后一句话不正确(见下面的评论)。请参阅上面的第1点!如果需要字节,请使用字节而不是字符。

答案 1 :(得分:0)

如果你使用非ascii字符串作为键,你会得到非常奇怪的结果。 kbytes数组中的字节将为负数。然后,符号扩展意味着val将变为负数。然后,转换为char将生成FF80-FFFF范围内的字符。

这些字符肯定不可打印,根据您用来检查输出的内容,您可能会显示“框”或其他一些替换字符。