将N位移位整个字符arrays

假设我有一个字符数组,我希望每个字节向左移N位,向左移,所以只有第一个字符的N位才会丢失。

示例: kxmo 3位的kxmoX@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

首先,想象用铅笔和纸做。 假设你将两个字节移动三位,你从字节abcdefghijklmnop ,你想用defghijklmnop000完成。

为此,您需要从第二个字节中提取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,因此可以。