不同长度的JAVA中的XOR Hex String

时间:2012-03-23 14:11:39

标签: java cryptography

我有两个字符串

String s1="426F62";
String s2="457665";

字符串以十六进制表示。我想对他们进行异或。通常逐个字符的异或为除F XOR 6以外的其他人提供正确的结果。(它给出112,答案应为9)

请告诉我在JAVA中实现它的正确方法

编辑:转换为int和xoring工作。但是当两个字符串长度不同时如何xor。

4 个答案:

答案 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)

它给出正确结果的事实是数字和字母的特定字符编码的伪像。您应该将这些数字转换为BigIntegerXOR,并转换回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);