将一个字节的前n位与另一个字节的最后8-n位合并

时间:2013-10-10 10:27:03

标签: c# java

如何将一个字节的前n位与另一个字节的最后8-n位合并?

我知道下面从第一个中选择3位,从第二个中选择5位(我在DES加密算法中观察到)
zByte=(xByte & 0xE0) | (yByte & 0x1F); 但我不知道为什么在这种情况下我们需要使用0XE0和0X1F。所以我试图了解每一位的细节。

4 个答案:

答案 0 :(得分:5)

在C#中,这将是:

    int mask = ~((-1) << n);
    var result = (x & ~mask) | (y & mask);

即。我们构建一个掩码(对于n = 5):000....0011111,然后我们将(&)一个操作数与该掩码组合,另一个操作数与 inverse 组合({ {1}})掩码,并组成它们(~)。

你也可以使用移位操作(完全避免使用掩码)更快地做一些事情 - 但前提是数据可以被视为|(因此Java可能会在这里遇到困难)。

答案 1 :(得分:1)

听起来你不明白布尔运算是如何工作的?如果这是你的问题,它就像这样:

0xEO0x1F是数字的十六进制表示。如果我们将这些数字转换为二进制,它们将是:

0xE0 = 11100000
0x1F = 00011111

另外&amp; (和)和| (或)是按位逻辑运算符。要理解逻辑运算符,首先要记住1 = true和0 = false。

&amp;的真值表是:

0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1

|的真值表是:

0 | 0 = 0
0 | 1 = 1
1 | 0 = 1
1 | 1 = 1

让我们一块一块地分解你的方程式。首先,我们将首先评估括号中的代码。我们将以二进制形式遍历每个数字,并为&amp;运算符如果每个操作数在相同的位位置有一个1,我们将返回1.如果任一个数字为0,那么我们将返回0.在我们完成对括号中操作数的评估之后,我们将得到2个结果数并应用|算子一点一滴地运行。如果任一数字在相同的位位置有一个1,我们将返回1.如果两个数字在相同的位位置都为0,我们将返回0.

为了讨论,让我们说

xByte = 255 or (FF in hex and 11111111 in binary)
yByte = 0 or (00 in hex and 00000000 in binary)

当你申请&amp;和|我们将逐个比较每个位:

zByte = (xByte & 0xEO) | (yByte & 0x1F)

变为:

zByte = (11111111 & 11100000) | (00000000 & 00011111)
zByte = 111000000 | 00000000
zByte = 11100000

如果您理解这一点以及布尔逻辑如何工作,那么您可以使用Marc Gravell的答案。

答案 2 :(得分:1)

这些数字背后的数学(0xE0和0x1F)非常简单。首先,我们利用0 & <bit>总是等于01 & <bit>始终等于<bit>的事实。

0x1F是00011111二进制,这意味着在&amp;之后前3位将始终为0。用另一个字节操作 - 最后5位与另一个字节相同。请记住,二进制数中的每1表示2的幂,因此如果要以数学方式找到掩码,则它将是从x = 0到n-1的2 ^ x的总和。然后你可以找到相反的掩码(11100000的掩码)来提取前3位,你只需要从11111111中减去掩码,你就会得到11100000(0xE0)。

答案 3 :(得分:0)

在java中,

通过使用以下函数,我们可以获得第一个字节的前n位和第二个字节的最后8位。

公共类BitExample {

public static void main(String[] args) {
    Byte a = 15;
    Byte b = 16;
    String mergedValue=merge(4, a, b);
    System.out.println(mergedValue);
}


public static String merge(int n, Byte a, Byte b) {
    String mergedString = "";
    String sa = Integer.toBinaryString(a);
    String sb = Integer.toBinaryString(b);

    if(n>sa.length()) {
        for(int i=0; i<(n-sa.length()); i++) {
            mergedString+="0";
        }
        mergedString+=sa;
    }else{
        mergedString+=sa.substring(0, n);
    }

    if(8*n>sb.length()) {
        for(int i=0; i<(8*n-sb.length()); i++) {
            mergedString+="0";
        }
        mergedString+=sb;
    }
    return mergedString;
}

}