TheAlgorithms/Java · error · IllegalArgumentException

Key must contain each position exactly once

Error message

Key must contain each position exactly once

What it means

validateKey() adds each position to a Set and rejects the key if add() returns false (i.e. the value was already present). A permutation must be a bijection — a duplicate means one block position is referenced twice while another is never reached, making encryption non-invertible and decryption impossible.

Source

Thrown at src/main/java/com/thealgorithms/ciphers/PermutationCipher.java:100

    /**
     * Validates that the permutation key is valid.
     * A valid key must contain all integers from 1 to n exactly once, where n is the key length.
     *
     * @param key the permutation key to validate
     * @throws IllegalArgumentException if the key is invalid
     */
    private void validateKey(int[] key) {
        if (key == null || key.length == 0) {
            throw new IllegalArgumentException("Key cannot be null or empty");
        }

        Set<Integer> keySet = new HashSet<>();
        for (int position : key) {
            if (position < 1 || position > key.length) {
                throw new IllegalArgumentException("Key must contain integers from 1 to " + key.length);
            }
            if (!keySet.add(position)) {
                throw new IllegalArgumentException("Key must contain each position exactly once");
            }
        }
    }

    /**
     * Pads the text with padding characters to make its length divisible by the block size.
     *
     * @param text the text to pad
     * @param blockSize the size of each block
     * @return the padded text
     */
    private String padText(String text, int blockSize) {
        int remainder = text.length() % blockSize;
        if (remainder == 0) {
            return text;
        }

        int paddingNeeded = blockSize - remainder;

View on GitHub (pinned to fdfb9a395b)

Solutions

  1. Ensure the key contains each integer from 1 to n exactly once — it is a permutation of {1,2,...,n}.
  2. Build the key from Collections.shuffle on an ArrayList of 1..n integers, which guarantees uniqueness by construction.
  3. Validate with a Set before calling the cipher: if set.size() != key.length, the key has a duplicate.

Example fix

// before (duplicate 2)
int[] key = {1, 2, 2, 3};

// after (build from a shuffled 1..n list)
List<Integer> base = new ArrayList<>();
for (int i = 1; i <= 4; i++) base.add(i);
Collections.shuffle(base);
int[] key = base.stream().mapToInt(Integer::intValue).toArray();
Defensive patterns

Strategy: validation

Validate before calling

Set<Integer> seen = new HashSet<>();
for (int v : key) seen.add(v);
if (seen.size() != key.length) {
    throw new IllegalArgumentException("Key contains duplicate positions");
}
cipher.encrypt(text, key);

Prevention

When it happens

Trigger: A key like {1,1,2} (position 1 repeated); {2,2} (position 2 repeated, position 1 missing); any array of 1..n values that contains a collision.

Common situations: Hand-crafted key with a duplicated number; a buggy custom shuffle that can repeat elements; copy-paste error when authoring the key.

Related errors


AI-assisted analysis of TheAlgorithms/Java@fdfb9a395b (2026-08-13). Data as JSON: /api/errors/63e0ceeebb6dc6f5. Report an issue: GitHub.