print_r(bin2hex("11111111"));
echo '</br>';
print_r(bindec("11111111"));
Result
131313131313131
255
I want a hexadecimal 16 byte value to do aes encryption.How is the conversion from binary to hex happening in php.I am getting incorrect value using the function.Also when i convert an array of hexadecimal values to string the byte length changes
You get a correct result, it's just not what you want. bin2hex() returns an ASCII string of the hexadecimal representation. A quote from the manual:
Returns an ASCII string containing the hexadecimal representation of str.
So If you want the hexadecimal number you can use this:
print_r(dechex(bindec("11111111")));
The converter to get hexidecimal is dechex(), but it needs a decimal number. To do that we convert you binary string to a decimal number first using bindec() and then pass it into dechex(), e.g:
print_r(dechex(bindec("11111111")));
<?php
$str = "Hello world!";
echo bin2hex($str) . "<br>";
echo pack("H*",bin2hex($str)) . "<br>";
?>
PHP.NET Manual :
http://php.net/manual/en/function.bin2hex.php
Test Your Result : http://www.cs.princeton.edu/courses/archive/fall07/cos109/bc.html
Detailed Explanation:
http://www.computerhope.com/binhex.htm
It's simply 9 * 16 + F where F is 15 (the letters A thru F stand for 10 thru 15). In other words, 0x9F is 159.
It's no different really to the number 314,159 being:
3 * 100,000 (10^5, "to the power of", not "xor")
+ 1 * 10,000 (10^4)
+ 4 * 1,000 (10^3)
+ 1 * 100 (10^2)
+ 5 * 10 (10^1)
+ 9 * 1 (10^0)
for decimal (base 10).
The signedness of such a number is sort of "one level up" from there. The unsigned value of 159 (in 8 bits) is indeed a negative number but only if you interpret it as one.
Related
I have a large binary buffer in PHP script, finding a specific position. I need to convert 4-byte value to 32bit integer.
$seg = hex2bin("AABBCC00010014AABBCC");
$findStart=3;
echo bin2hex($seg[$findStart+0]);
echo bin2hex($seg[$findStart+1]);
echo bin2hex($seg[$findStart+2]);
echo bin2hex($seg[$findStart+3]);
Prints:
00010014
I need to convert seg[findStart+0 .. findStart+3] to 32bit integer. How to do it in PHP script? This example is a decimal number 65556.
This is exactly the purpose of the unpack function, which takes a format string and extracts data from a binary string.
Looking at the list of format codes, and your example, I believe you want
N: unsigned long (always 32 bit, big endian byte order)
So it would look something like this:
$int = unpack('Nvalue', $seg, $findStart)['value'];
For compatibility with older versions of PHP (<7.1), you can emulate the offset argument by consuming a fixed number of bytes into an ignored variable:
$int = unpack("c{$findStart}ignore/Nvalue", $seg)['value'];
You can use ord() to convert a single byte into an integer, then use the left shift and the bitwise-or operator. The first byte you will shift 24 bits to the left, the second byte you will shift 16 bytes to the left, the third 8 bytes.
$a = ord($seg[$findStart+0]);
$b = ord($seg[$findStart+1]);
$c = ord($seg[$findStart+2]);
$d = ord($seg[$findStart+3]);
$newInt = ($a << 24) | ($b << 16) | ($c << 8) | $d;
why does the next operation fails to show me a float with 8 decimals?
echo round(round(10/100,8) * round(0.00003,8),8);
echo '<br>';
echo round(0.1 * 0.0003,8);
outputs
3.0E-6
3.0E-5
Basically I'm trying to get 10% value out of a float number.
Thank you!
The result is correct: it's the exponential notation. Essentially the number following the E is the exponent on base 10. If you need to print the decimal digits there is a specific function for that, which is number_format.
number_format(round(round(10/100,8) * round(0.00003,8),8), 8)
I am trying to xor two values which are like below:
Variable 1 : 6463334891
Variable 2 : 1000212390
When i did xor with these values in php it gives me wrong answer.
It should give me "7426059853"
This is my code
$numericValue = (int)$numericValue;
$privateKey = (int)$privateKey;
echo "Type of variable 1 ".gettype($numericValue)."<br />";
echo "Type of variable 2 ".gettype($privateKey)."<br />";
$xor_val = (int)$numericValue ^ (int)$privateKey;
echo "XOR Value :".$xor_val."<br />";
Just a total stab into the dark...
You're doing this:
echo "6463334891" ^ "1000212390";
When you want to be doing this:
echo 6463334891 ^ 1000212390;
XOR is an operation on bytes. The byte representation of the integer 6463334891 and the string "6463334891" are very different. Hence this operation will result in very different values depending on whether the operands are strings or integers. If you get your numbers in string form, cast them to an int first:
echo (int)$var1 ^ (int)$var2;
That is because you re hitting the MAXIMUM INTEGER LIMIT which is 2147483647
From the PHP Docs...
The maximum value depends on the system. 32 bit systems have a maximum
signed integer range of -2147483648 to 2147483647. So for example on
such a system, intval('1000000000000') will return 2147483647. The
maximum signed integer value for 64 bit systems is
9223372036854775807.
Thus to handle such big integers you need to make use of an extension like (GMP) GNU Multiple Precision
<?php
$v1="6463334891";
$v2="1000212390";
$a = gmp_init($v1);
$b = gmp_init($v2);
echo gmp_intval($a) ^ gmp_intval($b); //"prints" 7426059853
Else , Switch to a 64-bit system.
my solution to maintain the value of big integers is to convert them to binary (with base_convert cause decbin doesnt work) and then make the xor for every bit, to finally convert the string to decimal.
function binxor($w1,$w2)
{
$x=base_convert($w1, 10, 2);
$y=base_convert($w2, 10, 2);
// adjust so both have same lenght
if (strlen($y)<strlen($x)) $y=str_repeat(0,strlen($x)-strlen($y)).$y;
if (strlen($x)<strlen($y)) $x=str_repeat(0,strlen($y)-strlen($x)).$x;
$x=str_split($x);$y=str_split($y);
$z="";
for ($k=0;$k<sizeof($x);$k++)
{
// xor bit a bit
$z.=(int)($x[$k])^(int)($y[$k]);
}
return base_convert($z,2,10);
}
Also, to adjust large numbers to 32 bits
bindec(decbin($number))
because decbin cuts the number to 32 automatically.
What is a simple way to convert a 64 bit integer encoded as a hex string to a decimal string on a 32 bit system. It needs to be the full value, it can not be in scientific notation or truncated :/
"0c80000000000063" == "900719925474099299"
"0c80000000000063" != 9.007199254741E+17
PHP's base_convert() and hexdec() don't do the job right.
You need to use BC Math PHP extension (bundled).
First split your input string to get high and low bytes, next convert it to decimal and then do calculation via BC functions like this:
$input = "0C80000000000063";
$str_high = substr($input, 0, 8);
$str_low = substr($input, 8, 8);
$dec_high = hexdec($str_high);
$dec_low = hexdec($str_low);
//workaround for argument 0x100000000
$temp = bcmul ($dec_high, 0xffffffff);
$temp2 = bcadd ($temp, $dec_high);
$result = bcadd ($temp2, $dec_low);
echo $result;
/*
900719925474099299
*/
Have you seen the first comment to hexdec's help page on php.net?
When given large numbers, the hexdec function automatically converts
the value to scientific notation. So, "aa1233123124121241" as a
hexadecimal value will be converted to "3.13725790445E+21". If you're
converting a hexadecimal value that represents a hash value (md5 or
sha), then you need every single bit of that representation to make it
useful. By using the number_format function, you can do that
perfectly. For example :
<?php
// Author: holdoffhunger#gmail.com
// Example Hexadecimal
// ---------------------------------------------
$hexadecimal_string = "1234567890abcdef1234567890abcdef";
// Converted to Decimal
// ---------------------------------------------
$decimal_result = hexdec($hexadecimal_string);
// Print Pre-Formatted Results
// ---------------------------------------------
print($decimal_result);
// Output Here: "2.41978572002E+37"
// .....................................
// Format Results to View Whole All Digits in Integer
// ---------------------------------------------
// ( Note: All fractional value of the
// Hexadecimal variable are ignored
// in the conversion. )
$current_hashing_algorithm_decimal_result = number_format($decimal_result, 0, '', '');
// Print Formatted Results
// ---------------------------------------------
print($current_hashing_algorithm_decimal_result);
// Output Here: "24197857200151253041252346215207534592"
// .....................................
?>
echo(073032097109032116104101032118101114121032109111100101108032111102032097032109111100101114110032109097106111114032103101110101114097108046);
Essentially, a very large number. Now, why does it output 241872? I know PHP has float handlers. When I remove the leading zero, it functions as expected. What is that leading zero signifying?
If you use a leading zero, the number is interpreted by PHP as an octal number. Thus, a 9 is not a valid part of the number and the parser stops there:
0730320 (base 8)
= 7 * 8^5 + 3 * 8^4 + 3 * 8^2 + 2 * 8^1
= 7 * 32768 + 3 * 4096 + 3 * 64 + 2 * 8 (base 10)
= 241872 (base 10)
A leading zero indicates an octal integer value
Manual:
Warning
If an invalid digit is given in an octal integer (i.e. 8 or 9), the rest of the number is ignored.
Example #2 Octal weirdness
<?php
var_dump(01090); // 010 octal = 8 decimal
?>
So your number gets cut off after 0730320, which is 241872 in decimal.
010 gives you 8 (octal number)
0x10 gives you 16 (hexadecimal number)