Reputation: 3230
I have this piece of code here
#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]);
}
}
Which outputs
OUTPUT
0xffffffac,0xffffffeb,0xffffffb1,0xffffffb8,0xffffffc5,0x45,0x20,0x4b,0x25,0xffffffd0
where the expected output is
0xac,0xeb,0xb1,0xb8,0xc5,0x45,0x20,0x4b,0x25,0xd0,
How can I fix this ? Why does this happen ?
Upvotes: 1
Views: 387
Reputation: 154085
OP is using a format meant %x
for unsigned
.
Since a char
value becomes an int
with printf()
... parameters, use a format %hhx
meant for char
. This will print only the char
portion. Example:
printf("0x%02hhx,",enc[i]); --> 0xac,
Upvotes: 0
Reputation: 50368
Your encryption works fine. You problem is that you've declared enc
as an array of signed chars. (As ouah correctly notes, char
can be either signed or unsigned by default. On your compiler, it's apparently signed.)
Thus, chars like 0xAC
which have their MSB set are interpreted as negative numbers. When you pass them to printf()
, they're implicitly converted to ints, and therefore sign-extended to 32 bits.
To fix it, just declare enc
, key
and buf
explicitly as arrays of unsigned char
s. Alternatively, you could use Ben Voigt's solution and mask off the extra bits, but then you'd be pointlessly sign-extending your chars just to mask those extra bits off again.
Ps. You do realize that this kind of "encryption" is hopelessly weak if you're encrypting anything significantly longer than the key, right?
Upvotes: 1
Reputation: 283773
Right now, you not only have leading sign-extended bits, but also missing leading zeros.
Use
printf("0x%02x,", enc[i] & 0xFFu);
Upvotes: 0
Reputation: 145899
Change buf
and enc
type at declaration from char
to unsigned char
.
It is implementation-defined whether char
is a signed
or unsigned
type and in your implementation it is apparently a signed
type.
Upvotes: 3