def test_hamming_norm(self) -> None: hash = Hash256() hash.setAll() self.assertEqual(hash.hammingNorm(), 256) hash = Hash256.fromHexString(self.SAMPLE_HASH) self.assertEqual(hash.hammingNorm(), 128)
def test_binary_operations(self) -> None: hash = Hash256.fromHexString(self.SAMPLE_HASH) self.assertTrue(hash.bitwiseAND(hash) == hash) hash_negative = hash.bitwiseNOT() self.assertTrue(hash.bitwiseAND(hash_negative) == Hash256()) hash_set_all = Hash256() hash_set_all.setAll() self.assertEqual(hash.bitwiseOR(hash_negative), hash_set_all) self.assertEqual(hash.bitwiseXOR(hash_negative), hash_set_all)
def test_hamming_distance(self) -> None: hash1 = Hash256.fromHexString(self.SAMPLE_HASH) hash2 = Hash256() hash2.clearAll() self.assertEqual(hash1.hammingDistance(hash2), 128) hash1 = Hash256() hash1.setAll() hash2 = Hash256() hash2.clearAll() self.assertEqual(hash1.hammingDistance(hash2), 256) self.assertEqual(hash1.hammingDistanceLE(hash2, 1), False) self.assertEqual(hash1.hammingDistanceLE(hash2, 257), True) self.assertEqual(hash1.hammingDistanceLE(hash1, 0), True)
def test_trace_enabled(self) -> None: pdq = PDQHasher() hamming_tolerance = 16 for path, expected_hash in self.get_data(): computed_hash = pdq.fromFile(path) expected_hash = Hash256.fromHexString(expected_hash) computed_hash = computed_hash.getHash() hamming_distance = computed_hash.hammingDistance(expected_hash) print(computed_hash, expected_hash, hamming_distance) self.assertLessEqual(hamming_distance, hamming_tolerance)
class Context: """ Helper class for tracking image-to-image deltas""" numPDQHash = int() pdqHashPrev = Hash256() hadError = bool() def __init__(self, _numPDQHash, _pdqHashPrev, _hadError) -> None: self.numPDQHash = _numPDQHash self.pdqHashPrev = _pdqHashPrev self.hadError = _hadError
def pdqBuffer16x16ToBits(self, dctOutput16x16): """ Each bit of the 16x16 output hash is for whether the given frequency component is greater than the median frequency component or not. """ hash = Hash256() dctMedian = MatrixUtil.torben(dctOutput16x16, 16, 16) for i in range(16): for j in range(16): if dctOutput16x16[i][j] > dctMedian: hash.setBit(i * 16 + j) return hash
def test_bit_count(self) -> None: self.assertEqual(Hash256.bitCount(1), 1) self.assertEqual(Hash256.bitCount(100), 3) # dec(10) = bin(01100100)
def test_to_string(self) -> None: s = self.SAMPLE_HASH hash = Hash256.fromHexString(s) self.assertEqual(hash.__str__(), s)
def test_clone(self) -> None: hash = Hash256.fromHexString(self.SAMPLE_HASH) hash_copy = hash.clone() self.assertTrue(hash == hash_copy)
def test_correct_hex_format(self) -> None: hash = Hash256.fromHexString(self.SAMPLE_HASH) self.assertNotEquals(hash, None)
def test_incorrect_hex_format(self) -> None: with self.assertRaises(PDQHashFormatException): Hash256.fromHexString( "9c151c3af838278e3ef57c180c7d031c07aefd12f2ccc1e18f2a1e1c7d0ff16!" )
def test_incorrect_hex_length(self) -> None: with self.assertRaises(PDQHashFormatException): Hash256.fromHexString("AAA")