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

Property definitions

crapto :: xor $ RepeatingKeyXorCipher :: get_normalized_hamming_distances
	# 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