2

I want to encode a set of configuration options into a long string of hex digits.

The input is a mix of numbers (integers and floats) and strings. I can use binascii.a2b_hex from the standard library for the strings, bit-wise operators for the integers, and probably, if I go and read some on floating point representation (sigh), I can probably handle the floats, too.

Now, my questions:

  • When given the list of options, (how) should I type check the value to select the correct conversion routine?
  • Isn't there a library function for the numbers, too? I can't seem to find it.

The serialized data is sent to an embedded device and I have limited control over the code that consumes it (meaning, changes are possible, but a hassle). The specification for the serialization seems to conform to C value representation (char arrays for strings, Little Endian integers, IEEE 754 for floats), but it doesn't explicitily state this. So, Python-specific stuff like pickle are off-limits.

3 Answers 3

4

You want struct.

>>> struct.pack('16sdl', 'Hello, world!', 3.141592654, 42)
'Hello, world!\x00\x00\x00PERT\xfb!\t@*\x00\x00\x00\x00\x00\x00\x00'
Sign up to request clarification or add additional context in comments.

1 Comment

Yes, I do. Thanks. :) (Accepted Adam's answer, but upvoted yours, too)
2

You easiest bet is to pickle the whole list to a string and then use binascii.a2b_hex() to convert this string to hex digits:

a = ["Hello", 42, 3.1415]
s = binascii.b2a_hex(pickle.dumps(a, 2))
print s
# 80025d710028550548656c6c6f71014b2a47400921cac083126f652e
print pickle.loads(binascii.a2b_hex(s))
# ['Hello', 42, 3.1415]

1 Comment

Sorry, can't use pickle, the consumer of the serialization is an embedded device programmed in C, so I have a specific contract for the encoding.
1

What about using the struct module to do your packing/unpacking?

import struct
s = struct.pack('S5if',"Hello",42,3.1415)
print s
print struct.unpack('5sif')

or if you really want just hex characters

import struct, binascii
s = binascii.b2a_hex(struct.pack('S5if',"Hello",42,3.1415))
print s
print struct.unpack('5sif',binascii.a2b_hex(s))

Of course this requires that you know the length of strings that are being sent across or you could figure it out by looking for a NULL character or something.

1 Comment

The strings are serialized with a fixed length (truncated or padded with null bytes), so that fits well with struct.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.