pack a three byte int

p.lavarre at ieee.org p.lavarre at ieee.org
Fri Nov 10 00:41:23 CET 2006


> > > cdb0 = '\x08' '\x01\x23\x45' '\x80' '\0'
> >
> > cdb = ''
> > cdb += struct.pack('>B', 0x08)
> > cdb += struct.pack('>I', skip)[-3:]
> > cdb += struct.pack('>BB', count, 0)
>
> The change from [-3:] to [1:] is a minor cosmetic improvement,

Ouch, [1:] works while sizeof I is 4, yes, but that's not what I meant,
more generally.

Something else I tried that doesn't work is:

skip = 0x12345 ; count = 0x80
struct.pack('>8b3b21b8b8b', 0x08, 0, skip, count, 0)

That doesn't work, because in Python struct b means signed char, not
bit; and a struct repeat count adds fields, rather than making a field
wider.

But do you see what I mean?  The fields of this struct have 8, 3, 21,
8, and 8 bits.  The "skip" field has 21 bits, the "count" field has 8
bits, I'd like to vary both of those.

> why do you want to do that to concise working code???

cdb0 = '\x08' '\x01\x23\x45' '\x80' '\0'
works, but it's not parameterised.  Writing out the hex literal always
packs the same x12345 and x80 values into those 21 and 8 bit fields.

I see I can concisely print and eval the big-endian hex:

X08Read6 = 0x08
skip = 0x12345 ; count = 0x80
hex = '%02X' % X08Read6 + ('%06X' % skip) + ('%02X' % count) + '00'
''.join([chr(int(hex[ix:ix+2],0x10)) for ix in range(0,len(hex),2)])

But that's ugly too.  Maybe least ugly so far, if I bury the
join-chr-int-for-range-len-2 in a def.

Is there no less ugly way to say pack bits, rather than pack bytes, in
Python?




More information about the Python-list mailing list