我是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);
}
}
答案 0 :(得分:2)
Java中的字符串是Unicode - 并且Unicode字符串不是像ASCII字符串那样的字节的通用持有者。
您正在使用字符串并将其转换为字节而不指定所需的字符编码,因此您将获得平台默认编码 - 可能是US-ASCII,UTF-8或其中一个Windows代码页。
然后,您将对这些字节执行算术/逻辑运算。 (我没看过你在这里做什么 - 你说你知道算法。)
最后,您将获取这些转换后的字节并尝试将它们转换回字符串 - 即返回字符。同样,你还没有指定字符编码(但你会得到与将字符转换为字节相同的结果,所以没关系),但最重要的是......
除非您的平台默认编码每个字符使用一个字节(例如US-ASCII),否则您生成的所有字节序列都不代表有效字符。
因此,有两条建议来自:
在这种情况下,如果您专门提供US-ASCII作为编码,则可能会取得更大成功。编辑:这最后一句话不正确(见下面的评论)。请参阅上面的第1点!如果需要字节,请使用字节而不是字符。
答案 1 :(得分:0)
如果你使用非ascii字符串作为键,你会得到非常奇怪的结果。 kbytes数组中的字节将为负数。然后,符号扩展意味着val将变为负数。然后,转换为char将生成FF80-FFFF范围内的字符。
这些字符肯定不可打印,根据您用来检查输出的内容,您可能会显示“框”或其他一些替换字符。