如何将一个字节的前n位与另一个字节的最后8-n位合并?
我知道下面从第一个中选择3位,从第二个中选择5位(我在DES加密算法中观察到)
zByte=(xByte & 0xE0) | (yByte & 0x1F);
但我不知道为什么在这种情况下我们需要使用0XE0和0X1F。所以我试图了解每一位的细节。
答案 0 :(得分:5)
在C#中,这将是:
int mask = ~((-1) << n);
var result = (x & ~mask) | (y & mask);
即。我们构建一个掩码(对于n = 5):000....0011111
,然后我们将(&
)一个操作数与该掩码组合,另一个操作数与 inverse 组合({ {1}})掩码,并组成它们(~
)。
你也可以使用移位操作(完全避免使用掩码)更快地做一些事情 - 但前提是数据可以被视为|
(因此Java可能会在这里遇到困难)。
答案 1 :(得分:1)
听起来你不明白布尔运算是如何工作的?如果这是你的问题,它就像这样:
0xEO
和0x1F
是数字的十六进制表示。如果我们将这些数字转换为二进制,它们将是:
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>
总是等于0
而1 & <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;
}
}