将N位移位整个字符arrays
假设我有一个字符数组,我希望每个字节向左移N位,向左移,所以只有第一个字符的N位才会丢失。
示例: kxmo
3位的kxmo
为X@hx
这就是我目前所拥有的,但它没有按预期工作:
#include int main(void) { //shift the array with length *len* *shift* bits to the left int len = 4, shift = 3; unsigned char a[len] = "kxmo"; unsigned char b[len]; //X@hx unsigned char tmp = 0, tmp2 = 0; for(int i = len - 1; i > 0; i--) { tmp = 0 | (a[i] << shift); b[i] = a[i]; tmp2 = 0 | (a[i - 1] << shift); b[i - 1] = (a[i - 1] << shift) ^ tmp; } printf("old: %s | new: %s\n", a, b); return 0; }
我哪里失败了?
编辑:
这就是我现在得到的: old: kxmo | new: xmo
old: kxmo | new: xmo
首先,想象用铅笔和纸做。 假设你将两个字节移动三位,你从字节abcdefgh
, ijklmnop
,你想用defghijk
, lmnop000
完成。
为此,您需要从第二个字节中提取00000ijk
,并将其移入到移位后的第一个字节中。 为此,您需要将第二个字节向右移8-shift
,并使用00000111
屏蔽结果,即最后一个shift
位设置为1
。 可以通过将1
移位到shift+1
次,产生00001000
,并从结果中减去1
来构造该掩模。
以下是如何做到这一点:
char b1 = 'k'; char b2 = 'x'; int shift = 3; int carry = 0, nextCarry; nextCarry = (b1 >> (8-shift)) & ((1<<(shift+1))-1); b1 <<= shift; b1 |= carry; carry = nextCarry;
现在对b2
做同样的事情:
nextCarry = (b2 >> (8-shift)) & ((1<<(shift+1))-1); b2 <<= shift; b2 |= carry; carry = nextCarry;
如果在循环中执行此操作,则可以获得所需的结果。
演示。
这样的事情怎么样(假设0 <= shift
<8):
#define BITS_IN_BYTE 8 for(int i = len - 1; i > 0; i--) { b[i] = a[i] << shift; b[i - 1] = (a[i - 1] << shift) | (a[i] >> (BITS_IN_BYTE - shift)); }
我没有检查它,但我希望它会做你想要的。
编辑
好的,我检查了它,它做了你所期望的。
注意 – >你需要将len
设置为5而不是设置为'\0'
。 另请注意,第一次迭代( b[i] = a[i] << shift;
)将在'\0'
上完成,但由于其值为0,因此可以。