use*_*257 50
你想要这样的东西:
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import java.io.IOException;
public class StringXORer {
public String encode(String s, String key) {
return base64Encode(xorWithKey(s.getBytes(), key.getBytes()));
}
public String decode(String s, String key) {
return new String(xorWithKey(base64Decode(s), key.getBytes()));
}
private byte[] xorWithKey(byte[] a, byte[] key) {
byte[] out = new byte[a.length];
for (int i = 0; i < a.length; i++) {
out[i] = (byte) (a[i] ^ key[i%key.length]);
}
return out;
}
private byte[] base64Decode(String s) {
try {
BASE64Decoder d = new BASE64Decoder();
return d.decodeBuffer(s);
} catch (IOException e) {throw new RuntimeException(e);}
}
private String base64Encode(byte[] bytes) {
BASE64Encoder enc = new BASE64Encoder();
return enc.encode(bytes).replaceAll("\\s", "");
}
}
Run Code Online (Sandbox Code Playgroud)
完成base64编码是因为xor'ing字符串的字节可能不会为字符串返回有效字节.
Pet*_*rey 27
注意:这仅适用于低字符,即低于0x8000,这适用于所有ASCII字符.
我会为每个charAt()做一个XOR来创建一个新的String.喜欢
String s, key;
StringBuilder sb = new StringBuilder();
for(int i = 0; i < s.length(); i++)
sb.append((char)(s.charAt(i) ^ key.charAt(i % key.length())));
String result = sb.toString();
Run Code Online (Sandbox Code Playgroud)
回应@ user467257的评论
如果你的输入/输出是utf-8而你是"a"和"æ",你将留下一个无效的utf-8字符串,由一个字符组成(十进制135,一个连续字符).
它是char被xor'ed 的值,但字节值和这产生一个UTF-8编码的字符.
public static void main(String... args) throws UnsupportedEncodingException {
char ch1 = 'a';
char ch2 = 'æ';
char ch3 = (char) (ch1 ^ ch2);
System.out.println((int) ch3 + " UTF-8 encoded is " + Arrays.toString(String.valueOf(ch3).getBytes("UTF-8")));
}
Run Code Online (Sandbox Code Playgroud)
版画
135 UTF-8 encoded is [-62, -121]
Run Code Online (Sandbox Code Playgroud)
Paŭ*_*ann 17
请注意:
Java char对应于UTF-16代码单元,在某些情况下,一个真正的Unicode字符(代码点)需要两个连续的chars(所谓的代理对).
异或两个有效的UTF-16序列(即Java字符串char通过char,或逐字节编码后,UTF-16)并不一定会给你另一个有效的UTF-16字符串-你可能有未配对的替代品作为一个结果.(它仍然是一个完全可用的Java字符串,只是与代码点有关的方法可能会混淆,而那些转换为其他编码的输出和类似的.)
如果你首先将你的字符串转换为UTF-8然后将这些字节转换为XOR,那么同样有效 - 如果你的字符串不是纯ASCII字符串,那么你很可能会得到一个无效的UTF-8字节序列.
即使您尝试正确执行并通过代码点迭代两个字符串并尝试对代码点进行异或,您也可以得到有效范围之外的代码点(例如,U+FFFFF(平面15)XOR U+10000(平面16)= U+1FFFFF(这将是最后一个)平面的特征31),高于现有代码点的范围.你也可以用代理点保留的代码点(=无效的代码点)结束这种方式.
如果您的字符串只包含字符<128,256,512,1024,2048,4096,8192,16384或32768,那么(字符方式)XORed字符串将在相同的范围内,因此当然不包含任何代理项.在前两种情况下,您还可以将String编码为ASCII或Latin-1,并对字节具有相同的XOR结果.(你仍然可能最终得到控制字符,这对你来说可能是一个问题.)
我在这里最后说的是:不要指望将字符串加密的结果再次成为有效的字符串 - 而是简单地将其存储并作为byte[](或字节流)传输.(是的,在加密前转换为UTF-8,在解密后转换为UTF-8).
假设(!)字符串长度相等,为什么不将字符串转换为字节数组,然后对字节进行异或。根据您的编码,生成的字节数组也可能具有不同的长度(例如,UTF8 将针对不同的字符扩展为不同的字节长度)。
您应该小心指定字符编码以确保一致/可靠的字符串/字节转换。
| 归档时间: |
|
| 查看次数: |
94137 次 |
| 最近记录: |