Implemented Rabin-Karp rolling hash class abstraction. After testing muliple algorithms for efficient substring searching in a stream abstracted by a ring buffer, I've dropped the idea of using KMP in favor of implementing my own algorithm based of the Rabin-Karp rolling hash algorithm.
61 lines
1.6 KiB
Python
61 lines
1.6 KiB
Python
import unittest
|
|
|
|
from byteb4rb1e_utils.string import RollingHash
|
|
|
|
class test_compute_initial_hash(unittest.TestCase):
|
|
"""RollingHash.compute_initial_hash()
|
|
|
|
i calculated the hashes by hand, as a basis for this test case. Hopefully
|
|
there's no logical flaw...
|
|
"""
|
|
|
|
def test_default(self):
|
|
"""computation of hash"""
|
|
result = RollingHash.compute_initial_hash(
|
|
b'abcdefg',
|
|
base = 31,
|
|
mod = 10**9 + 7
|
|
)
|
|
|
|
self.assertEqual(result, 988021244)
|
|
|
|
class test___init__(unittest.TestCase):
|
|
"""RollingHash.__init__()
|
|
|
|
Make sure the class instance is initialized correctly
|
|
|
|
I calculated the hashes by hand, as a basis for this test case. Hopefully
|
|
there's no logical flaw...
|
|
"""
|
|
|
|
def test_default(self):
|
|
"""computation of initial hash and highest base factor"""
|
|
instance = RollingHash(b'abcdefg')
|
|
|
|
self.assertEqual(instance._hash, 988021244)
|
|
self.assertEqual(instance._hbase_factor, 887503681)
|
|
|
|
def test_defaults_override(self):
|
|
"""override of defaults"""
|
|
instance = RollingHash(
|
|
b'abcdefg',
|
|
base = 9,
|
|
mod = 4
|
|
)
|
|
|
|
self.assertEqual(instance._mod, 4)
|
|
self.assertEqual(instance._base, 9)
|
|
|
|
|
|
class test_roll(unittest.TestCase):
|
|
"""RollingHash.roll()"""
|
|
def test_rolling_hash(self):
|
|
base=31
|
|
mod=10**9 + 7
|
|
|
|
rh = RollingHash(b"foobar", base=base, mod=mod)
|
|
rolled_hash = rh.roll(ord("f"), ord("n"))
|
|
|
|
control_hash = RollingHash.compute_initial_hash(b"oobarn", base, mod)
|
|
|
|
self.assertEqual(rolled_hash, control_hash)
|