Bits
me: 8バイトなんだけど56bit、なぜなら入力がUS-ASCII限定で最上位ビットが0だからそこは詰めてもかまわない、と。詰めないでくれたらだいぶ楽なのに!!
me: 1バイトの節約とかやめてくれ!w
me: きっと組み込み脳とLL脳とでそのうち血で血を洗う戦争が発生する。
me: Pythonでビットを簡単に扱えるようにするためのライブラリはないのか
me: 「このバイト列から7ビットずつ取り出す」
というわけで書いた
def to_bin(x, width=8): """ for debug >>> to_bin('A') '01000001' >>> to_bin('AB') '01000001,01000010' """ if isinstance(x, str): if len(x) == 1: return to_bin(ord(x)) return ",".join(map(to_bin, x)) if isinstance(x, int): return "".join( str(int(bool(x & (2 ** i)))) for i in reversed(range(width))) raise NotImplementedError def split_to_fixed_bits(bytes, width): """ >>> to_bin("ABC") '01000001,01000010,01000011' >>> [to_bin(x, 4) for x in split_to_fixed_bits("ABC", 4)] ['0100', '0001', '0100', '0010', '0100', '0011'] >>> [to_bin(x, 3) for x in split_to_fixed_bits("ABC", 3)] ['010', '000', '010', '100', '001', '001', '000', '011'] """ if width > 8: raise NotImplementedError mask = (2 ** width) - 1 total = len(bytes) * 8 if total % width: bytes += "\x00" start = 0 for start in range(0, total, width): sb = start / 8 end = start + width eb = (end - 1) / 8 if end % 8 == 0: yield ord(bytes[sb]) & mask elif sb == eb: ret = ord(bytes[sb]) _mask = mask << (8 - end % 8) ret &= _mask ret >>= 8 - end % 8 yield ret else: before_half = ord(bytes[sb]) _mask = (2 ** (8 - start % 8)) - 1 before_half &= _mask before_half <<= end % 8 after_half = ord(bytes[eb]) _mask = (2 ** (end % 8)) - 1 _mask <<= 8 - end % 8 after_half &= _mask after_half >>= 8 - end % 8 yield before_half + after_half
というわけで個人的にはもうパズルをとき終わった気満点でこのままぽいっとしてしまいそうだけど、CodeReposに入れた方がいいのかな。入れた方がいいと思う人ははてなスターをぽちっと(ぉ