crypto :: RepeatingKeyXorCipher :: get_normalized_hamming_distances
min_length
and max_length
.The considered_keylength_count
smallest results are returned
# Computes the normalized hamming distances between blocks of ciphertext of length between `min_length` and `max_length`.
# The `considered_keylength_count` smallest results are returned
private fun get_normalized_hamming_distances(min_keylength, max_keylength, considered_keylength_count: Int): Array[Int] do
var normalized_distances = new HashMap[Float, Int]
# Iterate over all given key lengths
for ks in [min_keylength .. max_keylength[ do
# Initialize the blocks of size `ks`
var blocks = new Array[Bytes]
while (blocks.length + 1) * ks < ciphertext.length do
blocks.add(ciphertext.slice(blocks.length * ks, ks))
end
# Compute the normalized hamming distance with all block combinations
var pairs = new CombinationCollection[Bytes](blocks, 2)
var hamming_dists = new Array[Float]
for p in pairs do
hamming_dists.add(p[0].hamming_distance(p[1]).to_f / ks.to_f)
end
# Normalize the results based on the number of blocks
var normalized = 0.0
for dist in hamming_dists do normalized += dist
normalized /= hamming_dists.length.to_f
normalized_distances[normalized] = ks
end
# Collect the best candidates
var distances = normalized_distances.keys.to_a
default_comparator.sort(distances)
var best_distances = distances.subarray(0, considered_keylength_count)
var best_sizes = [for d in best_distances do normalized_distances[d]]
return best_sizes
end
lib/crapto/xor.nit:98,2--135,4