from exploits.hashes.collisions import crc32
from test.exploits.dummy_output import DummyOutput


def crc32_hash(bytes, hash_table_size):
    checksum = 0x00000000ffffffff
    for byte in bytes:
        checksum ^= ord(byte) & 0xff
        for _ in range(8):  # test each bit in the byte we just xor'd in
            checksum = (checksum >> 1) ^ 0xedb88320 if (checksum & 1) == 1 else checksum >> 1
    return (checksum ^ 0xffffffff) % hash_table_size


# crc32 takes a while so just one test where we generate one item
def test_run():
    output = DummyOutput()
    n_collisions = 1
    hash_table_size = 0xffffffff
    target = '42'
    length = 10
    crc32.options['n_collisions'] = n_collisions
    crc32.options['length'] = length
    crc32.options['target_type'] = 'image'
    crc32.options['target'] = target
    crc32.options['hash_table_size'] = hash_table_size
    crc32.run(output)
    assert output.count() == n_collisions
    for i in output:
        assert crc32_hash(i, hash_table_size) == int(target)
        assert len(i) == length
