【问题标题】:how to perform xor operation correctly?如何正确执行异或运算?
【发布时间】:2016-09-06 11:16:50
【问题描述】:

我有一个二进制字符串,我想对该字符串的几个位执行异或运算。 我的字符串是:

011001100011100000000011

我正在尝试使用下一行代码执行计算:

private String ParityCalc(String str){
    char[] cA = str.toCharArray();
    int[] D = new int[6];
    D[0] = D29^cA[0]^cA[1]^cA[2]^cA[4]^cA[5]^cA[9]^cA[10]^cA[11]^cA[12]^cA[13]^cA[16]^cA[17]^cA[19]^cA[22];
    D[1] = D30^cA[1]^cA[2]^cA[3]^cA[5]^cA[6]^cA[10]^cA[11]^cA[12]^cA[13]^cA[14]^cA[17]^cA[18]^cA[20]^cA[23];
    D[2] = D29^cA[0]^cA[2]^cA[3]^cA[4]^cA[6]^cA[7]^cA[11]^cA[12]^cA[13]^cA[14]^cA[15]^cA[18]^cA[19]^cA[21];
    D[3] = D30^cA[1]^cA[3]^cA[4]^cA[5]^cA[7]^cA[8]^cA[12]^cA[13]^cA[14]^cA[15]^cA[16]^cA[19]^cA[20]^cA[22];
    D[4] = D30^cA[0]^cA[2]^cA[4]^cA[5]^cA[6]^cA[8]^cA[9]^cA[13]^cA[14]^cA[15]^cA[16]^cA[17]^cA[20]^cA[21]^cA[23];
    D[5] = D29^cA[2]^cA[4]^cA[5]^cA[7]^cA[8]^cA[9]^cA[10]^cA[12]^cA[14]^cA[18]^cA[21]^cA[22]^cA[23];
    for (int i = 0; i < 6; i++){
        if (D[i] == 48){
            D[i] = 0;
        } else if (D[i] == 49){
            D[i] = 1;
        }
    }
    StringBuilder parity = new StringBuilder();
    parity.append(D[0]).append(D[1]).append(D[2]).append(D[3]).append(D[4]).append(D[5]);
    D29 = D[4];
    D30 = D[5];
    return parity.toString();
}

我得到的最终奇偶校验结果是:100000。 正确的结果应该是:001001。

D29 和 D30 是之前计算的奇偶校验位,都是整数。

我做错了什么,我该如何解决?我可能应该将其作为按位运算进行,但我似乎无法弄清楚。 任何帮助将不胜感激。

【问题讨论】:

  • 为什么不把字符串转成整数再做一次呢?
  • 因为操作在几个位上是连续的。你会怎么做呢?
  • 首先,可以将原始二进制字符串转换为整数,也可以将要提取的特定位构造为另一个整数。这取决于。
  • 为了说清楚,假设原来的二进制字符串是A,A的几位构造B,现在可以通过移位0x1正确地做因子,做异或操作。
  • 可以说我将使用Interger.parseInt(str) 将字符串转换为整数,那么我将如何在不同的位上执行异或?你能举个例子吗?

标签: java bit-manipulation xor parity bitwise-xor


【解决方案1】:

我试过下面的代码,它是你想要的吗?

public static void xor () {
    final String a = "011001100011100000000011";
    final String b = a.substring(3, 7);
    final long ai = Long.parseLong(a, 2);
    final long bi = Long.parseLong(b, 2);
    final long la = Long.toBinaryString(ai).length();
    final long lb = Long.toBinaryString(bi).length();
    long i,j,fa,fb,fo,result = ai;
    for (i = 0; i < lb; ++ i) {
        // get most significant bit one by one; a
        fb = 1l & (bi >> (lb - i - 1l));
        for (j = 0; j < la; ++ j) {
            // get most significant bit one by one; b
            fa = 1l & (ai >> (la - j - 1l));
            // one ^ one
            fo = fa ^ fb;
            if (0 == fo) {
                // & 0
                result &= ((-1l << la - j) | ((1l << (la - j - 1)) - 1));
            } else {
                // | 1
                result |= (1l << (la - j - 1l));
            }
        }
    }
    System.out.println(result);
}

解决方案:

对两个二进制字符串的每个位进行异或(将转换为整数)并将每个位重置为从原始二进制字符串转换的原始整数(可以是新整数,视情况而定)。

如果有任何问题,请告诉我。

【讨论】:

  • 我尝试按原样运行此代码,但它什么也没做。结果最终等于 ai 参数。这很奇怪。
  • 这个例子可以帮助你理解位操作。尽情享受吧。
【解决方案2】:

这将是我的方法:

private String ParityCalc(String str){
    int input = Integer.parseInt(str,2);
    int[] D = new int[6];
    D[0] = input & (int)0x4b3e37; // Mask for indices 0,1,2,4,5,9,10,11,12,13,16,17,19,22
    D[0] = (Integer.bitCount(D[0])&0x1)^D29; // Parity of masked input XOR D29

// D[1-5] accordingly

    StringBuilder parity = new StringBuilder();
    parity.append(D[0]).append(D[1]).append(D[2]).append(D[3]).append(D[4]).append(D[5]);
    D29 = D[4];
    D30 = D[5];
    return parity.toString();
}

掩码:0,1,2,4,5,9,10,11,12,13,16,17,19,22

3 3 2 1 210987654321098765432109876543210“位置” 000000000010010110011111000110111 BIN 0 0 4 B 3 E 3 7 十六进制(4 位二进制 = 1 十六进制)

【讨论】:

  • 你是如何生成掩码的?我不太明白你在这里做了什么:D[0] = input &amp; (int)0x4b3e37;?你能解释一下吗?
  • 掩码只是十六进制的数字,在二进制中,0、1、2、4、5、9 处会有 1,...我“和”带有该掩码的输入,所以示例输入:10101,掩码:11100,然后输入 & 掩码 = 10100
  • 然后你数1:10100 = 2 "1"s ;二进制中的 2 = 10(偶数)用 0x1 = 0 奇偶校验屏蔽。如果是例如11100 => 3 "1"s = 11(奇数)& 0x1 = 1 奇偶校验。
猜你喜欢
  • 2013-06-11
  • 2012-07-16
  • 1970-01-01
  • 1970-01-01
  • 2015-10-11
  • 1970-01-01
  • 1970-01-01
  • 2021-12-17
  • 1970-01-01
相关资源
最近更新 更多