Link to home
Start Free TrialLog in
Avatar of morees
morees

asked on

xor hex and decimal

Hi there,

I need to write a small function that will xor a hex value with a decimal value.

can someone please help with a small example.

Thanks
Avatar of sunnycoder
sunnycoder
Flag of India image

Hi morees,

hex or decimal does not matter as long as you use the xor operator correctly

x = 56 ^ 0xE4; is perfectly valid though a bit unintuitive

Sunnycoder
Avatar of morees
morees

ASKER

Thanks,

better explain this a bit more.

I need to read the char from a file, convert that char to hex an then xor it with an integer value read from a file.

My program boms out at the xor with invalid variant type conversion.
How can I cast the hex value to "1F" to 0x1F so that the xor will work.

ASKER CERTIFIED SOLUTION
Avatar of sunnycoder
sunnycoder
Flag of India image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
> need to read the char from a file

Do you mean you have a text file with a text (ASCII) representation of a number in it?
Avatar of morees

ASKER

the one file is a binary file that was xored with a key and the key file just contains the key.

the key file look like this
141592653589793238462643383279502884197169......

a byte at position x in the source file must be xored with the byte at position x in the key file.

that is what I want to do
The key file looks like ASCII.

> 141592653589793238462643383279502884197169...

Is the 2nd byte '4' as in 0x34?
Avatar of morees

ASKER

i think it should be..
Hi morees,
> the key file look like this
> 141592653589793238462643383279502884197169......

> a byte at position x in the source file must be xored with the byte at
> position x in the key file.

To understand you correctly: As the key is in hex-ascii the key file is twice as long as the encoded file, right?

For the hex->int conversion, you *could* use the strtol() function:

int hexbyte=strtol(hexstring,NULL,16);
(hexstring MUST be \0 at the third byte)

This won't be terribly efficient, though probably better by eons than a fscanf() solution. You could convert 4 bytes (or even 8 using strtoll) at once, but then you'll skid into endianess issues.

Recommendation: Use a lookup table. Here's a Perl program to create one:
my $i;
my @tab;
for $i (0 .. 0xff){
      my ($hi,$lo) = unpack("C2",sprintf "%02x",$i);
      my $arridx=($hi << 8) + $lo;
      $tab[$arridx]=$i;
      ($hi,$lo) = unpack("C2",sprintf "%02X",$i);
      $arridx=($hi << 8) + $lo;
      $tab[$arridx]=$i;
}

print "#define ERR -1\nshort lookup[65536]={";
for $i (0 .. 0xffff){
      print "\n\t" if ($i & 0xf) == 0;
      if(defined $tab[$i]){
            printf "0x%02x,",$tab[$i];
      } else {
            print  " ERR,";
      }
}
print "\n};\n";

The lookup logic is: "94" -> ASCII 0x3934 -> lookup[0x3934] -> 0x94
The nice side effect is that you'll have both upper & lower hex values and you can detect errors without major extra effort -> faaaast.

Cheers,
Stefan
In case you ask "why is this table defined as short?": All 256 possible values of (unsigned) char are valid, so you need a larger data type to store the error condition.

Stefan
Do something like the following:

#include <fstream>
#include <iostream>
using std::fstream;
using std::ios_base;
using std::cout;
using std::endl;


...
// open binary file
fstream f("my file.bin", ios_base::binary | ios_base::in);

unsigned short decimal_val = 12;
while (!f.eof())
{
    char c;
    // read char
    f.read(&c, 1);
    // do what you like, xor the value with our decimal and print it
    cout << (c ^ decimal_val) << endl;  
}



Stefan73, you assume morees knows perl ? ....