我有一个字符数组,我正在尝试向右移位>>
,然后用另一个数组移位&
。我想我对如何做到这一点有错误的想法。
我想,即使是一系列字符,只是陈述my_array >>= 1
会改变一切,但我收到错误:"error: invalid operands to binary >> (have ‘char[8]’ and ‘int’)"
我要做的按位比较是使用类似大小的数组启动所有“0”...为此我得到:"error: invalid operands to binary & (have ‘char *’ and ‘char *’)"
在转换和比较之前,我是否需要将这些数组转换为其他数组?
对不起,我不是很清楚......到目前为止所有很好的建议,我想我更多地意识到没有超级简单的方法可以做到这一点。更具体地说,我要做的是将WHOLE字符数组的位右移1,将右移的位移回数组的最左侧,与另一个相同大小的数组进行逐位比较。 / p>
从技术上讲,比较不必是带数组的数组......我只需要这些位。在尝试进行转换/比较之前,将数组转换为其他内容会更容易吗?
答案 0 :(得分:13)
你必须移位并比较元素。
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;
}
在另一个方向上遍历数组,因为你需要下一个更高位的位。
答案 1 :(得分:3)
/** 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.
}
}
}
答案 2 :(得分:2)
您必须逐个移动数组中的条目。 (如果你想比较其中的两个,你需要逐个元素地进行。)
如果你希望每个字符都移位,那么每个字符都会转移到下一个字符,你也需要手动处理它。
如果您想要转换到下一个字节的行为,并且不介意使您的代码变得令人讨厌且不可移植且容易出错,那么您可能可以获取指向该数组的指针,将其转换为像unsigned long long *
这样的东西,取消引用它并移动生成的整数,然后再将它存储起来。
但如果这是您想要的行为,那么您应该使用整数而不是char[8]
来开始。
(如果您可以详细说明您实际想要达到的目标,那么可能会有更多有用的答案。)
答案 3 :(得分:2)
如果你想在数组上执行诸如移位/ OR / XOR / AND /等等的操作,你应该在循环中执行它,你不能直接在数组上执行它。
答案 4 :(得分:2)
您只能移动该数组的成员,char(或int)。你无法移动整个阵列。移位my_array
尝试对数组类型(或指向char的指针)执行移位操作,这是不可能的。这样做:
for (i = 0; i < size; i++) {
my_array[i] >>= 1;
}
此外,您必须小心使用字符,因为它们通常是签名的,而包含负值的字符将从左侧带来“1”而不是零。所以你最好使用无符号字符。
修改强> 上面的代码很简单。如果您打算将数组作为一个整体向右移动,而不仅仅是每个字节本身,那么您需要“手动”将每个LSB复制到其右侧字节的MSB。回答理查德·彭宁顿的回答。
答案 5 :(得分:1)
我知道这是一个老话题,但是我对可用的答案不满意,这是我最近写的东西,它允许您指定可以移位的位数,并且其中还包含简单的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);
}
}
答案 6 :(得分:0)
/**
* 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;
}
}