XOR two hex strings - php

I want to XOR two strings (hex-encoded) in php.
I have tried using operator ^, but I get only 0.
How can I do that? Why is it wrong?

<?php
$s1 = 'ABCDEF1234567890';
$s2 = '0987654321ABCDEF';
$x = bin2hex(pack('H*',$s1) ^ pack('H*',$s2));
?>

$x = dechex(hexdec($s1) ^ hexdec($s2));
http://codepad.org/fgRfAPAI
The problem, that you initially had is, that a hex-string is in fact a string. When you use binary operators on strings, it uses the character-codes as byte value.

You need to decode them with hex2bin() before you apply the XOR ^ operator.
Update: I always forget that this function requires PHP/5.4 or greater, which can be an issue. In such case, you need to use the not very intuitive pack() function:
$binary = pack('H*', $hexadecimal);

Based on #KingCrunch's answer here and the comments I wrote this simple loop to compare octets and build up the answer. Interestingly, this has the same result as #lawlor's answer.
$key1 = 'ABCDEF1234567890ABCDEF1234567890';
$key2 = '0987654321ABCDEF0987654321ABCDEF';
$key1_octets = str_split($key1, 2);
$key2_octets = str_split($key2, 2);
$xor = '';
foreach ($key1_octets as $id => $key1_octet) {
$xor .= dechex(hexdec($key1_octets[$id]) ^ hexdec($key2_octets[$id]));
}
print $xor;
print bin2hex(pack('H*',$key1) ^ pack('H*',$key2));
I'm not actually sure if either one is a valid result, but I put this forth for feedback and in case it helps someone else who is looking at #KingCrunch's answer without knowing how to deal with the octets.

Related

How do I preserve leading and trailing zeros in PHP?

I am trying to read a number from a database and write it to an excel file, but I am having trouble keeping leading and trailing zeros. When I checked it, I was able to see that while reading the data, PHP is treating it as a number instead of a string. I have tried type casting and concatenation of the value with an empty string. However, the following code
<?php
$a = (string) 180961.65000;
echo $a;
?>
gets the below output
180961.65
How would I preserve the zeroes?
you can try this.
$number = 180961.65000;
$string = sprintf("%f",$number);
echo $string;
//result:180961.650000
Please use quotes to identify $a as string (also use quotes with echo if possible):
$a = "180961.65000";
echo "$a";
try putting
<?php
$a = (string) "180961.65000";
echo $a;
?>
You need number_format for this
Reference - http://php.net/number_format
$a = "180961.650000000";
$total_len = strlen($a);
$dec_pos = strpos($a, ".");
$diff = $total_len - ($dec_pos +1);
$a = number_format($a,$diff);
$a = str_replace(",", "", $a);
echo $a;
The data type is changing automatically in an unclear way somewhere, while working with the variable.
Therefore I suggest to preserve the leading and trailing digits explicitly while the variable is still a string. Then add them later when the variable has become a number. It might look ugly, but it is flexible for any number of zeroes.
Like this:
// Example number, assume it was received by database
$input = "00018096.16500000";
// Get the leading and trailing zeros as string.
preg_match("/^0+/", $input, $leading);
preg_match("/0+$/", $input, $trailing);
// Mark if there is a decimal point.
$hasDigit = strpos($input, ".") !== false;
// Only for here: force the input to become a number, thus removing all trailing and leading zeros.
$input = 1 * $input;
// Now add the leading and trailing zeroes again and turn the variable back to a string.
$saveOutput = $input . "";
if (count($leading) > 0) {
$saveOutput = $leading[0] . $saveOutput;
}
// If the number is not a float with decimal point, don't add the trailing zeros as they are still there in the integer number.
if (count($trailing) > 0 && $hasDigit) {
$saveOutput = $saveOutput . $trailing[0];
}
// Show result
echo $saveOutput;
// --> Result:
// 00018096.16500000
N.B., I call the variable saveOutput because you are sure it is a string and it won't change, like the input.

is_double function in a while loop condition

