PHP and Python unpack return different results from the same source

I cannot vaguely imagine the same data from Python (which I would prefer to use) and PHP (which works fine, encoded by the website host).

PHP connects to the same location as the Python script.

And before someone jumps the gun, I know that the python script receives only part of the data. But I can’t even get dimly the same data from the server.

Python:

import socket, struct host,port = 'baystation12.net', 8000 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((host, port)) s.send('status\r\n') data = s.recv(1024) s.close() print 'Received:', repr(data) # >>> Received: '\x00\xc7\x00\x07\x02\xadj\x00\x00\x1c\xf6' cache,form,listy = "",">H",[] for i in data: if cache != "": listy.append(struct.unpack(form,cache+i)) else: cache = i print "Unpacked:",listy # >>> Unpacked: [(199,), (0,), (7,), (2,), (173,), (106,), (0,), (0,), (28,), (246,)] text = "" for i in listy: text += chr(i[0]) print "Text:",text # >>> Text: Γ‡ #Shows up incorrectly when I try to copy it. 

PHP:

 #!/usr/bin/php <?php function export($addr,$port,$str) { if($str{0} != "?") $str = ("?" . $str); $query = "\x00\x83" . pack("n",strlen($str)+6) . "\x00\x00\x00\x00\x00" . $str . "\x00"; $server = socket_create(AF_INET,SOCK_STREAM,SOL_TCP) or exit('Unable to create export socket; ' . socket_strerror(socket_last_error())); socket_connect($server,$addr,$port) or exit('Unable to establish socket connection; ' . socket_strerror(socket_last_error())); $bytessent = 0; while($bytessent < strlen($query)) { $result = socket_write($server,substr($query,$bytessent),strlen($query)-$bytessent); if($result === FALSE) return('Unable to transfer requested data; ' . socket_strerror(socket_last_error())); $bytessent += $result; } $resbuf = ''; while( socket_recv($server, $message,1,0 )){ $resbuf .= $message; if(strpos($resbuf,"&end")!=FALSE) { echo $resbuf; socket_close($server); return($resbuf); } echo $message; }; echo $resbuf."\n"; socket_close($server); } export("localhost","8000","status"); ?> 

PHP output:

 version=Baystation+12&mode=extended&respawn=0&enter=1&vote=1&ai=1&host&players=5&player0=CompactNinja&player1=Sick+trigger&player2=SweetJealousy&player3=Cacophony&player4=Anchorshag&end 

Any idea why Python produces meaningless characters when decompressing data, while PHP produces above.

+4
source share
2 answers

You are not sending the same request to your server in python.

In python, you submit status

In PHP, you send something like \x00\x83\x00\x0d\x00\x00\x00\x00\x00\x00?status\x00

If you change your python to more closely mimic PHP, then it works much better:

 import socket, struct host,port = 'baystation12.net', 8000 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((host, port)) senddata = "?status" query = '\x00\x83' + struct.pack(">H", len(senddata)+6) + '\x00'*5 + senddata + '\x00' s.send(query) data = s.recv(1024) print `data` 

When I tried this, he printed

 '\x00\x83\x00\xe9\x06version=Baystation+12&mode=traitor&respawn=0&enter=1&vote=1&ai=1&host&players=7&player0=Kosherman&player1=Ghazkull&player2=Doug+H.+Nuts&player3=Lord+Braindead&player4=KirbyElder&player5=Master+of+Apples&player6=Cacophony&end=%23end\x00' 

Which looks pretty similar to what PHP was getting.

+2
source

Try listy.append(struct.unpack(form,cache+i)[0])

You end up with a list of 1-element tuples, not a list of numbers.

From the docs: http://docs.python.org/library/struct.html#struct.unpack

  struct.unpack(fmt, string) 

Unpack the string (supposedly packaged pack (fmt, ...)) in accordance with this format. The result is a tuple even if it contains exactly one element. The string must contain exactly the amount of data required by the format (len (string) must equal calcsize (FMT)).

0
source

Source: https://habr.com/ru/post/1384120/


All Articles