{"record":{"id":"63e0ceeebb6dc6f5","repo":"TheAlgorithms/Java","slug":"key-must-contain-each-position-exactly-once","errorCode":null,"errorMessage":"Key must contain each position exactly once","messagePattern":"Key must contain each position exactly once","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/com/thealgorithms/ciphers/PermutationCipher.java","lineNumber":100,"sourceCode":"    /**\r\n     * Validates that the permutation key is valid.\r\n     * A valid key must contain all integers from 1 to n exactly once, where n is the key length.\r\n     *\r\n     * @param key the permutation key to validate\r\n     * @throws IllegalArgumentException if the key is invalid\r\n     */\r\n    private void validateKey(int[] key) {\r\n        if (key == null || key.length == 0) {\r\n            throw new IllegalArgumentException(\"Key cannot be null or empty\");\r\n        }\r\n\r\n        Set<Integer> keySet = new HashSet<>();\r\n        for (int position : key) {\r\n            if (position < 1 || position > key.length) {\r\n                throw new IllegalArgumentException(\"Key must contain integers from 1 to \" + key.length);\r\n            }\r\n            if (!keySet.add(position)) {\r\n                throw new IllegalArgumentException(\"Key must contain each position exactly once\");\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Pads the text with padding characters to make its length divisible by the block size.\r\n     *\r\n     * @param text the text to pad\r\n     * @param blockSize the size of each block\r\n     * @return the padded text\r\n     */\r\n    private String padText(String text, int blockSize) {\r\n        int remainder = text.length() % blockSize;\r\n        if (remainder == 0) {\r\n            return text;\r\n        }\r\n\r\n        int paddingNeeded = blockSize - remainder;\r","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/TheAlgorithms/Java/blob/fdfb9a395b310167a66bd29e311e36e0e3e9b964/src/main/java/com/thealgorithms/ciphers/PermutationCipher.java#L82-L118","documentation":"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.","triggerScenarios":"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.","commonSituations":"Hand-crafted key with a duplicated number; a buggy custom shuffle that can repeat elements; copy-paste error when authoring the key.","solutions":["Ensure the key contains each integer from 1 to n exactly once — it is a permutation of {1,2,...,n}.","Build the key from Collections.shuffle on an ArrayList of 1..n integers, which guarantees uniqueness by construction.","Validate with a Set before calling the cipher: if set.size() != key.length, the key has a duplicate."],"exampleFix":"// before (duplicate 2)\nint[] key = {1, 2, 2, 3};\n\n// after (build from a shuffled 1..n list)\nList<Integer> base = new ArrayList<>();\nfor (int i = 1; i <= 4; i++) base.add(i);\nCollections.shuffle(base);\nint[] key = base.stream().mapToInt(Integer::intValue).toArray();","handlingStrategy":"validation","validationCode":"Set<Integer> seen = new HashSet<>();\nfor (int v : key) seen.add(v);\nif (seen.size() != key.length) {\n    throw new IllegalArgumentException(\"Key contains duplicate positions\");\n}\ncipher.encrypt(text, key);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Build keys via Collections.shuffle on a 1..n list to guarantee uniqueness.","Check set.size() == key.length before calling the cipher.","Avoid hand-authoring permutation keys; generate them programmatically."],"tags":["cipher","permutation","duplicate","validation","illegal-argument"],"backgroundTag":null,"analyzedSha":"fdfb9a395b310167a66bd29e311e36e0e3e9b964","analyzedAt":"2026-08-13T23:36:13.315Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}