Chip Wachob wrote: > Hello, > > I was not able to find any answers in the archive on this one. > > I'm wondering if this task can be done in a better way than what I've > attempted.. > > I have an array of bytes. Up to 64, which makes for 512 bits. > > I am reading these bytes in serially, and once I have a collection of > them, I want to shift them by 'n' bits. The size of the array and the > number of bits are both variable up to the limit of 64/512. > > Now, I've played around with looping through the bytes and taking the > LSByte and shifting it by 'n' bits using >> or << and that works for > the first byte. But then I need to take the next byte in the sequence > and shift it in the opposite direction by 8-n bits using << or >> > (opposite the LSByte direction), respectively. Then I OR the two > bytes and save them into the location of the LSByte and then move to > the next byte in the sequence and so on. While this works most of the > time, I sometimes get strange behavior at the 'fringes' of the bytes. > Sometimes I end up with zero, or the shift seems to 'roll over'. > > I'm thinking that maybe there's a way to treat the array / list and > shift allowing the bits to transfer from byte to byte as needed. > Maybe by concatenating the bytes into one huge word and then breaking > it apart again? > > I'm thinking that you folks out there know of a built-in function, or, > an easier and more predictable way to accomplish the same.
Here are two ways to implement the left shift: def bitshift(b, n, byteorder="big"): size = len(b) + (n + 7) // 8 shifted = int.from_bytes(b, byteorder) << n return shifted.to_bytes(size, byteorder) def bitshift2(b, n): nbytes, nbits = divmod(n, 8) if nbits: a = [0] for bb in b: hi, lo = divmod(bb << nbits, 256) a[-1] |= hi a.append(lo) b = bytes(a) return b + b"\x00" * nbytes assert bitshift(b"\xaa\xbb", 12) == b"\x0a\xab\xb0\x00" assert bitshift2(b"\xaa\xbb", 12) == b"\x0a\xab\xb0\x00" _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor