下面代码中bit get和bit set是bit rot left中要用到的简单函数,功能分别是取得和设置指定位的bit值,我很难看懂bit rot left函数,虽然书上简介写的很简单:轮转缓冲区bits(含size位),将位值向左移count位.此操作完成后,处于最左端的count位移动到缓冲区最右端,而且其他的位也相应的轮转.
但是我在main函数的测试中好像并不如意,代码如下:
#include <string.>
#include <stdio.h>
int bit_get(const unsigned char * bits, int pos)
{
unsigned char mask;
int i;
/*设置掩码*/
mask = 0x80;
for (i = 0; i < (pos % 8); i ++)
mask = mask >> 1;
/*获得当前位的数值*/
return (((mask & bits[(int)(pos / 8)]) == mask )? 1:0);
}
void bit_set(unsigned char * bits, int pos, int state)
{
unsigned mask;
int i;
mask = 0x80;
for (i = 0; i < (pos % 8); i ++)
mask = mask >> 1;
if (state)
bits[pos/8] |= mask;
else
bits[pos/8] &= (~mask);
return;
}
void bit_rot_left(unsigned char *bits,int size, int count)
{
int fbit,
lbit,
i,
j;
/*Rotate the buffer to the left the specified number of bits.*/
if (size > 0)
{
for ( j = 0; j < count; j++)
{
for(i=0;i<=((size - 1)/8);i++)
{
/*Get the bie about to be shifted off the current byte.*/
lbit = bit_get(&bits[i],0);
if (i == 0)
/*Save the bit shifted off the first byte for later.*/
fbit = lbit;
else
/*Set the rightmost bit of the previous byte to the leftmost bit about to be shifted off the current byte.*/
bit_set(&bits[i - 1],7,lbit);
/*Set the rightmost bit of the buffer to the bit shifted off the first byte.*/
bits[i] = bits[i] << 1;
}
bit_set(bits,size-1,fbit);
}
}
return;
}
int main()
{
unsigned char bits[]="10010101";
bit_rot_left(bits,8,2);
printf("%s\n",bits);
}
输出如下
?010101
嗯 你那个程序有错。。。我没有去调试它,不过我写了一个好用的:
#include <stdio.h>
int gcd(int a, int b)
{
return b == 0 ? a : gcd(b, a % b);
}
void swap(unsigned char *a, unsigned char *b)
{
unsigned char tmp = *a;
*a = *b;
*b = tmp;
}
void rot1(unsigned char *bits, int size, int count)
{
int m = gcd(size, count), i, j;
unsigned char tmp;
count %= size;
count = size - count;
for (i = 0; i < m; i++)
{
tmp = bits[i];
for (j = i + count; j != i; j += count)
{
if (j > size)
j -= size;
swap(&tmp, bits + j);
}
bits[i] = tmp;
}
}
void rot2(unsigned char *bits, int size, int count)
{
int i;
unsigned char mask = ~0 << (8 - count), tmp1 = 0, tmp2;
for (i = size - 1; i >= 0; i--)
{
tmp2 = (mask & bits[i]) >> (8 - count);
bits[i] <<= count;
bits[i] |= tmp1;
tmp1 = tmp2;
}
bits[size - 1] |= tmp1;
}
void bit_rot_left(unsigned char *bits, int size, int count)
{
rot1(bits, size, count / 8);
rot2(bits, size, count % 8);
}
void print_bits(unsigned char *bits, int size)
{
int i, j;
for (i = 0; i < size; i++)
for (j = 0x80; j; j >>= 1)
printf("%d", !!(j & bits[i]));
printf("\n");
}
int main()
{
unsigned char bits[]="10010101";
print_bits(bits, 8);
bit_rot_left(bits,8,2);
printf("%s\n",bits);
print_bits(bits, 8);
return 0;
}
输出如下
0011000100110000001100000011000100110000001100010011000000110001
????????
1100010011000000110000001100010011000000110001001100000011000100
测试程序应该这样写才对:
int main()
{
unsigned char bits[3]={0x4b,0xdb,0};
bit_rot_left(bits,16,2);
printf("%#x,%#X,%#x",bits[0],bits[1],bits[2]);
}
输出是
0x2f,0x6D,0