I'm trying to get the fractional number count of a decimal number. I tried following simple code, but the loop runs forever.
$var = 123.456;
$fraction_count = 0;
echo $var, "<br>";
while (is_double($var)) {
$var *= 10;
$fraction_count++;
echo $var, "<br>";
}
I'm new to php so, forgive me if this is a stupid question!
Floating point numbers are not trivial to deal with (see the manual for more information). But you don't even need to deal with the number as such.
If you treat it as a string, you can explode() on the . and use strlen() on the second part to get the $fraction_count:
$var = 123.456;
$parts = explode('.', $var);
$fraction_count = strlen($parts[1]);
Since PHP doesn't save trailing 0s on numbers, this will work for 123.4560 as well, but be sure to input it as a number, "123.4560" will get you a wrong result.

Problems with PHP bitwise & operator

Alright, so i have this code:
<?php
$p = 65536;
$p2 = 33554432;
if($p & $p2){
echo "True";
}else{
echo "False";
}
?>
Alright so if i put the numbers in the script the output is "False", but when i use $_GET,$_POST, etc it returns "True" even if i put the numbers in quotes.
whats the problem?
Any help is appreciated!
Elements of $_GET and $_POST are strings. If you read the docs, it converts each character into its ordinal position, hits them with the bitwise operator, and converts back to a character.
You should call intval() on the values first.
You need to cast them to int, or you are doing & with two strings.
$p = (int)$_GET['p'];
$p2 = (int)$_GET['p2'];
if ($p & $p2) {
// ...

Finding common characters in strings

I am tring this method to find the common characters in two strings namely, $a and $r, but the first character isn't getting printed . Moreover the $already collects the common characters and prevents them from being printed for multiple times( I need each character to be printed once only) but it isn't doing so. Please tell me what errors I am making.
<?php
$a="BNJUBCI CBDIDIBO";
$r="SBKJOJLBOU";
$already="";
for($i=0;$i<strlen($r);$i++)
{
if (stripos($a,$r[$i])!=FALSE)
{
if (stripos($already,$r[$i])==FALSE)
{
$already=$already.$r[$i];
echo "already=".$already."<br>";
echo $r[$i]."<br>";
}
}
}
?>
Use !==FALSE instead of !=FALSE. The problem is that stripos returns 0 if the needle is at the start of the haystack, and 0 is falsy. By using !== you are forcing it to ensure the result is actually false, and not just 0.
This is actually listed in the docs. An "RTM" might be appropriate here.
Warning
This function may return Boolean FALSE, but may also return a non-Boolean value which evaluates to FALSE. Please read the section on Booleans for more information. Use the === operator for testing the return value of this function.
The simplest way to find the intersection of the two strings in PHP is to turn them into arrays and use the built-in functions for that purpose.
The following will show all the unique and common characters between the two strings.
<?php
$a="BNJUBCI CBDIDIBO";
$r="SBKJOJLBOU";
$a_arr = str_split($a);
$r_arr = str_split($r);
$common = implode(array_unique(array_intersect($a_arr, $r_arr)));
echo "'$common'";
?>
I would think a much simpler solution to this would be to make the strings into arrays and compare those no?
Something like:
<?php
$a="BNJUBCI CBDIDIBO";
$r="SBKJOJLBOU";
$shared = implode( '' , array_intersect( str_split($a) , str_split($r) ) );
?>
That should return you a string of all the characters in $a that are present in $r

Do the math sum of a text variable? (E.g 5865/100 )

I have a variable that is...
$whatever = "5865/100";
This is a text variable.
I want it to calculate 5865/100 , so that I can add it to other numbers and do a calculation.
Number_format doesn't work, as it just returns "5,865". Whereas I want it to return 58.65
I could do...
$explode=explode("/",$whatever);
if(count($explode)=="2") {
$whatever = $explode[0]/$explode[1];
}
But it seems rather messy. Is there a simpler way?
Evaluate as PHP expression, but first check if it contains only digits and operators and space, and suppress any errors.
if (preg_match('/^[\d\+\-\/\*\s]+$/', $s)) {
#eval('$result = ' . $s . ';');
}
You can use the eval function to evaluate a string as code. However, you have to be careful as to where this code comes from because it will execute anything passed to it, not just simple math. If you knew your string contained a mathematical formula, you could do the following
$answer = 0;
$whatever = "5865/100";
eval ('$answer = ' . $whatever . ';');
print($answer);

Categories