I have a string which value is 123, like: $string = '123'; and my hex value, which is $hex = bin2hex($string); and the return is 313233. When i convert to string again, using hex2bin(), it returns 123 correctly. But when i try to make a "compare" it always returns both like a hexadecimal value.
I know that each number, both 1, 2 and 3 are part of hexadecimal table, but, is there a way that can i differentiate each one ? I'd already searched something about it, but i got no solution.
I'm sorry if this question is poor. But it will really helped me. Besides, it's a doubt that i have.
My php code:
<?php
$string = '123';
$hex = bin2hex($string);
if(hex2bin($hex)){
echo 'hex';
}else{
echo 'not hex';
}
?>
As far as I understand, you are looking for the ctype_xdigit() function, which returns true if all the individual letters in your string are hexadecimal digits, otherwise false.
You just have to pass the string as a parameter:
if (ctype_xdigit($hex_string)){
echo 'hex';
} else {
echo 'not hex';
}
What you did in your original code was converting binary numbers to hexadecimals and then the other way round. It's no surprise that it didn't give you the expected results, as 123 is not a binary number, in the input there couldn't be any other digits than 0 and 1.
firstly, functions don't work as you think they do, i.e. if(hex2bin($hex)) is kind of nonsense when used like that. (it returns "123" which will always evaluate as "true")
secondly, consider using ctype_xdigit which does what you want
<?php
$string = '123';
$hex = bin2hex($string);
if(ctype_xdigit($hex)){
echo 'is a hex value (was originally '+hex2bin($hex)+')';
}else{
echo 'not hex';
}
?>
Related
I've got a string representing an IPv4 address:
$ip = '\x7F\0\0\x01';
When I try to pass that to inet_ntop($ip) it's giving me grief:
PHP Warning: inet_ntop(): Invalid in_addr value
If I declare the variable manually using double quotes it works:
$ip = "\x7F\0\0\x01";
inet_ntop($ip); // "127.0.0.1"
However, I am not declaring these variables manually. I'm working with what is given to me in an object.
How can I convert '\x7F\0\0\x01' into a string that inet_ntop() will accept?
In other words, how can I make PHP parse a string literally as if I were manually declaring it with double quotes?
Some interesting facts:
gettype('\x7F\0\0\x01'); // string
gettype("\x7F\0\0\x01"); // string
ord('\x7F\0\0\x01'); // 92
ord("\x7F\0\0\x01"); // 127
implode(unpack('H*', '\x7F\0\0\x01')); // 5c7837465c305c305c783031
implode(unpack('H*', "\x7F\0\0\x01")); // 7f000001
mb_detect_encoding('\x7F\0\0\x01'); // ASCII
mb_detect_encoding("\x7F\0\0\x01"); // UTF-8
"\x7F\0\0\x01" == '\x7F\0\0\x01'; // false
// and for the haters
long2ip('\x7F\0\0\x01'); // PHP Warning: long2ip() expects parameter 1 to be integer, string given
One possibility is to parse the string into its component pieces (starting with \); convert them to the decimal equivalent and use chr to get back the original characters. These can then be joined into a string which is suitable for inet_ntop:
$ip = '\x7F\0\0\x01';
preg_match_all('/\\\x?([\dA-F]+)/', $ip, $parts);
$ip = implode('', array_map(function ($v) { return chr(hexdec($v)); }, $parts[1]));
echo inet_ntop($ip);
Another alternative is to use pack, after stripping out the \x parts and replacing \0 with 00:
$ip = '\x7F\0\0\x01';
$ip = pack('H*', str_replace(array('\x', '\0'), array('', '00'), $ip));
echo inet_ntop($ip);
In both cases the output is:
127.0.0.1
Demo on 3v4l.org
The problem is that you've got the literal ASCII output of a binary string and not the real binary value you expect it to be. I'm not sure how you got the literal ASCII value. There is a way to convert it, but you're not going to like it.
You can use eval() to accomplish what you're trying to do. All arguments for eval() being evil still apply.
$ip = '\x7F\0\0\x01';
eval("\$ip = \"$ip\";");
echo inet_ntop($ip);
This will print out 127.0.0.1.
Since binary doesn’t always result in literal ASCII characters, I worry you’ll see literal characters like � in the strings, and these won’t convert properly to the binary value you expect them to be.
For example, here are the characters printed to screen in Psysh:
>>> hex2bin('7f000001') // This is 127.0.0.1
=> "\x7F\0\0\x01"
>>> hex2bin('ffffffff') // This is 255.255.255.255
=> b"ÿÿÿÿ"
The first value looks familiar, right? That's the string literal that we can convert back into a binary string using eval(), like we did in the example above. But the binary value for ffffffff is a different story. If we try to convert it, it doesn't give us the 255.255.255.255 value we expect.
$ip = 'ÿÿÿÿ';
eval("\$ip = \"$ip\";");
echo inet_ntop($ip);
In this case, inet_ntop() returns false, but we know it should work:
>>> inet_ntop(hex2bin('ffffffff'));
=> "255.255.255.255"
So, I worry that any attempt to convert these values from string literals into binary strings is not going to work in all cases, whether using eval() or any of the other answers provided here.
However, if everything is coming to you in the format \0\0\0\0, where each "segment" is either a zero or a hex value in the format x00, then you should be in good shape, because these are the same:
>>> "\xFF\xFF\xFF\xFF"
=> b"ÿÿÿÿ"
You can make your own function like this
function convertStringToInAddr(string $string) {
$return = null;
$exploded = explode("\\", $string);
foreach($exploded as $hex) {
if( $hex != "" ) {
$return .= chr(hexdec(str_replace("x", "", $hex)));
}
}
return $return;
}
I am trying to convey $string to float. The type of $string is string in the format of "0.0111455667". I have the following code in php.I have tried all these methods and I got 0 for all of them. how can I convert the string to float?why I always get 0?
PS: please do not assume my question as duplicate, I have already tried all the methods in the similar questions and none of them worked for me.
$float = (float) $string;
//$float2 = $string + 0.0; //this works as well.
$floatval = floatval($string);
$double = (double) $string;
// TEST
echo $string;
echo $float;
//echo $float2;
echo $floatval;
echo $double;
Your problem is the content of $string.
In PHP, every time you convert a string to a float, be it by casting (float) $string, or floatval($string), you will always get 0 if the first character of the string is not numeric.
From PHP docs: String conversion to numbers
The value is given by the initial portion of the string. If the string starts with valid numeric data, this will be the value used. Otherwise, the value will be 0 (zero)
Double-check the content of $string. Probably you have some spurious characters at its beginning.
If i have some code in index.php
if ($_GET['x']==="\x01\x03\x03\x07")
{
echo 'OK';
}
So, how i could pass value x in url index.php?x=??? to get output 'OK'.
Thanks!
so, url must be like this:
... index.php?x=\x01\x03\x03\x07
and your $_GET must be like this:
$_GET['x'] = "\\x01\\x03\\x03\\x07";
It will return "OK"
To compare '\x01\x03\x03\x07'(hex value) with variable x that you sent in the url, first you have to change '\x01\x03\x03\x07' to '\\x01\\x03\\x03\\x07'. Why ? because if you don't double the '\' you won't be able to compare these.
So, you have to place the hex in a variable like this:
$hex = "\x01\x03\x03\x07";
and you will compare 'x' with edited $hex (the value be "\\x01\\x03\\x03\\x07").
to make edited/fixed $hex we have to use a function, str_ireplace().
here's the example:
$hex = "\x01\x03\x03\x07";
$hex_able_to_compare = "\\x01\\x03\\x03\\x07";
$fixed = str_ireplace($hex,$hex_able_to_compare,$hex);
if ($_GET['x'] == $fixed){
echo "OK!";
}
else {
echo "Not OK!";
}
So you can still compare your hex with place your hex to $hex variable.
But the problem is: what if the the hex value is dynamic? we should make the value of $hex_able_to_compare as dynamic too,. :D
To passing the hex value in URL you need character "%" before hex code. For example, %20 stand for space character.
So URL you need is:
index.php/x=%01%03%03%07
You can references HTML URL Encode here
P/s: I think you are playing ctf.wargamevn.vn ;))
I'm new to Xor encryption, and I'm having some trouble with the following code:
function xor_this($string) {
// Let's define our key here
$key = ('magic_key');
// Our plaintext/ciphertext
$text =$string;
// Our output text
$outText = '';
// Iterate through each character
for($i=0;$i<strlen($text);)
{
for($j=0;$j<strlen($key);$j++,$i++)
{
$outText .= $text{$i} ^ $key{$j};
//echo 'i='.$i.', '.'j='.$j.', '.$outText{$i}.'<br />'; //for debugging
}
}
return $outText;
}
When I run this it works for normal strings, like 'dog' but it only partially works for strings containing numbers, like '12345'.
To demonstrate...
xor_this('dog') = 'UYV'
xor_this('123') = ''
It's also interesting to note that xor_this( xor_this('123') ) = '123', as I expect it to. I'm pretty sure the problem resides somewhere in my shaky understanding of bitwise operators, OR possibly the way PHP handles strings that contain numbers. I'm betting there's someone clever out there that knows exactly what's wrong here. Thanks.
EDIT #1: It's not truly 'encryption'. I guess obfuscation is the correct term, which is what I'm doing. I need to pass a code containing unimportant data from a user without them being able to easily tamper with it. They're completing a timed activity off-line and submitting their time to an online scoreboard via this code. The off-line activity will obfuscate their time (in milliseconds). I need to write a script to receive this code and turn it back into the string containing their time.
How i did it, might help someone ...
$msg = 'say hi!';
$key = 'whatever_123';
// print, and make unprintable chars available for a link or alike.
// using $_GET, php will urldecode it, if it was passed urlencoded
print "obfuscated, ready for url: " . urlencode(obfuscate($msg, $key)) . "\n";
print "deObfuscated: " . obfuscate(obfuscate($msg, $key), $key);
function obfuscate($msg, $key) {
if (empty($key)) return $msg;
return $msg ^ str_pad('', strlen($msg), $key);
}
I think you might have a few problems here, I've tried to outline how I think you can fix it:
You need to use ord(..) to get the ASCII value of a character so that you can represent it in binary. For example, try the following:
printf("%08b ", ord('A')); // outputs "01000001"
I'm not sure how you do an XOR cipher with a multi-byte key, as the wikipedia page on XOR cipher doesn't specify. But I assume for a given key like "123", your key starts "left-aligned" and extends to the length of the text, like this:
function xor_this($text) {
$key = '123';
$i = 0;
$encrypted = '';
foreach (str_split($text) as $char) {
$encrypted .= chr(ord($char) ^ ord($key{$i++ % strlen($key)}));
}
return $encrypted;
}
print xor_this('hello'); // outputs "YW_]]"
Which encrypts 'hello' width the key '12312'.
There's no guarantee that the result of the XOR operation will produce a printable character. If you give us a better idea of the reason you're doing this, we can probably point you to something sensible to do instead.
I believe you are faced with console output and encoding problem rather than XOR-related.
Try to output results of xor function in a text file and see a set of generated characters. I believe HEX editor would be the best choice to observe and compare a generated characters set.
Basically to revert text back (even numbers are in) you can use the same function:
var $textToObfuscate = "Some Text 12345";
var $obfuscatedText = $xor_this($textToObfuscate);
var $restoredText = $xor_this($obfuscatedText);
Based on the fact that you're getting xor_this( xor_this('123') ) = '123', I am willing to guess that this is merely an output issue. You're sending data to the browser, the browser is recognizing it as something which should be rendered in HTML (say, the first half dozen ASCII characters). Try looking at the page source to see what is really there. Better yet, iterate through the output and echo the ord of the value at each position.
Use this code, it works perfect
function scramble($inv) {
$key=342244; // scramble key
$invarr=str_split($inv);
for($index=0;$index<=strlen($inv)-1;$index++) {
srand($key);
$var=rand(0,255);
$res=$res.(chr(ord($var)) ^ chr(ord($invarr[$index])));
$key++;
}
return($res);
}
Try this:
$outText .= (string)$text{$i} ^ (string)$key{$j};
If one of the two operands is an integer, PHP casts the other to an integer and XORs them for a numeric result.
Alternatively, you could use this:
$outText .= chr(ord($text{$i}) ^ ord($key{$j}));
// Iterate through each character
for($i=0; $i<strlen($text); $i++)
{
$outText .= chr(ord($text{$i}) ^ ord($key{$i % strlen($key)))};
}
note: it probably will create some weird characters...
Despite all the wise suggestions, I solved this problem in a much simpler way:
I changed the key! It turns out that by changing the key to something more like this:
$key = 'ISINUS0478331006';
...it will generate an obfuscated output of printable characters.
OK, so there is a page I'm querying on another server that returns a comma separated list of two values. Something it would return would be:
850,640
I have some PHP code that calls file_get_contents on that page and needs to do some numeric calculations based on the two values.
No matter what I try, I can't seem to get an int value out of this.
$res = trim(file_get_contents('http://thatURL/'));
echo "X" . $res . "X<br/>";
list($x,$y) = array_map(create_function('$a', 'return (int)$a;'), explode(',', $res));
echo "X:$x";
results in the output:
X 850,640 X
X:0
Note the spaces before and after the comma separated values(how the hell? I trim'd them!) and that $x is assigned the value 0.
What am I doing wrong here?
What am I doing wrong here?
Nothing, as far as I can see, which indicates that the content of $res is not quite what you expect. Could you change the first echo to:
echo htmlentities($res);
My guess is $res contains some un-printed characters, for example, it is actually:
<span> </span>850,640<span> </span>
or
850,640
Try the following. The array_map and llamda function are arguably overkill for your usage.
$res = " 850,640 ";
echo "X" . $res . "X<br/>";
list($x,$y) = explode(',', trim($res));
echo "X:" . (int)$x;
echo "Y:" . (int)$y;
Worked for me, but I'm not using file_get_contents(). If that doesn't work, something else is being output by the page.
PHP is not a typed language. Use intval to convert a string to integer.
Correction: it is a loosely typed language! That's what I meant!
Since I was using file_get_contents() on a URL, there was some HTML being put in as well that I didn't notice in my echo because it parsed out... just empty body and html tags. Oops!