C 字符的按位移位数组';s

C 字符的按位移位数组';s,c,bit-manipulation,C,Bit Manipulation,我有一个字符数组,我正试图将其按位右移>,然后用另一个数组将其右移&。我想我对如何做这件事的想法是错误的 我想,即使它是一个字符数组,只要声明my_array>>=1就会移动所有内容,但我得到了一个错误:“错误:无效操作数到二进制>>(有'char[8]'和'int')” 我尝试进行的逐位比较是与一个启动到所有“0”的大小相似的数组进行比较……因此我得到:“错误:二进制操作数无效&(具有'char*'和'char*”)” 我是否需要将这些数组转换为其他数组,然后才能进行移位和比较 对不起,我不是

我有一个字符数组,我正试图将其按位右移
>
,然后用另一个数组将其右移
&
。我想我对如何做这件事的想法是错误的

我想,即使它是一个字符数组,只要声明
my_array>>=1
就会移动所有内容,但我得到了一个错误:
“错误:无效操作数到二进制>>(有'char[8]'和'int')”

我尝试进行的逐位比较是与一个启动到所有“0”的大小相似的数组进行比较……因此我得到:
“错误:二进制操作数无效&(具有'char*'和'char*”)”

我是否需要将这些数组转换为其他数组,然后才能进行移位和比较

对不起,我不是很清楚。。。到目前为止,所有这些都是很好的建议,我想我更清楚地认识到,要做到这一点,没有超简单的方法。更具体地说,我要做的是将整个char数组的位右移1,将右移的位添加到数组的最左侧,并与另一个大小相同的数组进行逐位比较


从技术上讲,比较不必是数组与数组之间的比较。。。我只需要一点点。在尝试进行移位/比较之前,是否更容易将数组中的项转换为其他项?

您必须逐个移位数组中的项。(如果要比较其中的两个,则需要逐个元素进行比较。)

如果您希望从每个字符转移的位会被转移到下一个字符,那么您也需要手动处理

如果您希望转换到下一个字节行为,并且不介意使代码变得讨厌、不可移植和容易出现错误,那么您可以将指针指向数组,将其转换为类似于
unsigned long*
,取消引用它并将结果整数移位,然后再次存储

但是如果这是您想要的行为,那么您应该首先使用整数而不是
char[8]


(如果你能说出更多你真正想要达到的目标,那么可能会有更多有用的答案。)

你必须转换并进行元素比较

for(i = 0; i < len; ++i)
    array[i] >>= 3;
(i=0;i 数组[i]>>=3; 比如说。如果你想把移位的位从一个元素移到下一个元素,那就更复杂了,假设你是右移的,那么

unsigned char bits1 = 0, bits2 = 0;
for(i = len-1; i >= 0; --i) {
    bits2 = array[i] & 0x07;
    array[i] >>= 3;
    array[i] |= bits1 << 5;
    bits1 = bits2;
}
无符号字符位s1=0,位s2=0;
对于(i=len-1;i>=0;--i){
bits2=数组[i]&0x07;
数组[i]>>=3;

数组[i]|=位1如果要在数组上执行移位/或/XOR/和/等操作,则应在循环中执行,不能直接在数组上执行。

只能移位该数组的成员、字符(或int)。无法移动整个数组。shift
my_array
尝试对数组类型(或指向char的指针)执行移位操作,但这是不可能的。请改为:

for (i = 0; i < size; i++) {
  my_array[i] >>= 1;
}
for(i=0;i>=1;
}
此外,您还必须小心使用字符,因为它们通常是有符号的,并且包含负值的字符将从左侧带“1”而不是零。因此,您最好使用无符号字符

编辑: 上面的代码过于简单。如果您打算将数组作为一个整体右移,而不仅仅是将每个字节单独右移,则需要“手动”将每个LSB复制到其右侧字节的MSB。在Richard Pennington的答案处进行循环。

/**
/** Shift an array right.
 * @param ar The array to shift.
 * @param size The number of array elements.
 * @param shift The number of bits to shift.
 */
void shift_right(unsigned char *ar, int size, int shift)
{
    int carry = 0;                              // Clear the initial carry bit.
    while (shift--) {                           // For each bit to shift ...
        for (int i = size - 1; i >= 0; --i) {   // For each element of the array from high to low ...
            int next = (ar[i] & 1) ? 0x80 : 0;  // ... if the low bit is set, set the carry bit.
            ar[i] = carry | (ar[i] >> 1);       // Shift the element one bit left and addthe old carry.
            carry = next;                       // Remember the old carry for next time.
        }   
    }
}   
*将若干位右移 * *@param SRC要移位的数组 *@param len数组的长度 *@param shift要移位的连续位数 * */ 静态无效移位\u位\u右(uint8\u t SRC[],uint16\u t len,uint32\u t移位){ uint32_t i=0; uint8\u t开始=移位/8; uint8\u t rest=班次%8; uint8_t previous=0; 对于(i=0;i
我知道这是一个老话题,但我对可用的答案不满意,下面是我最近写的一篇文章,它允许您指定可以移位的位的数量,并且其中有简单的XOR加密

//https://github.com/ashvin-bhuttoo/CryptoTest/blob/master/CryptoTest/Crypto.cpp
//CRYPTO CONFIGURATION PARAMETERS
#define BIT_SHIFT 3
#define XOR_KEY 0x3C
#define ENABLE_XOR_VARIANCE true
////////////////////////////////

int get_rs_mask(int shift)
{
    switch (shift)
    {
    case 0:
        return 0x00;
    case 1:
        return 0x01;
    case 2:
        return 0x03;
    case 3:
        return 0x07;
    case 4:
        return 0x0F;
    case 5:
        return 0x1F;
    case 6:
        return 0x3F;
    case 7:
        return 0x7F;
    default:
        throw "get_rs_mask -> Error, shift argument outside legal range 0-7";
    }
}

void shift_right(char* buf, int msg_len, int shift)
{
    unsigned char tmp = 0x00, tmp2 = 0x00;
    for (int k = 0; k <= msg_len; k++)
    {
        if (k == 0)
        {
            tmp = buf[k];
            buf[k] >>= shift;
        }
        else
        {
            tmp2 = buf[k];
            buf[k] >>= shift;
            buf[k] |= ((tmp & get_rs_mask(shift)) << (8 - shift));

            if (k != msg_len)
                tmp = tmp2;
        }
    }
}

int get_ls_mask(int shift)
{
    switch (shift)
    {
    case 0:
        return 0x00;
    case 1:
        return 0x80;
    case 2:
        return 0xC0;
    case 3:
        return 0xE0;
    case 4:
        return 0xF0;
    case 5:
        return 0xF8;
    case 6:
        return 0xFC;
    case 7:
        return 0xFE;
    default:
        throw "get_ls_mask -> Error, shift argument outside legal range 0-7";
    }
}

void shift_left(char* buf, int msg_len, int shift)
{
    char tmp = 0x00, tmp2 = 0x00;
    for (int k = msg_len; k >= 0; k--)
    {
        if (k == msg_len)
        {
            tmp = buf[k];
            buf[k] <<= shift;
        }
        else
        {
            tmp2 = buf[k];
            buf[k] <<= shift;
            buf[k] |= ((tmp & get_ls_mask(shift)) >> (8 - shift));

            tmp = tmp2;
        }
    }
}

void crypt(char* buf, int msg_len, bool decrypt = false)
{
    if (!decrypt)
    {
        shift_right(buf, msg_len, BIT_SHIFT);
        for (int k = 0; k < msg_len; k++)
        {
            buf[k] = buf[k] ^ XOR_KEY ^ k * (ENABLE_XOR_VARIANCE ? 2 : 0);
        }
        buf[msg_len] = '\0';
    }
    else
    {
        for (int k = 0; k < msg_len; k++)
        {
            buf[k] = buf[k] ^ XOR_KEY ^ k * (ENABLE_XOR_VARIANCE ? 2 : 0);
        }
        shift_left(buf, (msg_len)-1, BIT_SHIFT);
    }
}
//https://github.com/ashvin-bhuttoo/CryptoTest/blob/master/CryptoTest/Crypto.cpp
//加密配置参数
#定义位u移位3
#定义XOR_键0x3C
#定义启用异或方差为真
////////////////////////////////
int get\U rs\U掩码(int shift)
{
开关(换档)
{
案例0:
返回0x00;
案例1:
返回0x01;
案例2:
返回0x03;
案例3:
返回0x07;
案例4:
返回0x0F;
案例5:
返回0x1F;
案例6:
返回0x3F;
案例7:
返回0x7F;
违约:
抛出“get\u rs\u mask->错误,将参数移到法律范围0-7之外”;
}
}
无效向右移位(char*buf,int msg\u len,int shift)
{
无符号字符tmp=0x00,tmp2=0x00;
对于(int k=0;k>=shift;
}
其他的
{
tmp2=buf[k];
buf[k]>>=移位;
buf[k]|=((tmp&get_-rs_-mask(shift))=0;k--)
{
如果(k==msg_len)
{
tmp=buf[k];

buf[k]您是在尝试旋转数组的内容,还是在尝试对数组中的每个元素进行逐位移位?这两种操作都不存在于C中。您需要编写一个循环,将每个元素复制到一个位置,或者对数组中的每个元素进行逐位移位。我假设他希望将数组视为单个元素值,所以您也需要从更重要的字节中携带一位。这看起来很奇怪,或者我遗漏了什么。它看起来像是向右移位和向左移位的混合。携带位旁边的注释是“将元素向左移位一位”,但它向右移动。而for循环是从高到低,我宁愿从低到高向右移动。我也会移动
//https://github.com/ashvin-bhuttoo/CryptoTest/blob/master/CryptoTest/Crypto.cpp
//CRYPTO CONFIGURATION PARAMETERS
#define BIT_SHIFT 3
#define XOR_KEY 0x3C
#define ENABLE_XOR_VARIANCE true
////////////////////////////////

int get_rs_mask(int shift)
{
    switch (shift)
    {
    case 0:
        return 0x00;
    case 1:
        return 0x01;
    case 2:
        return 0x03;
    case 3:
        return 0x07;
    case 4:
        return 0x0F;
    case 5:
        return 0x1F;
    case 6:
        return 0x3F;
    case 7:
        return 0x7F;
    default:
        throw "get_rs_mask -> Error, shift argument outside legal range 0-7";
    }
}

void shift_right(char* buf, int msg_len, int shift)
{
    unsigned char tmp = 0x00, tmp2 = 0x00;
    for (int k = 0; k <= msg_len; k++)
    {
        if (k == 0)
        {
            tmp = buf[k];
            buf[k] >>= shift;
        }
        else
        {
            tmp2 = buf[k];
            buf[k] >>= shift;
            buf[k] |= ((tmp & get_rs_mask(shift)) << (8 - shift));

            if (k != msg_len)
                tmp = tmp2;
        }
    }
}

int get_ls_mask(int shift)
{
    switch (shift)
    {
    case 0:
        return 0x00;
    case 1:
        return 0x80;
    case 2:
        return 0xC0;
    case 3:
        return 0xE0;
    case 4:
        return 0xF0;
    case 5:
        return 0xF8;
    case 6:
        return 0xFC;
    case 7:
        return 0xFE;
    default:
        throw "get_ls_mask -> Error, shift argument outside legal range 0-7";
    }
}

void shift_left(char* buf, int msg_len, int shift)
{
    char tmp = 0x00, tmp2 = 0x00;
    for (int k = msg_len; k >= 0; k--)
    {
        if (k == msg_len)
        {
            tmp = buf[k];
            buf[k] <<= shift;
        }
        else
        {
            tmp2 = buf[k];
            buf[k] <<= shift;
            buf[k] |= ((tmp & get_ls_mask(shift)) >> (8 - shift));

            tmp = tmp2;
        }
    }
}

void crypt(char* buf, int msg_len, bool decrypt = false)
{
    if (!decrypt)
    {
        shift_right(buf, msg_len, BIT_SHIFT);
        for (int k = 0; k < msg_len; k++)
        {
            buf[k] = buf[k] ^ XOR_KEY ^ k * (ENABLE_XOR_VARIANCE ? 2 : 0);
        }
        buf[msg_len] = '\0';
    }
    else
    {
        for (int k = 0; k < msg_len; k++)
        {
            buf[k] = buf[k] ^ XOR_KEY ^ k * (ENABLE_XOR_VARIANCE ? 2 : 0);
        }
        shift_left(buf, (msg_len)-1, BIT_SHIFT);
    }
}