Wallace
Wallace

Reputation: 651

How to Pack Different Types of Data Together into Binary Data with Python

Suppose there is a user-defined protocol as below:

The protocol:

 ------------- ------------- ---------------- -----------------
|   Seqno.    |      ip     |       port     |    user name    |
| int, 4 bytes| int, 4 bytes| short, 2 bytes | string, 50 bytes|


the [user name] field stores a string ending with zero,    
if the string length is less than 50 bytes, padding with zeros.

Usually I will pack these fields in C language like this:

//Pseudo code
buffer = new char[60];
memset(buffer, 0, 60);

memcpy(buffer, &htonl(Seqno), 4);
memcpy(buffer+4, &htonl(ip), 4);
memcpy(buffer+4, &htons(port), 2);
memcpy(buffer+2, Usrname.c_str(), Usrname.length() + 1);

But how can we pack the protocol data in python? I am new to python.

Upvotes: 1

Views: 494

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1122332

Use the struct module:

import struct

binary_value = struct.pack('!2IH50s', seqno, ip, port, usrname)

This packs 2 4-byte unsigned integers, a 2-byte unsigned short and a 50-byte string into 60 bytes with network (big-endian) byte ordering. The string will be padded out with nulls to make up the length:

>>> import struct
>>> seqno = 42
>>> ip = 0xc6fcce10
>>> port = 80
>>> usrname = 'Martijn Pieters'
>>> struct.pack('!2IH50s', seqno, ip, port, usrname)
'\x00\x00\x00*\xc6\xfc\xce\x10\x00PMartijn Pieters\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

Python's string representation uses ASCII characters for any bytes in the ASCII printable range, \xhh for most other byte points, so the 42 became \x00\x00\x00*.

Upvotes: 1

Related Questions