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)。无法移动整个数组。shiftmy_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);
}
}