{"record":{"id":"0b011c5b9747deac","repo":"gchq/CyberChef","slug":"the-key-must-consist-only-of-letters-in-the-englis","errorCode":null,"errorMessage":"The key must consist only of letters in the English alphabet","messagePattern":"The key must consist only of letters in the English alphabet","errorType":"exception","errorClass":"OperationError","httpStatus":null,"severity":"error","filePath":"src/core/operations/BifidCipherDecode.mjs","lineNumber":55,"sourceCode":"    /**\n     * @param {string} input\n     * @param {Object[]} args\n     * @returns {string}\n     *\n     * @throws {OperationError} if invalid key\n     */\n    run(input, args) {\n        const keywordStr = args[0].toUpperCase().replace(\"J\", \"I\"),\n            keyword = keywordStr.split(\"\").unique(),\n            alpha = \"ABCDEFGHIKLMNOPQRSTUVWXYZ\",\n            structure = [];\n\n        let output = \"\",\n            count = 0,\n            trans = \"\";\n\n        if (!/^[A-Z]+$/.test(keywordStr) && keyword.length > 0)\n            throw new OperationError(\"The key must consist only of letters in the English alphabet\");\n\n        const polybius = genPolybiusSquare(keywordStr);\n\n        input.replace(\"J\", \"I\").split(\"\").forEach((letter) => {\n            const alpInd = alpha.split(\"\").indexOf(letter.toLocaleUpperCase()) >= 0;\n            let polInd;\n\n            if (alpInd) {\n                for (let i = 0; i < 5; i++) {\n                    polInd = polybius[i].indexOf(letter.toLocaleUpperCase());\n                    if (polInd >= 0) {\n                        trans += `${i}${polInd}`;\n                    }\n                }\n\n                if (alpha.split(\"\").indexOf(letter) >= 0) {\n                    structure.push(true);\n                } else if (alpInd) {","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/operations/BifidCipherDecode.mjs#L37-L73","documentation":"Thrown by BifidCipherDecode.run when the keyword, after uppercasing and J->I substitution, contains any character outside A-Z AND is non-empty. The Bifid cipher builds a 5x5 Polybius square from the keyword, so the keyword must be pure English letters (I/J merged). An empty keyword is allowed (defaults to the standard square). The check is /^[A-Z]+$/ on the uppercased keyword string, so digits, spaces, punctuation, and accented letters all trigger rejection.","triggerScenarios":"Supplying a keyword with spaces, hyphens, digits (e.g. 'KEY 2'), accented characters (e.g. 'CAFE'), punctuation, or mixed scripts. Note: because J is replaced by I first, a literal 'J' in the keyword passes the check.","commonSituations":"User includes a space or hyphen thinking it is ignored; passphrase contains a digit; non-English accent characters in the keyword.","solutions":["Use a keyword containing only English letters A-Z (spaces/punctuation are not stripped).","Strip or replace non-A-Z characters before setting the keyword.","Leave the keyword empty to use the default ABCDE... Polybius square."],"exampleFix":"// before\nchef.bifidCipherDecode(input, { keyword: \"MY-KEY 2\" });\n\n// after\nchef.bifidCipherDecode(input, { keyword: \"MYKEY\" });","handlingStrategy":"validation","validationCode":"function assertBifidKeyword(keyword) {\n  const kw = String(keyword).toUpperCase();\n  if (kw.length > 0 && !/^[A-Z]+$/.test(kw)) {\n    throw new Error(\"Bifid keyword must contain only English letters A-Z\");\n  }\n  return kw;\n}\nassertBifidKeyword(keyword);","typeGuard":"function isAlphaKeyword(s) {\n  const kw = String(s ?? \"\").toUpperCase();\n  return kw.length === 0 || /^[A-Z]+$/.test(kw);\n}","tryCatchPattern":null,"preventionTips":["Use only English letters in the keyword; spaces/punctuation are not stripped.","Strip non-A-Z characters before setting the keyword.","Leave the keyword empty for the default Polybius square."],"tags":["cipher","bifid-cipher","input-validation"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}