python3实现bitmap
我已经封装,可以直接使用。
import unittest
from utilset import Bitmap
class TestBitmap(unittest.TestCase):
def test_bitmap(self):
bm = Bitmap.Bitmap(10)
bm.set(2)
bm.set(7)
self.assertTrue(bm.test(2))
self.assertFalse(bm.test(3))
if __name__ == "__main__":
unittest.main()
源码:
import array
class BitMap(object):
BITMASK = [0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80]
BIT_CNT = [bin(i).count("1") for i in range(256)]
def __init__(self, maxnum=0):
nbytes = (maxnum + 7) // 8
self.bitmap = array.array("B", [0 for i in range(nbytes)])
def __del__(self):
pass
def set(self, pos):
"""
Set the value of bit@pos to 1
"""
self.bitmap[pos // 8] |= self.BITMASK[pos % 8]
def reset(self, pos):
"""
Reset the value of bit@pos to 0
"""
self.bitmap[pos // 8] &= ~self.BITMASK[pos % 8]
def flip(self, pos):
"""
Flip the value of bit@pos
"""
self.bitmap[pos // 8] ^= self.BITMASK[pos % 8]
def count(self):
"""
Count bits set
"""
return sum([self.BIT_CNT[x] for x in self.bitmap])
def size(self):
"""
Return size
"""
return len(self.bitmap) * 8
def test(self, pos):
"""
Return bit value
"""
return (self.bitmap[pos // 8] & self.BITMASK[pos % 8]) != 0
def any(self):
"""
Test if any bit is set
"""
return self.count() > 0
def none(self):
"""
Test if no bit is set
"""
return self.count() == 0
def all(self):
"""
Test if all bits are set
"""
return (self.count() + 7) // 8 * 8 == self.size()
def nonzero(self):
"""
Get all non-zero bits
"""
return [i for i in range(self.size()) if self.test(i)]
def tostring(self):
"""
Convert BitMap to string
"""
return "".join([("%s" % bin(x)[2:]).zfill(8) for x in self.bitmap[::-1]
])
def __str__(self):
"""
Overloads string operator
"""
return self.tostring()
def __getitem__(self, item):
"""
Return a bit when indexing like a array
"""
return self.test(item)
def __setitem__(self, key, value):
"""
Sets a bit when indexing like a array
"""
if value is True:
self.set(key)
elif value is False:
self.reset(key)
else:
raise Exception("Use a boolean value to assign to a bitfield")
def tohexstring(self):
"""
Returns a hexadecimal string
"""
val = self.tostring()
st = "{0:0x}".format(int(val, 2))
return st.zfill(len(self.bitmap) * 2)
@classmethod
def fromhexstring(cls, hexstring):
"""
Construct BitMap from hex string
"""
bitstring = format(
int(hexstring, 16), "0" + str(len(hexstring) / 4) + "b")
return cls.fromstring(bitstring)
@classmethod
def fromstring(cls, bitstring):
"""
Construct BitMap from string
"""
nbits = len(bitstring)
bm = cls(nbits)
for i in range(nbits):
if bitstring[-i - 1] == "1":
bm.set(i)
elif bitstring[-i - 1] != "0":
raise Exception("Invalid bit string!")
return bm
参考:
python3实现bitmap
https://blog.puresai.com/2023/08/11/492/