我有两个字符串
String s1="426F62";
String s2="457665";
字符串以十六进制表示。我想对他们进行异或。通常逐个字符的异或为除F XOR 6
以外的其他人提供正确的结果。(它给出112,答案应为9)
请告诉我在JAVA中实现它的正确方法
编辑:转换为int和xoring工作。但是当两个字符串长度不同时如何xor。
答案 0 :(得分:15)
不是对 Unicode 表示进行异或,而是将每个字符转换为它以十六进制表示的数字,将其转换为XOR,然后将其转换回十六进制。你仍然可以一次做一个角色:
public String xorHex(String a, String b) {
// TODO: Validation
char[] chars = new char[a.length()];
for (int i = 0; i < chars.length; i++) {
chars[i] = toHex(fromHex(a.charAt(i)) ^ fromHex(b.charAt(i)));
}
return new String(chars);
}
private static int fromHex(char c) {
if (c >= '0' && c <= '9') {
return c - '0';
}
if (c >= 'A' && c <= 'F') {
return c - 'A' + 10;
}
if (c >= 'a' && c <= 'f') {
return c - 'a' + 10;
}
throw new IllegalArgumentException();
}
private char toHex(int nybble) {
if (nybble < 0 || nybble > 15) {
throw new IllegalArgumentException();
}
return "0123456789ABCDEF".charAt(nybble);
}
请注意,这应该适用于字符串很长(只要它们的长度相同)并且永远不需要担心负值 - 您将始终只获得对每对字符进行异或的结果。
答案 1 :(得分:4)
试试这个:
String s1 = "426F62";
String s2 = "457665";
int n1 = Integer.parseInt(s1, 16);
int n2 = Integer.parseInt(s2, 16);
int n3 = n1 ^ n2;
String s3 = String.format("%06x", n3);
为什么要将十六进制值存储为字符串?将十六进制数表示为十六进制整数或长整数是个更好的主意。
答案 2 :(得分:3)
它给出正确结果的事实是数字和字母的特定字符编码的伪像。您应该将这些数字转换为BigInteger
,XOR
,并转换回String
:
BigInteger i1 = new BigInteger(s1, 16);
BigInteger i2 = new BigInteger(s2, 16);
BigInteger res = i1.xor(i2);
String s3 = res.toString(16);
编辑(响应Jon Skeet的评论):使用BigInteger
代替int
来解决四字节限制问题。
答案 3 :(得分:0)
另一个可能有用的选项取决于字符串的大小
String s1="426F62";
String s2="457665";
BigInteger one = new BigInteger(s1, 16);
BigInteger two = new BigInteger(s2, 16);
BigInteger three = one.xor(two);