python: Add initial prototype
This commit is contained in:
40
python/passgeny/bhash.py
Normal file
40
python/passgeny/bhash.py
Normal file
@ -0,0 +1,40 @@
|
||||
import math
|
||||
|
||||
class BhashException(Exception): pass
|
||||
|
||||
class Bhash:
|
||||
"""
|
||||
Hash manipulation class.
|
||||
|
||||
The hash is internally treated as a big-endinan integer. This allows for
|
||||
easy implementation of operations such as modulo.
|
||||
|
||||
Note: The consumed bits are calculated using math.log() so the exact number
|
||||
may be inprecise.
|
||||
"""
|
||||
def __init__(self):
|
||||
self.bhash = None
|
||||
self.bits_avail = 0
|
||||
self.bits_used = 0.0
|
||||
|
||||
def from_bytes(self, buf: bytes):
|
||||
"""
|
||||
Initialize a Bhash from a bytes object
|
||||
"""
|
||||
self.bhash = int.from_bytes(buf, byteorder='big')
|
||||
self.bits_avail = len(buf) * 8
|
||||
self.bits_used = 0.0
|
||||
|
||||
def modulo(self, mod: int) -> int:
|
||||
"""
|
||||
Treat the hash as a bigint and divide it by mod. The hash is updated
|
||||
with the division result while the module value is returned.
|
||||
"""
|
||||
self.bits_used += math.log(mod) / math.log(2)
|
||||
if self.bits_used > self.bits_avail:
|
||||
raise BhashException("Consumed all bits in hash")
|
||||
|
||||
r = self.bhash % mod
|
||||
self.bhash //= mod
|
||||
|
||||
return r
|
||||
Reference in New Issue
Block a user