Reading through your Delph questions, along with your comments, I really don't fully understand what all this is supposed to do. However, given the input data along with the output, I can at least get pretty close, and exact with some additional corrections.
Basically, you can use mb_convert_encoding
to get UTF-16LE, and then you can get the bytes as hex strings using unpack
. To convert the decimal numbers to hex strings, just use dechex
.
From your sample, I'm not certain why the decimal number 64
when converted to the hex string 40
is written as FF 40
and not just 40
or 40 00
, but the $finalStringWithNumbersPadded
variable has the FF
appended. If the age or score were greater than 255
I'm not really sure what to do since FF
is 1111 1111
and completely full.
Also, I'm assuming you have a typo in your expected bytes, the character for the last name should by 76 00
and not just 76
.
Hopefully the code speaks for itself:
$score = 64;
$firstName = 'Jack';
$lastName = 'Saliv';
$age = 21;
$expected = 'FFFEFF404A00610063006B00530061006C00690076FFFEFF15';
$expectedCorrected = 'FFFEFF404A00610063006B00530061006C0069007600FFFEFF15';
// Convert to UTF-16LE and get hex, https://stackoverflow.com/a/16080439/231316
$nameAsUtf16LE = unpack('H*', mb_convert_encoding($firstName.$lastName, 'UTF-16LE', 'UTF-8'));
// UTF-16LE BOM
$utf16LeBom = 'FFFE';
// Convert to hex strings
$scoreAsHex = dechex($score);
$ageAsHex = dechex($age);
$finalString = sprintf(
'%1$s%2$s%3$s',
$utf16LeBom.$scoreAsHex,
strtoupper($nameAsUtf16LE[1]), // This is 1-based, not 0-based
$utf16LeBom.$ageAsHex,
);
$numberPadding = 'FF';
$finalStringWithNumbersPadded = sprintf(
'%1$s%2$s%3$s',
$utf16LeBom.$numberPadding.$scoreAsHex,
strtoupper($nameAsUtf16LE[1]), // This is 1-based, not 0-based
$utf16LeBom.$numberPadding.$ageAsHex,
);
echo 'Calculated : '.$finalString;
echo PHP_EOL;
echo 'Padded : '.$finalStringWithNumbersPadded;
echo PHP_EOL;
echo 'Expected : '.$expected;
echo PHP_EOL;
echo 'Expected Corrected : '.$expectedCorrected;
assert($finalStringWithNumbersPadded === $expectedCorrected);
/* Output:
Calculated : FFFE404A00610063006B00530061006C0069007600FFFE15
Padded : FFFEFF404A00610063006B00530061006C0069007600FFFEFF15
Expected : FFFEFF404A00610063006B00530061006C00690076FFFEFF15
Expected Corrected : FFFEFF404A00610063006B00530061006C0069007600FFFEFF15
*/
Demo: https://3v4l.org/XTdjA#v8.2.6
Edit
To write a string of hex characters to disk as binary data you can use pack
:
$bindata = pack('H*', 'FFFEFF404A00610063006B00530061006C0069007600FFFEFF15');
file_put_contents('testing.data', $bindata);