不同长度的JAVA中的XOR Hex String

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9840675/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-16 08:25:49  来源:igfitidea点击:

XOR Hex String in JAVA of different length

javacryptography

提问by dejavu

I have two strings

我有两个字符串

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

The strings are in hex representation. I want to XOR them. XORing normally character by character gives the correct result for others except F XOR 6.(It gives 112, the answer should be 9)

字符串以十六进制表示。我想对它们进行异或。正常逐字符异或给出正确的结果,除了F XOR 6.(它给出 112,答案应该是 9)

Please tell me the correct way to implement it in JAVA

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

EDIT: Converting to int and xoring works. But how to xor when two strings are of different length.

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

采纳答案by Jon Skeet

Rather than XORing the Unicoderepresentations, just convert each character into the number it represents in hex, XOR those, then convert it back to hex. You can still do that one character at a time:

而不是对Unicode表示进行异或,只需将每个字符转换为它以十六进制表示的数字,对这些数字进行异或,然后将其转换回十六进制。你仍然可以一次做一个角色:

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);
}

Note that this should work however long the strings are (so long as they're the same length) and never needs to worry about negative values - you'll always just get the result of XORing each pair of characters.

请注意,无论字符串有多长(只要它们的长度相同),这都应该有效,并且永远不需要担心负值 - 您总是会得到每对字符的异或结果。

回答by dasblinkenlight

The fact that it gives correct result is an artifact of the particular character encoding for digits and letters. You should convert the numbers to BigInteger, XORthem, and convert back to String:

它给出正确结果的事实是数字和字母的特定字符编码的产物。您应该将数字转换为BigIntegerXOR它们,然后转换回String

BigInteger i1 = new BigInteger(s1, 16);
BigInteger i2 = new BigInteger(s2, 16);
BigInteger res = i1.xor(i2);
String s3 = res.toString(16);

EDIT(in response to Jon Skeet's comment): Using BigIntegerinstead of intto address the four-byte limit issue.

编辑(回应 Jon Skeet 的评论):使用BigInteger而不是int解决四字节限制问题。

回答by óscar López

Try this:

尝试这个:

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);

Why are you storing hex values as strings? it'd be a much better idea to represent hex numbers as hex integers or longs.

为什么将十六进制值存储为字符串?将十六进制数字表示为十六进制整数或长整数会更好。

回答by Edwin Dalorzo

Another option that could be helpful depending on the size of the strings

另一个可能有用的选项取决于字符串的大小

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

BigInteger one = new BigInteger(s1, 16);
BigInteger two = new BigInteger(s2, 16);
BigInteger three = one.xor(two);