Most pythonic way to implement byte stuffing algorithm
On 2018-04-17, Travis Griggs <travisgriggs at gmail.com> wrote:
> I posted this on SO, but? yeah?
> I'm doing some serial protocol stuff and want to implement a basic
> byte stuffing algorithm in python. Though really what this really
> generalizes to is ?what is the most pythonic way to transform one
> sequence of bytes where some bytes are passed through 1:1, but
> others are transformed to longer subsequences of bytes?? I?m pretty
> sure this rules out the use of transform() which expects a 1:1
> So far, I've come with 5 different approaches, and each of them has something I don't like about it:
> 1 Via Generator
> def stuff1(bits):
> for byte in bits:
> if byte in _EscapeCodes:
> yield PacketCode.Escape
> yield byte ^ 0xFF
> yield byte
> This may be my favorite, but maybe just because I'm kind of
> fascinated by yield based generators. I worried that the generator
> would make it slow, but it's actually the second fastest of the
I find that the most readible, and would certainly get my vote -- even
if it was the slowest (unless it was so slow as to be a problem).
> def stuff5(bits):
> escapeStuffed = bytes(bits).replace(bytes([PacketCode.Escape]), bytes([PacketCode.Escape, PacketCode.Escape ^ 0xFF]))
> stopStuffed= escapeStuffed.replace(bytes([PacketCode.Stop]), bytes([PacketCode.Escape, PacketCode.Stop ^ 0xFF]))
> return stopStuffed.replace(bytes([PacketCode.Start]), bytes([PacketCode.Escape, PacketCode.Start ^ 0xFF]))
> This is the fastest. But I don't like the way the code reads and the intermediate sweeps.
Yow, that's ugly -- I don't think I'd be able to tell you what it
actually does without actually running it.
If speed is that important, I might just write a function in C and
call it with ctypes. :)
Grant Edwards grant.b.edwards Yow! HAIR TONICS, please!!