按位移位char数组

yi0zb3m4  于 2023-02-21  发布在  其他
关注(0)|答案(9)|浏览(227)

我有一个字符数组,我试图按位右移>>,然后用另一个数组右移&,我想我对如何做有错误的想法。
我想,即使它是一个字符数组,只是声明my_array >>= 1将转移一切,但我得到了一个错误:"error: invalid operands to binary >> (have ‘char[8]’ and ‘int’)"
我正在尝试做的逐位比较是与一个类似大小的数组初始化为所有的“0”......对于我得到的:"error: invalid operands to binary & (have ‘char *’ and ‘char *’)"
在移位和比较之前,我需要把这些数组转换成别的东西吗?
对不起,我不是很清楚......到目前为止,所有的建议都很好,我想我越来越意识到没有一个超级简单的方法来做到这一点。更具体地说,我正在尝试做的是将整个字符数组的位右移1,将右移的位添加回数组的最左侧,与另一个相同大小的数组进行逐位比较。
从技术上讲,比较不一定是数组与数组的比较...我只需要位。在尝试进行移位/比较之前,将数组转换为其他形式会更容易吗?

du7egjpx

du7egjpx1#

你必须逐个元素地变换和比较。

for(i = 0; i < len; ++i)
    array[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;
}

在另一个方向上遍历阵列,因为您需要来自下一个更高槽的位。

cnh2zyt3

cnh2zyt32#

你必须一个接一个地移动数组中的条目(如果你想比较其中的两个,你需要一个接一个地移动)。
如果你希望从每个字符中移走的位会被移到下一个字符中,你也需要手工处理。
如果你想要这种移位到下一个字节的行为,并且不介意让你的代码变得糟糕、不可移植和容易出错,你可以取一个指向数组的指针,将它强制转换为类似unsigned long long *的类型,解引用它并移位结果整数,然后再把它存储回去。
但是,如果这是你想要的行为,那么你应该使用一个整数,而不是一个char[8]开始。
(If你可以多说一些你真正想要达到的目标,这样就可能得到更有帮助的答案。)

kgsdhlau

kgsdhlau3#

如果要在数组上执行诸如移位/或/异或/与等操作,则应在循环中执行,不能直接在数组上执行。

nkkqxpd9

nkkqxpd94#

/** 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.
        }   
    }
}
kcrjzv8t

kcrjzv8t5#

你只能移位数组的成员,一个char(或int)。你不能移位整个数组。移位my_array试图对一个数组类型(或一个char指针)执行移位操作,这是不可能的。请改为:

for (i = 0; i < size; i++) {
  my_array[i] >>= 1;
}

另外,你必须小心字符,因为它们通常是有符号的,一个包含负值的字符会从左边带“1”而不是零,所以你最好使用无符号字符。

**EDIT:**上面的代码过于简单。如果你想把数组作为一个整体右移,而不仅仅是每个字节本身,那么你需要“手动”把每个LSB复制到它右边字节的MSB。按照Richard彭宁顿的答案循环。

oknrviil

oknrviil6#

/**
 * shift a number of bits to the right
 *
 * @param   SRC         the array to shift
 * @param   len         the length of the array
 * @param   shift       the number of consecutive bits to shift
 *
*/
static void shift_bits_right(uint8_t SRC[], uint16_t len, uint32_t shift) {
    uint32_t i = 0;

    uint8_t start = shift / 8;
    uint8_t rest = shift % 8;
    uint8_t previous = 0;

    for(i = 0; i < len; i++) {
        if(start <= i) {
            previous = SRC[i - start];
        }
        uint8_t value = (previous << (8 - rest)) | SRC[i + start] >> rest;
        SRC[i + start] = value;
    }
}
rwqw0loc

rwqw0loc7#

我知道这是一个老主题,但我不满意的答案可用,这里是我最近写的东西,它允许您指定的位数,您可以移位,也有简单的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);
    }
}
shstlldc

shstlldc8#

/**
 * Shift a number of bits to the right
 *
 * @param   array       The array to shift
 * @param   len         The length of the array
 * @param   shift       The number of consecutive bits to shift. To the right if shift is positif.
 *
*/
static void shift_bits_right(uint8_t *array, int len, int shift) {

    uint8_t macro_shift = shift / 8;
    shift = shift % 8;

    uint8_t array_out[len];
    memset(array_out, 0, len);
    
    for(int i = 0; i < len; i++) {
        if(i+macro_shift < len)
            array_out[i+macro_shift] += array[i]>>shift;
        if(i+macro_shift+1 < len)
            array_out[i+macro_shift+1] += array[i]<<(8-shift);
    }

    memcpy(array, array_out, len);
}
tvmytwxo

tvmytwxo9#

对于每个正在寻找代码片段来(逻辑地)右移字节数组 * 并实际工作 * 的人:

template<size_t N> void shift_right(array<uint8_t, N>& arr, uint64_t bits)
{
    int64_t num_bytes = bits / 8;
    int64_t num_bits  = bits % 8;

    for(int64_t i = N-1; i >= 0; i--)
    {
        int64_t i_from = i - num_bytes;
        int64_t i_from_minus_one = i - num_bytes - 1;
        uint8_t v_from = i_from < 0 ? 0 : arr[i_from];
        uint8_t v_from_minus_one = i_from_minus_one < 0 ? 0 : arr[i_from_minus_one];
         
        arr[i] = v_from >> num_bits | v_from_minus_one << (8 - num_bits);
    }
}

相关问题