So, I have numeric values from 0 to 15, so I saved them in hex codes (0 to f). Now I have a string of data containing hex code values of my nibbles.
Data looks like this:
a0fc3d78270db962e4ba525cf3acd
What is the accurate/elegant/fast way of performing binary xor on two nibbles and what would be the fastest way of performing a binary not on a nibble?
What I have in mind right now is to first convert the nibbles into full bytes:
$nibble = "c";
$numeric = ord($nibble);
$byte = ($numeric<58)?chr($numeric-48):chr($numeric-55);
Then perform the desired operation (xor or not) on these bytes, and reconvert the resultant value into a nibble again.
$byte1 = chr(7); $byte2=chr(12);
$xor_val = $byte1 ^ $byte2;
$numeric = ord($xor_val);
$nibble = ($numeric<58)?chr($numeric+48):chr($numeric+55);
The problem with this approach is that if I apply a not (~) operation on a byte, it reverses the first 4 bits too (hence adding 1111 to the left side of the nibble), and I have to get into an extra complexity of subtracting 240 from the ord() value of the result before I reconvert it into a nibble with the code presented above. This does not only make it cumbersome for future upgrades to the code, but also makes it harder to interpret the functionality of the code in the future.
What is the best/accurate way of performing bitwise xor and not on nibbles and having the resultant value as a hex code (string)?
Examples:
'3' xnor 'a' = '6'
'c' xnor '5' = '6'
'b' xnor '8' = 'c'
Using a binary AND operation to only select relevant bits:
This is called "masking off" bits, where
0x0F
is called the "mask".Without masking, the result of the operation
~(0x0b ^ 0x08)
would beffffffffffffffffc
, due to PHP representing integers as 64-bit longs.Now when we apply the mask, the following happens (I left out the 4 upper bytes for easier visualization):
We "select" only the lower last nibble.
To mask the upper nibble, use
0xF0
and (optionally) shift right 4.