I've been asked to design back-end in php for a web app having ASP front-end. So I can't really dig up those ASP files. I have the MySQL database - that's it! The programmer who made the front-end isn't responding.
How do I decode this? Or just this - "what's the name of this encryption method?"
It looks something like HEX though.
Another sample - 0E0800160E0330595D57
0 1 2 3 4 5 6 7 8 9
0E 0B 02 06 01
0E 08 00 16 0E 03 30 59 5D 57
UPDATE - When I change my password to "kachwa" (without quotes), it gets updated as 040E0C07180E in the database.
Each byte is xor'd with 0x6f.
PHP sample encryption:
function enc($pass)
{
$enc = '';
for ($i = 0; $i < strlen($pass); ++$i)
$enc .= sprintf("%02x", ord($pass[$i]) ^ 0x6f);
return $enc;
}
echo enc("kachwa"),"\n";
Output:
040e0c07180e
And for the sake of completeness:
function dec($pass)
{
$dec = '';
foreach (str_split($pass, 2) as $hex)
$dec .= chr(hexdec($hex) ^ 0x6f);
return $dec;
}
echo dec("040e0c07180e"),"\n";
Related
My problem is that I was some time ago base64 encoding random bytes from openssl sha256 in C (as uint8_t), feeding them into a shell script and using the output.
What I can recreate from my data now is:
Content of file.txt:
uvjWEHTUk1LnzVZul9ynRpezWfKYN3bvlx103wxACxo
test#test:~# base64 -d file.txt | od -t x1
0000000 ba f8 d6 10 74 d4 93 52 e7 cd 56 6e 97 dc a7 46
0000020 97 b3 59 f2 98 37 76 ef 97 1d 74 df 0c 40 0b 1a
The output is the same as calling in PHP:
echo bin2hex(base64_decode("uvjWEHTUk1LnzVZul9ynRpezWfKYN3bvlx103wxACxo="));
baf8d61074d49352e7cd566e97dca74697b359f2983776ef971d74df0c400b1a
What I did all the time in shell and need to do now in PHP is the following:
Again, same content of file.txt:
uvjWEHTUk1LnzVZul9ynRpezWfKYN3bvlx103wxACxo
test#test:~# base64 -d file.txt | od -t x8
0000000 5293d47410d6f8ba 46a7dc976e56cde7
0000020 ef763798f259b397 1a0b400cdf741d97
My problem here: what is now the equal procedure in PHP (to od -t x8 in shell)?
I tried pack / unpack / bin2hex / ... and can't get the same result.
I'm trying to get a string with this content:
"5293d47410d6f8ba46a7dc976e56cde7ef763798f259b3971a0b400cdf741d97"
from a starting point of base64_decode("uvjWEHTUk1LnzVZul9ynRpezWfKYN3bvlx103wxACxo="). Any ideas?
If x8 is what you really need, which is 8 bytes, then the implementation would be as simple as
<?php
$str = 'uvjWEHTUk1LnzVZul9ynRpezWfKYN3bvlx103wxACxo';
$bin = base64_decode($str);
if (strlen($bin) % 8 !== 0) {
throw new \RuntimeException('data length should be divisible by 8');
}
$result = '';
for ($i = 0; $i < strlen($bin); $i += 8) {
for ($j = $i + 7; $j >= $i; --$j) {
$result .= bin2hex($bin[$j]);
}
}
echo $result;
It iterates over blocks of 8 bytes, then dumps them in reverse order each.
Ideone: https://ideone.com/hBanqi
I read bytes from a file and process them. Afterwards I would like to save the packed bytes.
What is the recommended+generic way to convert an array with mixed objects/types to a byte string? In my case: array with int and string, pack types a,C,x.
A simplified example:
// $bytes = fread($handle, 100);
$bytes = "437XYZ25.011001DBEFORE ....";
$unpackString = "a3CPN/x8spare/CDSC/x4spare/a32OPT";
$unpacked = unpack($unpackString, $bytes);
var_dump($unpacked);
/*
array(3) {
["CPN"]=> string(3) "437"
["DSC"]=> int(49)
["OPT"]=> string(32) "BEFORE "
}
*/
// example of processing
$unpacked["DSC"] = 12;
$unpacked["OPT"] = "AFTER ";
// pack + write the result
// $packString = "a3x8Cx4a32";
$packTypes = ["a3","x8","C","x4","a32"];
$packFields = [ $unpacked["CPN"], null, $unpacked["DSC"], null, $unpacked["OPT"] ];
// ...
update: in the simplified example I have replaced $packString with $packTypes and $packFields to make sure it is clear what content belongs where and with what type.
I suppose what you're looking for is a way to call pack, which accepts arguments with an associative array as you have in your example. For this, we can use call_user_func_array which calls a function by its name and provides its arguments from a given array.
$bytes = "437XYZ25.011001DBEFORE ....";
$unpackString = "a3CPN/x8spare/CDSC/x4spare/a32OPT";
$unpacked = unpack($unpackString, $bytes);
// example of processing
$unpacked["DSC"] = 12;
$unpacked["OPT"] = "AFTER ";
// pack + write the result
$packTypes = ["a3", "x8", "C", "x4", "a32"];
$packFields = [$unpacked["CPN"], null, $unpacked["DSC"], null, $unpacked["OPT"]];
$packString = "";
$packArguments = [];
for ($i = 0; $i < count($packTypes); $i++){
$packString .= $packTypes[$i];
if ($packFields[$i] !== null){
// the null bytes don't use an argument
$packArguments[] = $packFields[$i];
}
}
// put packString as the first argument
array_unshift($packArguments, $packString);
$output = call_user_func_array("pack", $packArguments);
And $output would then be:
00000000 34 33 37 00 00 00 00 00 00 00 00 0c 00 00 00 00 |437.............|
00000010 41 46 54 45 52 20 20 20 20 20 20 20 20 20 20 20 |AFTER |
00000020 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 | |
00000030
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
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;
How can I encode strings on UTF-16BE format in PHP? For "Demo Message!!!" the encoded string should be '00440065006D006F0020004D00650073007300610067006'. Also, I need to encode Arabic characters to this format.
First of all, this is absolutly not UTF-8, which is just a charset (i.e. a way to store strings in memory / display them).
WHat you have here looks like a dump of the bytes that are used to build each characters.
If so, you could get those bytes this way :
$str = utf8_encode("Demo Message!!!");
for ($i=0 ; $i<strlen($str) ; $i++) {
$byte = $str[$i];
$char = ord($byte);
printf('%02x ', $char);
}
And you'd get the following output :
44 65 6d 6f 20 4d 65 73 73 61 67 65 21 21 21
But, once again, this is not UTF-8 : in UTF-8, like you can see in the example I've give, D is stored on only one byte : 0x44
In what you posted, it's stored using two Bytes : 0x00 0x44.
Maybe you're using some kind of UTF-16 ?
EDIT after a bit more testing and #aSeptik's comment : this is indeed UTF-16.
To get the kind of dump you're getting, you'll have to make sure your string is encoded in UTF-16, which could be done this way, using, for example, the mb_convert_encoding function :
$str = mb_convert_encoding("Demo Message!!!", 'UTF-16', 'UTF-8');
Then, it's just a matter of iterating over the bytes that make this string, and dumping their values, like I did before :
for ($i=0 ; $i<strlen($str) ; $i++) {
$byte = $str[$i];
$char = ord($byte);
printf('%02x ', $char);
}
And you'll get the following output :
00 44 00 65 00 6d 00 6f 00 20 00 4d 00 65 00 73 00 73 00 61 00 67 00 65 00 21 00 21 00 21
Which kind of looks like what youy posted :-)
(you just have to remove the space in the call to printf -- I let it there to get an easier to read output=)
E.g. by using the mbstring extension and its mb_convert_encoding() function.
$in = 'Demo Message!!!';
$out = mb_convert_encoding($in, 'UTF-16BE');
for($i=0; $i<strlen($out); $i++) {
printf("%02X ", ord($out[$i]));
}
prints
00 44 00 65 00 6D 00 6F 00 20 00 4D 00 65 00 73 00 73 00 61 00 67 00 65 00 21 00 21 00 21
Or by using iconv()
$in = 'Demo Message!!!';
$out = iconv('iso-8859-1', 'UTF-16BE', $in);
for($i=0; $i<strlen($out); $i++) {
printf("%02X ", ord($out[$i]));
}