Big-endian binary data to/from Python ints?

W

William McBrine

Here are a couple of functions that I feel stupid for having written.
They work, and they're pretty straightforward; it's just that I feel like
I must be missing an easier way to do this...

def net_to_int(numstring):
"""Convert a big-endian binary number, in the form of a string of
arbitrary length, to a native int.
"""
num = 0
for i in numstring:
num *= 256
num += ord(i)
return num

def int_to_net(num):
"""Convert a native int to a four-byte big-endian number, in the form
of a string.
"""
numstring = ''
for i in xrange(4):
numstring = chr(num % 256) + numstring
num /= 256
return numstring

The situation: I'm getting a four-byte packet from a socket that consists
of a big-endian 32-bit integer. (It specifies the length of the data that
follows.) I have to send the same thing in reply. send() and recv() work
with strings... I'm familiar with ntohl() and htonl(), but those expect/
return integers.
 
M

Matt Nordhoff

William said:
Here are a couple of functions that I feel stupid for having written.
They work, and they're pretty straightforward; it's just that I feel like
I must be missing an easier way to do this...

def net_to_int(numstring):
"""Convert a big-endian binary number, in the form of a string of
arbitrary length, to a native int.
"""
num = 0
for i in numstring:
num *= 256
num += ord(i)
return num

def int_to_net(num):
"""Convert a native int to a four-byte big-endian number, in the form
of a string.
"""
numstring = ''
for i in xrange(4):
numstring = chr(num % 256) + numstring
num /= 256
return numstring

The situation: I'm getting a four-byte packet from a socket that consists
of a big-endian 32-bit integer. (It specifies the length of the data that
follows.) I have to send the same thing in reply. send() and recv() work
with strings... I'm familiar with ntohl() and htonl(), but those expect/
return integers.

The struct module should do it, but do you prefer your code or format
strings? :p

<http://docs.python.org/lib/module-struct.html>
--
 
D

Dennis Lee Bieber

Here are a couple of functions that I feel stupid for having written.
They work, and they're pretty straightforward; it's just that I feel like
I must be missing an easier way to do this...


The situation: I'm getting a four-byte packet from a socket that consists
of a big-endian 32-bit integer. (It specifies the length of the data that
follows.) I have to send the same thing in reply. send() and recv() work
with strings... I'm familiar with ntohl() and htonl(), but those expect/
return integers.

Still sounds like Section 7.2 (for Python 2.4.x) of the library
reference manual applies.

socket.ntohl()
socket.ntohs()
socket.htonl()
socket.htons()

Especially if the input is a net-order 32-bit value... Especially as
they would be aware of the native ordering for the host -- your code
might (I've not actually checked it) be incorrect if ported to another
machine. If the problem is that you have the four bytes as a character
string, use the struct module to interpret it as a binary integer and
then feed the results to the above functions, followed by using struct
to convert back to a string representation.

Heck, looking at struct, it already has a format modifier for
net-oriented... (assuming unsigned 32-bit integer)

pinteger = struct.unpack("!I", netstring[0:4])[0]
and
netstring = struct.pack("!I", pinteger)



--
Wulfraed Dennis Lee Bieber KD6MOG
(e-mail address removed) (e-mail address removed)
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: (e-mail address removed))
HTTP://www.bestiaria.com/
 
W

William McBrine

your code might (I've not actually checked it) be incorrect if ported
to another machine.

Nope. :)
If the problem is that you have the four bytes as a character string,
use the struct module to interpret it as a binary integer and then feed
the results to the above functions, followed by using struct to convert
back to a string representation.

Heck, looking at struct, it already has a format modifier for
net-oriented... (assuming unsigned 32-bit integer)

pinteger = struct.unpack("!I", netstring[0:4])[0]
and
netstring = struct.pack("!I", pinteger)

Thanks, that seems to be what I was looking for.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top