private static long permute(byte[] table, int srcWidth, long src) {
long dst = 0;
for (int i=0; i<table.length; i++) {
int srcPos = srcWidth - table[i];
dst = (dst<<1) | (src>>srcPos & 0x01);
}
return dst;
}
这里dst =(dst&lt;&lt; 1)| (src&gt;&gt; srcPos&amp; 0x01);这是如何运作的??我假设|是OR运算符吗?
答案 0 :(得分:3)
考虑按位&#34;和&#34;的一种方法和&#34;或&#34;操作是在结果中设置(打开)和重置(关闭)位的方法。
你认为你的&#34;掩码是一个操作数&#34; - 表示需要设置或重置的内容的1和0。另一个操作数将被掩盖&#34;通过那个&#34;面具&#34;。通过以下方式:
如果运算符是&
,那么&#34;掩码中的每一位都是#{1}}。在结果中,零为零。每个位为1的位将具有来自另一个操作数的值。
所以例如result = x & 0b11111111_11111111_11111111_11110111
(大数字是我们的掩码,而我用二进制显示它)将使所有位与x
相同,除了第四位来自权利,即使它在x
中为0或1,也将为0。
使用&#34;掩码&#34;做&
被认为是&#34;位重置&#34;操作,或&#34;归零&#34;操作
对于|
(或)运算符,您可以将其视为&#34; bit-set&#34;操作。掩码中1的每个位在结果中将为1。每个0位都将具有另一个操作数中的任何内容。所以在结果中,掩码中1的所有位都将被设置。
例如result = x | 0b1000
将包含x中的所有位,除了右边的第四位,无论x是什么,它都将为1。
在二进制文件中编写掩码很长,在Java中是最近的事情,所以你更有可能看到用十六进制编写的掩码。在这种情况下,0xfffffff7
示例为&
,0x8
示例为|
。
现在让我们用一个&#34;掩码&#34;来看看你的表情。观点:
dst<<1
表示将dst
移位1.它的所有位都向左移动一个位置,最右边的位置为零。从本质上讲,这是&#34;腾出空间&#34;在最右边的位置。src
移动srcPos
位置向右移动。所以从右边开始的srcPos+1
位是现在最右边的位。0x01
。也就是0b00000000_00000000_00000000_00000001
。这是一个&
掩码,因此不是最右边的所有内容都将为零。只保存最右边的位。最终结果是它曾经位于srcPos+1
的{{1}}位置,而仅位 - 所有休止符都被重置。< / LI>
src
事物有关。由于它是dst<<1
操作,因此它是一个&#34;设置&#34;面具。我们的掩码只有一个重要的位 - 我们在|
操作中没有擦除的位。它位于最右边的位置。如果它为1,则结果为1,如果为0,则结果为0(因为左边的操作数在该位置为零)。基本上它的作用是:
&
中的位推到左侧。dst
+ 1位置放置在最右边的位置。如果srcPos
中的值都是0和table
之间的唯一位置,那么这将为您提供srcWidth
位的加扰 - 在每一轮中将推送一位根据{{1}}的值src
进入dst
。
答案 1 :(得分:1)
|
是按位或不是逻辑OR
按位OR对该长度中的每个位单独进行操作。这会改变它的值,这与定义它不同。
打破这一行:
dst = (dst<<1) | (src>>srcPos & 0x01);
dst<<1 // means left shift 1 place. The same as multiply by 2. Zeros lowest bit.
src>>srcPos // means right shift srcPos places. The same as divide by 2 to the srcPos
// this puts the selected bit in the lowest place
& 0x01 // means set every bit to zero except the rightmost one which will stay the same
(src>>srcPos & 0x01) // means give me the value of the src bit at srcPos
(dst<<1) | (src>>srcPos & 0x01); // means shift dst left and put a src bit at the end
这里的按位OR就像它附加了一点。这只能起作用,因为不会被使用的比特在每一方都被小心地归零。
当循环绕过table
时,控制从src
取样的位,并将其选择的任何位置附加到dst
的右端。因此table
控制src
置换的方式。
答案 2 :(得分:1)
&#34; | &#34;是二进制OR运算符,如果它存在于任一操作数中,则复制一位。 举个例子:
A|B
将给出61这是0011 1101。
&#34; || &#34;被称为逻辑OR运算符。如果两个操作数中的任何一个非零,则条件变为真。举个例子:
(A || B)是真的。