【问题标题】:XOR function for two Hex byte arrays两个十六进制字节数组的异或函数
【发布时间】:2014-01-15 04:09:39
【问题描述】:

我正在尝试执行两个字节数组的异或运算并将结果作为十六进制字符串返回。我已经将两个字节数组转换为它们对应的二进制字符串。每个字节都有位,因为它有 8 个字节。

byte[] key =  { 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18 };
byte[] PAN =  { 0x12, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x23 };

到目前为止,我使用了一种将字节数组转换为相应的二进制字符串值的方法,例如“10101010101”。但是,当我执行下面的方法来获取 XOR 时,我会返回一串笑脸,这可能是一些特殊的 ASCII 字符。

但是我不知道如何做到这一点。我正在考虑将二进制字符串转换为整数,但这不是一个好的解决方案,因为它不适合作为整数。

请问您有什么想法吗?可能有一些示例代码?

public static string exclusiveOR(string string_1, string string_2)
{
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < string_1.Length; i++)
        sb.Append((char)(string_1[i] ^ string_2[(i % string_2.Length)]));
        String result = sb.ToString();

        return result;
}

【问题讨论】:

  • 看起来您正在计算字符的异或。我认为这仅在您的字符串包含 Char(0) 和 Char(1) 值时才有效。
  • 我的字符串只包含 0 和 1 但仍然不起作用
  • 它是否包含字符 0 或 Char(0)?因为字符 0 的 ASCII 值是 48。对于 1 也是如此,它是 ASCII 值 49
  • 给我们一个示例输入和预期输出的例子。
  • 而不是 string_1[i] 使用 Convert.ToInt32(string_1[i],16) 和其他字符的相同转换。并使用 ToString("X") 而不是字符转换将为您提供 HEX 字符串。

标签: c# string hex logic xor


【解决方案1】:

试试这个:

public static string exclusiveOR(byte[] key, byte[] PAN)
{
    if (key.Length == PAN.Length)
    {
        byte[] result = new byte[key.Length];
        for (int i = 0; i < key.Length; i++)
        {
            result[i] = (byte)(key[i] ^ PAN[i]);
        }
        string hex = BitConverter.ToString(result).Replace("-", "");
        return hex;
    }
    else
    {
        throw new ArgumentException();
    }
}

这是如何工作的:首先检查数组是否具有相同的长度,如果是这种情况,您将对数组执行 XOR 操作。 BitConverter.ToString() 方法将字节数组转换为字符串,但由于每个十六进制数之间用连字符隔开,您可以使用Replace() 方法去除这些破折号。

【讨论】:

    【解决方案2】:

    IMO 最好将其分成两部分。一个函数进行分段异或,另一个函数将字节数组转换为十六进制字符串。

    public static byte[] exclusiveOR(byte[] arr1, byte[] arr2)
    {
        if (arr1.Length != arr2.Length)
            throw new ArgumentException("arr1 and arr2 are not the same length");
    
        byte[] result = new byte[arr1.Length];
    
        for (int i = 0; i < arr1.Length; ++i)
            result[i] = (byte) (arr1[i] ^ arr2[i]);
    
        return result;
    }
    
    public static string arrayToHexString(byte[] arr)
    {
        var sb = new StringBuilder();
        for (int i = 0; i < arr.Length; ++i)
            sb.Append(arr[i].ToString("x2"));
        return sb.ToString();
    }
    

    现在你可以说:

    Console.WriteLine(arrayToHexString(exclusiveOR(arr1, arr2)));
    

    您的解决方案打印奇怪字符的原因是您对 ASCII 值 '1''0' 进行异或运算,因为这些是字符串中的字符。因为'1' 是0x31 而'0' 是0x30,所以结果是0x30 xor 0x31 = 1。然后您将ASCII 字符0x01(这是一个不可打印的控制字符)放入您的结果字符串中。

    【讨论】:

    • 感谢您的回复....现在工作正常。我只会尝试在每四个字符之后添加“-”符号以使其像这样,例如0x1234-1234-1234-1234.
    • @Abatonime 否:for 循环的迭代语句 ++i 直到循环体运行后才被评估。至于为什么++i而不是i++,见this question。在这里没有区别,但为了养成良好的习惯,我总是预先增加,除非有特定的后期增加需要。
    【解决方案3】:

    我认为string 是错误的类型。相反,您应该使用BitArray,它甚至已经有了Xor() 方法。

    【讨论】:

      【解决方案4】:

      您这样做是正确的 - 您的代码 XORs 两个字符串的字符,如果第一个恰好是较长的字符串,则环绕第二个。

      但是,XOR 的特性是只有不同的位在输出中保持设置。因此,当你对0x110x12 进行异或运算时,你最终会得到0x03,当显示在控制台上时,looks like a heart

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-08
        • 1970-01-01
        • 2018-02-28
        • 2012-04-16
        • 2013-06-28
        相关资源
        最近更新 更多