I'm trying to convert from ASCII to HEX in PHP but get a different result to some of the online tools that are available. I know the result I'm looking for so the online tool's result appear to be correct and my code incorrect but I can't work out why.
String: 2Ffbj?DoyXOU
Correct output: 32 46 66 62 6a 3f 44 6f 79 58 4f 55 (from linked site above)
My output: 32 46 66 62 6a 3f 44 6f 79 58 4f 75
My script:
echo bin2hex(utf8_decode("2Ffbj?DoyXOU"));
Where is the fault?
Use that:
function ascii2hex($ascii) {
$hex = '';
for ($i = 0; $i < strlen($ascii); $i++) {
$byte = strtoupper(dechex(ord($ascii{$i})));
$byte = str_repeat('0', 2 - strlen($byte)).$byte;
$hex.=$byte." ";
}
return $hex;
}
The result:
Try this:
function ascii2hex($arg){
return implode(" ",array_map(fn($x) => sprintf("%02s",strtoupper(dechex(ord($x)))),str_split($arg)));
}
Thanks Patrick Maciel for the good answer.
Now if use PHP 7.4, there maybe an error message "Array and string offset access syntax with curly braces is no longer supported". Using "[" and "]" to replace "{" and "}" can solve the problem.
Reference:
Array and string offset access syntax with curly braces is deprecated
Related
I want to display the character codes of a string in php.
<?php
$Text = '{"text":"سلام"}';
for($i = 0;$i < strlen($Text);$i++){
echo mb_ord($Text[$i]),"<br>";
}
?>
But its output is null
You are trying to get all "bytes" of the unicode string. You need to use mb_strlen() to get the real length of the characters.
Then, you need to use mb_substr() to get the right character.
$Text = '{"text":"سلام"}';
for($i = 0; $i < mb_strlen($Text); $i++) {
echo mb_ord(mb_substr($Text,$i, 1)), "<br>";
}
Output :
123
34
116
101
120
116
34
58
34
1587
1604
1575
1605
34
125
See also all mb_* functions
NodeJS code:
const salt = new Buffer('GHlDHToiZA1ViUu+W+EXww==', 'base64');
Output like this:
<Buffer 18 79 43 1d 3a 22 64 0d 55 89 4b be 5b e1 17 c3>
I need the same output in PHP. Read somewhere about PHP's pack function but I don't know how to use it.
Seems that you are working with base64; in php you are right pack and unpack is your friends.
example
in Node
$ node
> Buffer('hello world').toString('base64')
aGVsbG8gd29sZA==
in PHP
$ php -a
php > echo base64_encode('hello world');
aGVsbG8gd29ybGQ=
But if you are only looking for the binary:
in Node
> Buffer('hello wold')
<Buffer 68 65 6c 6c 6f 20 77 6f 6c 64>
in PHP
php > print_r(unpack('H*', 'hello world'));
Array
(
[1] => 68656c6c6f20776f726c64
)
So in your instance you would first decode the base64 and then unpack it.
php > $raw = base64_decode('GHlDHToiZA1ViUu+W+EXww==');
php > print_r(unpack('H*', $raw));
Array
(
[1] => 1879431d3a22640d55894bbe5be117c3
)
Easy peasy ;)
I have the same problem, and i found solution using the packet: lcobucci/jwt.
Must to create a buffer by your key in base64, after create will be converting to binary for sign the jwt.
$configuration = Configuration::forSymmetricSigner(
// You may use any HMAC variations (256, 384, and 512)
new Sha256(),
// replace the value below with a key of your own!
InMemory::base64Encoded('your-base64-key')
// You may also override the JOSE encoder/decoder if needed by providing extra arguments here
);
I have this example data to be converted into hex
$converToHex = "##X27,5556789,A89,2*";
$convertedHex = bin2hex($converToHex);
how do I add spaces so that i can output something like this
23 23 58 32 37 2c 35 35 35 36 37 38 39 2c 41 38 39 2c 32 2a
Thank you in advance.
Use chunk_split() function in php to split the string into smaller parts.Use the code below :
<?php
$converToHex = "##X27,5556789,A89,2*";
$convertedHex = bin2hex($converToHex);
echo chunk_split($convertedHex, 2, ' ');
?>
Hope this helps you.
You can use the str_splitt function
In your case :
$converToHex = "##X27,5556789,A89,2*";
$convertedHex = bin2hex($converToHex);
$hexTab = str_split($convertedHex,2);
foreach($hexTab as $b){
echo $b." ";
}
I have a file with hex code and I need to get all the least significant bits from every byte in the file, concatenate them, split them in groups of 8 and then convert the bytes into ASCII. My problem is to extract the LSB from every byte.
The hex file looks like this (but is much longer):
58 00 00 1F 58 00 00 00 00 00 00 00 00 00 00 1C 22 23 1F 26 25 1E 2C 26 20 31 2B 22 38 2F 26 42 36 25 47 37 24 49 39 22
My code looks like this:
<?php
// Read file, remove spaces
$file = implode('', explode(' ', file_get_contents('vogel.hex')));
// Save LSB
$bits = array();
for ($i = 1; $i < strlen($file); ++$i)
{
$bits[] = $file[$i] & 1;
}
// Split LSB array into chunks of 8 bits.
$bytes = array_chunk($bits, 8);
// Implode byte arrays, convert to decimal, convert to ASCII.
foreach ($bytes as $byte)
{
echo chr(bindec(implode('', $byte)));
}
?>
I think that the splitting and converting part should work correctly, but I think I made a mistake when extracting the LSB. Can someone provide an example how I can extract the LSB?
I slightly edited my code, so that I start reading the bits at position 1. Then the decimal representation is within the ASCII range and the script outputs an actual ASCII character.
You could simply build up the bit string within the for loop, skipping the entire array procedure:
$bits = '';
for ($i = 1; $i < strlen($file); $i++) {
$bits .= (($file[$i] & 1) == 0) ? '0' : '1';
if ($i % 8 == 0) {
echo bindec($bits);
$bits = '';
}
}
Of course, you'd have some dangling bits if the input file's size isn't a multiple of 8.
A lot of programmers might cringe at your solution, but it works just fine with both ASCII and EBCDIC. I don't know of any other character set one might possibly be using with PHP.
The least significant bit of the character digit is the same as the value it represents. So your code will work. But it really deserves to have a comment explaining it relies on the least significant bit of the ASCII/EBCDIC display codes being the same as the digit.
what about shifting the hex left for hexvalue/2 times?
$hex = 0x05;
$shiftVal = (0 + $hex)/2;
echo $hex>>$shiftVal;//should output 1
another approach is to convert the hex to a number and see if it's odd or even:
$hex = 0xad;
echo $hex%2;
<?php
$file = 'file.dat';
$file_contents = file_get_contents($file);
for ($i = 0x000481; $i <= 0x00048B; $i++) {
print $i;
}
?>
I am creating an online file analyzer but I have a small problem. It outputs (which is the actual position the hex is in)
1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163
when it should be
44 72 48 79 64 72 61 6C 69 73 6B
which his hex for DrHydralisk (me). Can anyone help me output the latter or just have it strait output ASCII (but hex is fine, I can just convert it)?
edit
Here is an image of what I am trying to do that I think will help.
http://imgur.com/nwenA.png
Here is the file I am trying to read, its a Starcraft replay (file.SC2Replay). Just search for DrHydralisk in a hex editor and that is where I am trying to read from.
http://www.mediafire.com/?6w8wi35q3o6ix8q
It should be (if clear text is in the file):
for( $i=0x481; $i<0x48D; $i++ ) {
printf("%X ", ord($file_contents[$i]));
}
Note the loop boundaries: 0x481 .. 0x48D
Result:
44 72 20 48 79 64 72 61 6C 69 73 6B
If the file contains hexadecimal numbers, this would be impossible because you need two bytes per hex char for the ascii character value range. So what is really in the file?
Edit
After reading your file, i did:
...
$file = 'file.SC2Replay';
$file_contents = file_get_contents($file);
for( $i=0x438; $i<0x443; $i++) {
printf("%X ", ord($file_contents[$i]));
}
for( $i=0x438; $i<0x443; $i++) {
printf("%s ", $file_contents[$i]);
}
...
And it says:
72 48 79 64 72 61 6C 69 73 6B
and
D r H y d r a l i s k
You messed up the file position ;-)
Regards
rbo
EDIT:
Thanks for providing the file, helped a lot! Beleive I got it working too:
//Do binary safe file read
$filename = 'file.SC2Replay';
$file = fopen($filename, "rb");
$contents = fread($file, filesize($filename));
fclose($file);
//position 1080 - 1091
for ($i = 0x438; $i < 0x443; $i++)
echo $contents[$i];
The reasons you were probably having problems is that first of all, a binary safe file read in php automatically replaces the bytes with the correct ASCII characters, so that threw off what position you actually needed to start reading from. Intead of 1153, it starts at 1080.
Could you explain how you are using the file you read in? Because the hex equivalent of:
11531154115511561157115811591160116111621163
is:
481 482 483 484 485 486 487 488 489 48a 48b
Also, there are two php functions you may find helpful
chr(int): returns the ascii character associated with the integer provided - http://php.net/manual/en/function.chr.php
dechex(int): returns the hex value of the integer provided - http://php.net/manual/en/function.dechex.php