I have this ruby function:
def WhitespaceHexEncode(str)
result = ""
whitespace = ""
str.each_byte do |b|
result << whitespace << "%02x" % b
whitespace = " " * (rand(3) + 1)
end
result
end
I am trying to make the same on php, this is the code I have so far:
function WhitespaceHexEncode($str)
{
$result = "";
$whitespace = "";
for($i=0;$i<strlen($str);$i++)
{
$result = $result.$whitespace.sprintf("%02x", $str[$i]);
$whitespace = " ";
for($x=0;$x<rand(0,5);$x++)
$whitespace = $whitespace." ";
}
return $result;
}
But the PHP function doesn't show the same output as the ruby one, for example:
print WhitespaceHexEncode("test fsdf dgksdkljfsd sdfjksdfsl")
Output: 74 65 73 74 20 66 73 64 66 20 64 67 6b 73 64 6b 6c 6a 66 73 64 20 73 64 66 6a 6b 73 64 66 73 6c
--------------------------------------------------------------
echo WhitespaceHexEncode("test fsdf dgksdkljfsd sdfjksdfsl")
Output: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Can someone tell me what's wrong in the php code?
UPDATE: Fixed it using bin2hex()
The following should work as well:
<?php
function WhitespaceHexEncode($str) {
$result = '';
foreach (str_split($str) as $b) {
$bytes = $whitespace = sprintf('%02x', ord($b));
$whitespace = str_repeat(' ', (rand(0, 5) + 1));
$result .= $bytes . $whitespace;
}
return $result;
}
echo WhitespaceHexEncode('test fsdf dgksdkljfsd sdfjksdfsl');
Related
I have a DBF file created as part of a shapefile with rgdal library's writeOGR function (in R).
When I ask to see its first bytes with Linux od command, I get the following.
od -x -c -N 32 BRA.dbf
0000000 7703 1e07 001b 0000 00a1 00d1 0000 0000
0000020 0000 0000 0000 0000 0000 0000 5700 0000
0000040
My PHP code goes like this.
$dbf = fopen('BRA.dbf','rb');
fread($dbf,10); // jumps over the first 10 bytes
$dbfRecSize = unpack('v',fread($dbf,2))[1]; // 'v' = little endian 16 bits: 00d1 = d1(16) = 209
fread($dbf,17); // jumps over a few more bytes
$dbfLangID = ord(fread($dbf,1)); // language driver ID
if ($dbfLangID == 0x57) {
echo "Language: 0x57 (ISO-8859-1)\n";
} else {
echo "Language: $dbfLangID;\n";
}
The code above outputs "Language: 0x57 (ISO-8859-1)", which means the "57" close to the end of the od output is being read with the ord(fread($dbf,1)); command.
Strange thing is that I've read 10+2+17 = 29 bytes from the file, so the next byte should be "00", or not (right after the 0x57)? $dbfRecSize is 209, which means my logic is correct in the first two reads. Why isn't it in the following reads?
What am I misunderstanding here?
The error is that I was confusing od command with debug from DOS...
od -x prints bytes with the order reversed every two bytes (too confusing to me).
0000000 7703 1e07 001b 0000 00a1 00d1 0000 0000
0000020 0000 0000 0000 0000 0000 0000 5700 0000
od -t x1 prints each byte once and separated (harder to count/read in the middle of the line).
0000000 03 77 07 1e 1b 00 00 00 a1 00 d1 00 00 00 00 00
0000020 00 00 00 00 00 00 00 00 00 00 00 00 00 57 00 00
Wonder if is there an option to print bytes two by two (in hexadecimal), without reversing their orders?
I'm trying to learn binary and create a simple WebM parser in PHP based on Matroska.
I read TimecodeScale, MuxingAppm WritingApp, etc. with unpack(format, data). My problem is when I reach Duration (0x4489) in Segment Information (0x1549a966) I must read a float and based on TimecodeScale convert it to seconds: 261.564s->00:04:21.564 and I don't know how.
This is a sample sequence:
`2A D7 B1 83 0F 42 40 4D 80 86 67 6F 6F 67 6C 65 57 41 86 67 6F 6F 67 6C 65 44 89 88 41 0F ED E0 00 00 00 00 16 54 AE 6B`
TimecodeScale := 2ad7b1 uint [ def:1000000; ]
MuxingApp := 4d80 string; ("google")
WritingApp := 5741 string; ("google")
Duration := 4489 float [ range:>0.0; ]
Tracks := 1654ae6b container [ card:*; ]{...}
I must read a float after (0x4489) and return 261.564s.
The duration is a double precision floating point value (64-bits) represented in the IEEE 754 format. If you want to see how the conversion is done check this.
The TimecodeScale is the timestamp scale in nanoseconds.
In php you can do:
$bin = hex2bin('410fede000000000');
$timecode_scale = 1e6;
// endianness
if (unpack('S', "\xff\x00")[1] === 0xff) {
$bytes = unpack('C8', $bin);
$bytes = array_reverse($bytes);
$bin = implode('', array_map('chr', $bytes));
}
$duration = unpack('d', $bin)[1];
$duration_s = $duration * $timecode_scale / 1e9;
echo "duration=${duration_s}s\n";
Result:
duration=261.564s
I am trying to convert little endian hex to big endian hex.
Example:
Little endian:
E1 31 01 00 00 9D
Big endian:
9D 00 00 01 31 E1
If numbers are in the format described than you can convert by using standard array functions.
function littleToBigEndian($little) {
return implode(' ',array_reverse(explode(' ', $little)));
}
echo littleToBigEndian('E1 31 3C 01 00 00 9B');
// Output: 9B 00 00 01 3C 31 E1
If there are no spaces for separation of numbers you need to str_split() the string instead.
function littleToBigEndian($little) {
return implode('',array_reverse(str_split($little,2)));
}
echo littleToBigEndian('E1313C0100009B');
// Output: 9B0000013C31E1
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
Hey guys I have the following:
session_start();
$seterror = 0;
function returnBack(){
header("Location:../memberinterface.php?getmsg=15");
exit;
}
function returnBackfile(){
header("Location:../memberinterface.php?getmsg=16");
exit;
}
if (!empty($_FILES['csvfile']['error'] ) )
{
$seterror = 1;
returnBack();
}
if (empty($_POST['firstname'])){
$seterror =1;
returnBack();
}
if (empty($_POST['lastname'])){
$seterrro =1;
returnBack();
}
if (empty($_POST['email'])){
$seterror =1;
returnBack();
}
if ($seterror !== 1){
$file = $_FILES['csvfile']['tmp_name'];
$handle = fopen($file , "r");
$fileop = fgetcsv($handle,0,"\t");
echo '<pre>'; var_dump($fileop); var_dump($_POST); echo '</pre>';
exit;
$fileop=array_map("strtoupper",array_map("trim",$fileop));
$firstname_index = array_search(strtoupper($_POST["firstname"]),$fileop);
if ($firstname_index===false){
returnBack();
}
$lastname_index = array_search(strtoupper($_POST["lastname"]),$fileop);
if ($lastname_index===false){
returnBack();
}
$email_index = array_search(strtoupper($_POST["email"]),$fileop);
if ($email_index===false){
returnBack();
}
//open file and store values
$j = 0;
while (($fileop=fgetcsv($handle,0,"\t")) !== false)
{
$fileop=array_map("trim",$fileop);
$firstname[$j] = $fileop[$firstname_index];
if (empty($firstname[$j])){
returnBackfile();
}
$lastname[$j] = $fileop[$lastname_index];
if (empty($lastname[$j])){
returnBackfile();
}
$email[$j] = $fileop[$email_index];
if (empty($email[$j])){
returnBackfile();
}
$j++;
}
//create sessions, send back to memberinterface.php and open table to display the results to delete
$_SESSION['CSVRfirstnames'] = $firstname;
$_SESSION['CSVRlastnames'] = $lastname;
$_SESSION['CSVRemails'] = $email;
header("Location:../memberinterface.php?RemoveCSV=1");
}
And the section where I echo out the columns: echo '<pre>'; var_dump($fileop); var_dump($_POST); echo '</pre>'; - a weird thing happens.
For some CSV files I get this outprinted:
array(4) {
[0]=>
string(726) "PK!|l˜l [Content_Types].xml ¢( Ì”]KÃ0†ïÿCÉ4Ù&ˆÈº]øq©çˆÍé–&!'›Û¿÷4û#¤nzÓÐæœ÷}’4ïp¼jL¶„€ÚÙ‚õye`K§´ìmú”ß²£´Jg¡`k#6]^§k˜Q·Å‚Õ1ú;!°¬¡‘ÈK3•ŒôfÂËr.g ½Þ(`c[
6>#%&f+ú¼!"
[1]=>
string(71) "`e÷›ÂÖ«`Ò{£K‰T,úæ’o8u¦¬µÇ+Â`¢Ó¡ùÙ`Û÷B[´‚l"C|–
aˆ•.Ìß›óÃ"”®ªt"
[2]=>
string(951) "v€£ Ö±1<¼‘Úî¸ø§bi蟤]_>‘cðO8®ÿˆ#Òÿ"=$IæÈ`\À3¯v#z̹–Ôk”gøª}ˆƒîÑ$8”(Nß…]d´Ý¹'!QÃ>4º.ßÞ‘ÒètÃo·Ú¼S :¼EÊ×Ñ'ÿÿPK!µU0#õL_rels/.rels ¢( Œ’ÏNÃ0ÆïH¼CäûênH¡¥»LH»!TÀ$îµ£$#÷ö„‚JcÛÑöçÏ?[ÞîæiTb/Nú(A±3b{×jxŸV b"giÇŽaWÝÞl_x¤”›b×û¨²‹‹º”ü#b4Oñìr¥‘0QÊahÑ“¨eÜ”å=†¿P-<ÕÁj{ª>ú<ù²·4Mox/æ}b—NŒ#ž;ËvåCf©ÏÛ¨šBËIƒóœÓÉû"cž&Ú\Oôÿ¶8q"K‰ÐHàó<ߊs#ëë.Ÿh©ø½Î<⧄áMdøaÁÅT_ÿÿPK!Þ"
[3]=>
string(530) "(Ôxl/_rels/workbook.xml.rels ¢( ¼“ÏjÃ0ÆƒÑ}q’ne”:½ŒA¯[÷&QâÐÄ6–ö'o?“Cº#É.¡ƒ$ü}?Чýá§ïÄjU%)´¥«ZÛ(ø8½><ƒ Ö¶Ò³¨`#‚Cq·ÃNsüD¦õ$¢Š%†Ù襤Ò`¯)qmœÔ.ôšcéuyÖ
Ê
string(9) "Firstname"
["lastname"]=>
string(8) "lastname"
["email"]=>
string(5) "Email"
}
And other csv files I get it nicely organized:
array(3) {
[0]=>
string(9) "firstname"
[1]=>
string(8) "lastname"
[2]=>
string(5) "email"
[3]=>
}
array(3) {
["firstname"]=>
string(9) "Firstname"
["lastname"]=>
string(8) "lastname"
["email"]=>
string(5) "email"
}
Now I don't know why I am getting the weird symbols for some, and I don't want those so if you could help me that would be great!
David
Make sure your .CSV file is saved as "comma delimited" or "tab delimited" in Excel. Cheers!
Some of yours "CSV" files are not CSV files. This ackward structure you are printing is potentially the content of a .xlsx file or some of the many other Microsoft Office 2007 formats.
If I create a blank .docx or .xlsx file and see in the hexadecimal editor I will see something like this:
00000000h: 50 4B 03 04 14 00 06 00 08 00 00 00 21 00 DD FC ; PK..........!.Ýü
00000010h: 95 37 66 01 00 00 20 05 00 00 13 00 08 02 5B 43 ; •7f... .......[C
00000020h: 6F 6E 74 65 6E 74 5F 54 79 70 65 73 5D 2E 78 6D ; ontent_Types].xm
00000030h: 6C 20 A2 04 02 28 A0 00 02 00 00 00 00 00 00 00 ; l ¢..( .........
00000040h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000050h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000060h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
Quite familiar, isn't it?
Those files are actually .zip files contenting a tree of .xml files and other resources belonging to your document.
can you try utf8_encode() on the string?
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]));
}