Files
Passgeny/python/passgeny/bhash.py
Mitja HORVAT bcae51ead9 c,python: Use little-endina byte order for bigint arithmetics
This better matches what one would expect from the hex or base64
(upcoming) formats.
2021-11-15 01:13:17 +01:00

41 lines
1.1 KiB
Python

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='little')
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