I have this code in C++, which returns outputs the following number
int main(int argn, char** argv)
{
cout << (*((unsigned long*)"P3TF")) << endl;
cin.get();
return 0;
}
How can I achieve the above in PHP (i.e. the string "P3TF" in unsigned long int). I tried using the pack method:
<?php
$lol = pack('N', 'P3TF');
var_dump( $lol, // returns jumbled up characters
ord($lol[0]), // returns int 0
ord($lol[1]), // returns int 0
ord($lol[2]), // returns int 0
ord($lol[3]), // returns int 0
ord($lol[0]).ord($lol[1]).ord($lol[2]).ord($lol[3]) // returns 4 zeros as a string.
);
?>
I need it in bigendian byte order so I haven't used pack('V') or pack('L').
Anyone know how to achieve this?
Thanks!
If it's literally "P3TF" in the real code, why not convert it once, and define a constant in the PHP code?
Failing that, you need unpack, not pack. e.g. running
<?php
$in = 'P3TF';
$arr = unpack('N', $in);
printf("%08x\n", $arr[1]);
?>
Gives 50335446, which is the ASCII codes for 'P' '3' 'T' 'F' in hex (concatenated)
Related
I try to convert any string into binary. But if binary start with zeros, it doesn't display it. All my test give me the binary value from the first 1 until end. Here my code :
$value = unpack('H*', $MESSAGE);
$binary .= base_convert($value[1], 16, 2);
For example when I tried to convert the character "%" it display : 100101 instead of : 00100101
Did I forget something?
Thanks.
Yacine
It is easy to see that the question boils down to the following:
Why base_convert($value[1], 16, 2) does not zero-pad the result?
The reason is that base_convert interprets the first argument as a number (not a string of bytes, for example); it stops converting the bytes after the most significant bit is reached:
static char digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
char buf[(sizeof(zend_ulong) << 3) + 1];
char *ptr, *end;
zend_ulong value;
if (Z_TYPE_P(arg) != IS_LONG || base < 2 || base > 36) {
return ZSTR_EMPTY_ALLOC();
}
value = Z_LVAL_P(arg);
end = ptr = buf + sizeof(buf) - 1;
*ptr = '\0';
do {
*--ptr = digits[value % base];
value /= base;
} while (ptr > buf && value);
return zend_string_init(ptr, end - ptr, 0);
(i.e. when the value becomes zero.) The behavior is correct, since it is possible to add any number of zeroes up after the most significant bit without changing the result, e.g. 100101 is equal to 00100101.
The function does not have a parameter that affects the formatting of the result. So, in order to achieve the desired output, you need to use other function(s) such as sprintf.
I am trying to convert a hex string into a signed integer.
I am able to easily transfer it into an unsigned value with hexdec() but this does not give a signed value.
Edit:
code in VB - the two "AA" hex values are representative.
Dim bs(2) As Byte
bs(1) = "AA"
bs(2) = "AA"
Dim s As Short
s = BitConverter.ToInt16(bs, 1)
Check out this comment via php.net:
hexdec() returns unsigned integers. For example hexdec("FFFFFFFE") returns 4294967294, not -2. To convert to signed 32-bit integer you may do:
<?php
echo reset(unpack("l", pack("l", hexdec("FFFFFFFE"))));
?>
As said on the hexdec manual page :
The function can now convert values
that are to big for the platforms
integer type, it will return the value
as float instead in that case.
If you want to get some kind of big integer (not float), you'll need it stored inside a string... This might be possible using BC Math functions.
For instance, if you look in the comments of the hexdec manual page, you'll find this note
If you adapt that function a bit, to avoid a notice, you'll get :
function bchexdec($hex)
{
$dec = 0;
$len = strlen($hex);
for ($i = 1; $i <= $len; $i++) {
$dec = bcadd($dec, bcmul(strval(hexdec($hex[$i - 1])), bcpow('16', strval($len - $i))));
}
return $dec;
}
(This function has be copied from the note I linked to ; and only a bit adapted by me)
And using it on your number :
$h = 'D5CE3E462533364B';
$f = bchexdec($h);
var_dump($f);
The output will be :
string '15406319846273791563' (length=20)
So, not the kind of big float you had ; and seems OK with what you are expecting :
Result from calc.exe =
15406319846273791563
Hope this help ;-)
And, yes, user notes on the PHP documentation are sometimes a real gold mine ;-)
I've been trying to find a decent answer to this question and so I wrote this function which works well for a Hex string input, returning a signed decimal value.
public function hex_to_signed_int($hex_str){
$dec = hexdec($hex_str);
//test is value negative
if($dec & pow(16,strlen($hex_str))/2 ){ return $dec-pow(16,strlen($hex_str));}
return $dec;
}
I'm trying to convert PHP code to C++.
$this->Key + 1 + log2p (floor($TimePlot/$this->kY)*M_PI-2*20
In PHP Key is string in C++ key2 is char*, timeplot is time_t and val is int.
key2 + 1 + log2(floor((double)timeplot/this->val*M_PI-2*20))
and the error is:
error C2111: '+' : pointer addition requires integral operand
I don't know what to do to make it working. Thanks in advance.
If your $this->key is string, and you want to end up with a string in C++ also, then you need to do something like this:
char bf[1024];
sprintf (bf, "%f", 1.0 + log2(floor((double)timeplot/this->val*M_PI-2*20)) );
std::string k = key2;
k += bf;
assuming everything else in your expression resolve to numeric values that can participate in numeric calculations. I used a buffer length of 1024 bytes here, you can adjust it accordingly.
Ok i wanted to create a crawler with my PHP script. Certain parts of my crawler requires real fast manipulation of strings thats why i have decided to use a C/C++ program to assist my PHP script for that particular job. The following is my code:
$op=exec('main $a $b');
echo $op;
main is the executable file generated using my C file main.c i.e main.exe. in the above operation i just made a simple C program which accepts 2 values from PHP and returns the sum of the two values. the following is how my C program in looking like
#include< stdio.h >
#include< stdlib.h >
int main(int argc, char *argv[])
{
int i=add(atoi(argv[1]),atoi(argv[2]));
printf("%d\n",i);
return 0;
}
int add(int a, int b)
{
int c;
c=a+b;
return c;
}
i tried to execute the program via the CMD main 1 1 and it returned 2....it worked! when i entered them in the php script like this,
$a=1;
$b=1;
$op=exec('main $a $b');
echo $op;
it didn't work as expected so any ideas, suggestions or anything else i need to do on my code. I would be great if you could show me an example. THANKS IN ADVANCE!!!
You should enclosed the arguments of exec with double quotes since you're passing variables. And the output of your program is in the second argument of exec.
exec("main $a $b", $out);
print_r($out);
See exec() reference.
The function atoi() cannot distinguish invalid and valid inputs.
I suggest you use strtol() instead.
#include <stdio.h>
#include <stdlib.h>
void quit(const char *msg) {
if (msg) fprintf(stderr, "%s\n", msg);
exit(EXIT_FAILURE);
}
int add(int, int);
int main(int argc, char *argv[]) {
int a, b, i;
char *err;
if (argc != 3) quit("wrong parameter count");
a = strtol(argv[1], &err, 10);
if (*err) quit("invalid first argument");
b = strtol(argv[2], &err, 10);
if (*err) quit("invalid second argument");
i = add(a, b);
printf("%d\n", i);
return 0;
}
int add(int a, int b) {
return a + b;
}
You need to create an executable ./main.
And then use this code.It works
<?php
$a=1;
$b=1;
echo exec("./main $a $b");
?>
I am trying to pass over from php a string into C++, i managed to figure out how to pass numbers, but it doesn't work for letters. Here's what i have that works for PHP
<?php
$r = 5;
$s = 12;
$x= 3;
$y= 4;
$q= "Hello World";
$c_output=`project1.exe $r $s $x $y $q`; // pass in the value to the c++ prog
echo "<pre>$c_output</pre>"; //received the sum
//modify the value in php and output
echo "output from C++ programm is" . ($c_output + 1);
?>
This sends the variables r,s,x,y, and q to the C++ programm project1.exe and IT WORKS, but the problem is that it doesn't work for the string variable $q.
Here's the code that I have in my C++ programm, it's simple:
#include<iostream>
#include<cstdlib>
#include<string>
using namespace std;
int main(int in, char* argv[]) {
int val[2];
for(int i = 1; i < in; i++) { // retrieve the value from php
val[i-1] = atoi(argv[i]);
}
double r = val[0];
double s = val[1];
double x = val[2];
double y = val[3];
double q = val[4]; // here's the problem, as soon as i try to define val[4] as a string or char, it screws up
cout << r;
cout <<s;
cout << x;
cout << y;
cout << q;
// will output to php
return 0;
}
It works, but for the string "Hello world" which i pass through $q from PHP doesn't give me the string back (i know it's defined as a double, but as soon as i try to change it to a string or a char variable the code just doesn't compile).
Please explain to me how i have to go around this problem so that $q can be processed as a string. FYI, I am a newbie to programming (6 months in).
Try not converting the final argument using atoi(argv[i]). Just keep it as argv[i].
for(int i = 1; i < in-1; i++)
{
val[i-1] = atoi(argv[i]);
}
q = argv[i];
It doesn't work for letters because you are doing atoi(..)(which converts char-string to integer) in the C++ program.
Have some means of letting the program know what to expect -- whether a number or a string. May be the first argument can help the program differentiate, like may be the following:
$c_output = `project1.exe nnsnns 1 2 string1 3 4 string2`
Then you could do:
for(int i = 0/*NOTE*/,len=strlen(argv[1]); i < len; i++) { // retrieve the value from php
if (argv[1][i] == 'n'){
//argv[2+i] must be an integer
}else if (argv[1][i] == 's'){
//argv[2+i] is a string
}
}
Of course you should check if (strlen(argv[1]) == in-2).
BTW, in the C++ code above, val is a array holding 2 ints; and you are trying to access much beyond index 1.
To pass one single string to the C++ you would do something like the following:
$output = `project1.exe $q`; //Read below.
NOTE: $q must be a single word. No spaces, no extra characters like '|', '&', or any other character which the shell might interpret differently. $q must be clean before you pass that on to C++ Program. If $q is more than one word, use quotes.
C++ Part (Just try the following, then you can modify as you go along)
cout<<argv[1]<<endl;