C 异或加密期间额外的0xFFFFFF
我这里有一段代码C 异或加密期间额外的0xFFFFFF,c,encryption,xor,C,Encryption,Xor,我这里有一段代码 #include<stdio.h> #define LEN 10 char buf[] = {0xff,0xaa,0xfc,0xe8,0x89,0x00,0x00,0x00,0x60,0x89}; char key[] = "SAMPLE KEY"; int main() { int i; char enc[LEN]; for(i=0;i<LEN;i++) {
#include<stdio.h>
#define LEN 10
char buf[] = {0xff,0xaa,0xfc,0xe8,0x89,0x00,0x00,0x00,0x60,0x89};
char key[] = "SAMPLE KEY";
int main()
{
int i;
char enc[LEN];
for(i=0;i<LEN;i++)
{
enc[i] = (key[i % LEN] ^ buf[i]);
printf("0x%x,",enc[i]);
}
}
预期输出在哪里
0xac,0xeb,0xb1,0xb8,0xc5,0x45,0x20,0x4b,0x25,0xd0,
我怎样才能解决这个问题?
为什么会发生这种情况?将
buf
和enc
在声明中的类型从char
更改为unsigned char
实现定义了
char
是signed
还是unsigned
类型,在您的实现中,它显然是signed
类型。在声明中将buf
和enc
类型从char
更改为unsigned char
实现定义了
char
是signed
还是unsigned
类型,在您的实现中,它显然是signed
类型。现在,您不仅有前导符号扩展位,而且还缺少前导零
使用
现在,您不仅有前导符号扩展位,而且还缺少前导零 使用
您的加密工作正常。您的问题是您已经将
enc
声明为一个签名字符数组。(正如ouah正确指出的,char
在默认情况下可以是有符号的,也可以是无符号的。在编译器上,它显然是有符号的。)
因此,像0xAC
这样设置了MSB的字符被解释为负数。当您将它们传递到printf()
时,它们会隐式转换为int,因此转换为32位
要修复它,只需将enc
、key
和buf
显式声明为无符号字符的数组。或者,你可以使用Ben Voigt的解决方案,屏蔽掉多余的比特,但是你会毫无意义地扩展你的字符,只是为了再次屏蔽那些多余的比特
另外,您确实意识到,如果您加密的任何内容都比密钥长得多,那么这种“加密”就非常弱,是吗?您的加密工作正常。您的问题是您已经将enc
声明为一个签名字符数组。(正如ouah正确指出的,char
在默认情况下可以是有符号的,也可以是无符号的。在编译器上,它显然是有符号的。)
因此,像0xAC
这样设置了MSB的字符被解释为负数。当您将它们传递到printf()
时,它们会隐式转换为int,因此转换为32位
要修复它,只需将enc
、key
和buf
显式声明为无符号字符的数组。或者,你可以使用Ben Voigt的解决方案,屏蔽掉多余的比特,但是你会毫无意义地扩展你的字符,只是为了再次屏蔽那些多余的比特
Ps.您确实意识到,如果您加密的任何内容都比密钥长得多,那么这种“加密”就太弱了,对吗?OP使用的格式意味着%x
用于未签名的
由于char
值与printf()一起变成int
。。。参数,使用表示字符的格式%hhx
。这将只打印char
部分。例如:
printf("0x%02hhx,",enc[i]); --> 0xac,
OP使用的格式意味着%x
用于无符号
由于char
值与printf()一起变成int
。。。参数,使用表示字符的格式%hhx
。这将只打印char
部分。例如:
printf("0x%02hhx,",enc[i]); --> 0xac,
这是因为任何带有符号位集(位7)的东西都会通过输出函数的隐式转换得到扩展。+1谢谢,这很有效,但是你介意解释一下为什么会出现这个问题吗…@vikkyhacks:你溢出了achar
可以容纳的值。在您的实现中,char
是有符号的,几乎可以肯定它是8位2的补码。这意味着它只能保存–128到127之间的值。源文本0xff
代表数字255,大于char
所能容纳的大小。因此,它泛滥了。在C实现中,它将位11111111存储在字符中。这些位表示值–1。当值为-1的有符号char
传递给printf
时,它将被提升为int
。结果是一个值为-1的int
,用位0xFFFFFF表示。@vikkyhacks:此外,您还可以使用%x
打印此int
,它是无符号int
的说明符。如果要使用%x
说明符打印,则应先将值转换为unsigned int
,然后再将其传递给printf
。这是有效的,因为任何设置了符号位(位7)的内容都将通过输出函数的隐式转换进行扩展。+1谢谢,这非常有效,但是你能解释一下为什么会有这个问题吗?@vikkyhacks:你溢出了achar
所能容纳的值。在您的实现中,char
是有符号的,几乎可以肯定它是8位2的补码。这意味着它只能保存–128到127之间的值。源文本0xff
代表数字255,大于char
所能容纳的大小。因此,它泛滥了。在C实现中,它将位11111111存储在字符中。这些位表示值–1。当值为-1的有符号char
传递给printf
时,它将被提升为int
。结果是一个值为-1的int
,用位0xFFFFFF表示。@vikkyhacks:此外,您还可以使用%x
打印此int
,它是无符号int
的说明符。如果要使用%x
说明符打印,应先将值转换为无符号int
,然后再将其传递给printf
(a)OP不表示需要前导零。(b) 这并不能修复实现-d
printf("0x%02hhx,",enc[i]); --> 0xac,