Created
April 28, 2020 21:52
-
-
Save cosinekitty/5730ba897400e8b7d9cf3952433c6b69 to your computer and use it in GitHub Desktop.
BitBuffer class for converting variable-length bit strings to Base64 on the fly
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class BitBuffer: | |
| def __init__(self): | |
| self.buf = bytearray() | |
| self.accum = 0 | |
| self.nbits = 0 | |
| self.column = 0 | |
| def Append(self, pattern): | |
| data, dbits = pattern | |
| while self.nbits + dbits >= 6: | |
| # We can emit a complete base64 character to represent a chunk of 6 bits. | |
| grab = 6 - self.nbits | |
| mask = (1 << grab) - 1 | |
| self.accum = (self.accum << grab) | (mask & (data >> (dbits - grab))) | |
| dbits -= grab | |
| self.buf.append(b'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'[self.accum]) | |
| self.accum = 0 | |
| self.nbits = 0 | |
| self.column += 1 | |
| if self.column == 80: | |
| self.buf.append(ord('\n')) | |
| self.column = 0 | |
| # Transfer any residual data bits into the accumulator. | |
| if dbits >= 0: | |
| mask = (1 << dbits) - 1 | |
| self.accum = (self.accum << dbits) | (mask & data) | |
| self.nbits += dbits | |
| def Format(self): | |
| # Flush any remaining bits left in the accumulator. | |
| if self.nbits > 0: | |
| self.Append((0, (6 - self.nbits))) | |
| # Always end on a newline. | |
| if self.column > 0: | |
| self.buf.append(ord('\n')) | |
| self.column = 0 | |
| # Convert the bytes to utf-8 text. | |
| return self.buf.decode('utf-8') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment