我只是在Mac OS X上进行了一些测试。但我不明白为什么会这样。
当我尝试对unsigned long long int应用一些按位运算时, 当某些操作超过32位时,没有关于操作的设备。
代码在下面..
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define KEY_MAX 31
#define INDEX_MASK 0b11111
unsigned long long int makePlain(unsigned long long int chipherText, int pattern);
static char testArray[] = {
'A', 'B', 'C', 'D', 'E',
'F', 'G', 'H', 'I', 'J',
'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X', 'Y',
'Z', ' ', '@', '@', '@' };
int main(void) {
unsigned int i;
unsigned long long int chipherText = 0b1010100100101010101111001000110101110101001001100111010;
unsigned long long int plain = 0;
for (i = 2; i < 3; i++) {
plain = makePlain(chipherText, i);
int j;
for (j = 0; j < 11; j++) {
printf("IDX=[%d] : %d\n", j,(unsigned int)(plain >> (5 * j) & INDEX_MASK));
}
printf("%c%c%c%c%c%c%c%c%c%c%c\n",
testArray[(unsigned int)((plain >> (5 * 10)) & INDEX_MASK)],
testArray[(unsigned int)((plain >> (5 * 9)) & INDEX_MASK)],
testArray[(unsigned int)((plain >> (5 * 8)) & INDEX_MASK)],
testArray[(unsigned int)((plain >> (5 * 7)) & INDEX_MASK)],
testArray[(unsigned int)((plain >> (5 * 6)) & INDEX_MASK)],
testArray[(unsigned int)((plain >> (5 * 5)) & INDEX_MASK)],
testArray[(unsigned int)((plain >> (5 * 4)) & INDEX_MASK)],
testArray[(unsigned int)((plain >> (5 * 3)) & INDEX_MASK)],
testArray[(unsigned int)((plain >> (5 * 2)) & INDEX_MASK)],
testArray[(unsigned int)((plain >> (5 * 1)) & INDEX_MASK)],
testArray[(unsigned int)((plain >> (5 * 0)) & INDEX_MASK)] );
}
return 0; }
unsigned long long int makePlain(unsigned long long int chipherText, int pattern) {
int i;
unsigned int temp;
unsigned long long int plain = 0;
for (i = 0; i < 11; i++) {
temp = ((chipherText >> (5 * i)) & INDEX_MASK);
temp = temp ^ pattern;
printf("[%d]:temp -after xor : %d\n", i, temp);
plain |= (temp << (5 * i)); // Here is make problems.
}
return plain; }
(起初,代码不好看......对不起大家。)
请参阅makePlain函数的最后一行循环..
当变量i为6时,它的写位超过32位。 之后,“plain | =”的所有操作都不适用,但对于32位以上的位保持为0。
下面是Xcode Debbugger的结果。
所以,我只是确认了asm,我发现了那种代码..
call printf
LM42:
movl -4(%rbp), %edx # i -> edx
movl %edx, %eax # eax = i
sall $2, %eax # i * 4
addl %edx, %eax # i * 5
movl -20(%rbp), %edx # temp -> edx (maybe problem
# becase it load 64bit on 32)
movl %eax, %ecx # eax -> ecx ==> ecx = i * 5
sall %cl, %edx # edx << i * 5 //why 32 bit?
movl %edx, %eax # eax saving (plain) //why 32bit
movl %eax, %eax #
orq>%rax, -16(%rbp) # saving
我认为上面的代码是
plain | =(temp&lt;&lt;(5 * i));
关于makePlain函数。
我的问题是......
答案 0 :(得分:2)
您的temp
变量只有32位,因为它是unsigned int
。将其类型更改为unsigned long long
以解决您的问题。
在这一行:
plain |= (temp << (5 * i));
变量temp
具有unsigned int
类型,通常为32位类型。因此,左移位也是32位移位,并且丢弃超出32位的移位。该代码还表现出不确定的行为时i
是大于6,通过多个位比其类型移值具有未定义。
有两种方法可以解决这个问题。一种是给temp
正确的类型,另一种是使用适当的强制转换以确保班次是unsigned long long
班次:
plain |= ((unsigned long long)temp << (5 * i));
答案 1 :(得分:1)
在编写代码时,请始终确保所有变量彼此依赖的数据类型相同。在这种情况下,它可以避免内存溢出