[{"data":1,"prerenderedAt":530},["ShallowReactive",2],{"navigation_docs":3,"-ciphers-substitution":288,"-ciphers-substitution-surround":525},[4,36],{"title":5,"path":6,"stem":7,"children":8,"icon":35},"Guide","\u002Fguide","1.guide\u002F01.index",[9,11,15,19,23,27,31],{"title":10,"path":6,"stem":7},"Getting Started",{"title":12,"path":13,"stem":14},"Encode and decode","\u002Fguide\u002Ftransform","1.guide\u002F02.transform",{"title":16,"path":17,"stem":18},"Analysis","\u002Fguide\u002Fanalysis","1.guide\u002F03.analysis",{"title":20,"path":21,"stem":22},"CLI","\u002Fguide\u002Fcli","1.guide\u002F04.cli",{"title":24,"path":25,"stem":26},"Agents","\u002Fguide\u002Fagents","1.guide\u002F05.agents",{"title":28,"path":29,"stem":30},"Custom ciphers","\u002Fguide\u002Fcustom","1.guide\u002F06.custom",{"title":32,"path":33,"stem":34},"Playground","\u002Fguide\u002Fplayground","1.guide\u002F07.playground","i-lucide-book-open",{"title":37,"path":38,"stem":39,"children":40,"icon":287},"Ciphers","\u002Fciphers","2.ciphers\u002F00.index",[41,43,47,51,55,59,63,67,71,75,79,83,87,91,95,99,103,107,111,115,119,123,127,131,135,139,143,147,151,155,159,163,167,171,175,179,183,187,191,195,199,203,207,211,215,219,223,227,231,235,239,243,247,251,255,259,263,267,271,275,279,283],{"title":42,"path":38,"stem":39},"Overview",{"title":44,"path":45,"stem":46},"Classical","\u002Fciphers\u002Fclassical","2.ciphers\u002F01.classical",{"title":48,"path":49,"stem":50},"Caesar","\u002Fciphers\u002Fcaesar","2.ciphers\u002F02.caesar",{"title":52,"path":53,"stem":54},"ROT-13","\u002Fciphers\u002Frot13","2.ciphers\u002F03.rot13",{"title":56,"path":57,"stem":58},"ROT-47","\u002Fciphers\u002Frot47","2.ciphers\u002F04.rot47",{"title":60,"path":61,"stem":62},"Atbash","\u002Fciphers\u002Fatbash","2.ciphers\u002F05.atbash",{"title":64,"path":65,"stem":66},"Affine","\u002Fciphers\u002Faffine","2.ciphers\u002F06.affine",{"title":68,"path":69,"stem":70},"Substitution","\u002Fciphers\u002Fsubstitution","2.ciphers\u002F07.substitution",{"title":72,"path":73,"stem":74},"Vigenère","\u002Fciphers\u002Fvigenere","2.ciphers\u002F08.vigenere",{"title":76,"path":77,"stem":78},"Beaufort","\u002Fciphers\u002Fbeaufort","2.ciphers\u002F09.beaufort",{"title":80,"path":81,"stem":82},"Autokey","\u002Fciphers\u002Fautokey","2.ciphers\u002F10.autokey",{"title":84,"path":85,"stem":86},"Trithemius","\u002Fciphers\u002Ftrithemius","2.ciphers\u002F11.trithemius",{"title":88,"path":89,"stem":90},"Alberti","\u002Fciphers\u002Falberti","2.ciphers\u002F12.alberti",{"title":92,"path":93,"stem":94},"Playfair","\u002Fciphers\u002Fplayfair","2.ciphers\u002F13.playfair",{"title":96,"path":97,"stem":98},"Hill","\u002Fciphers\u002Fhill","2.ciphers\u002F14.hill",{"title":100,"path":101,"stem":102},"Polybius square","\u002Fciphers\u002Fpolybius","2.ciphers\u002F15.polybius",{"title":104,"path":105,"stem":106},"Nihilist","\u002Fciphers\u002Fnihilist","2.ciphers\u002F16.nihilist",{"title":108,"path":109,"stem":110},"Morse code","\u002Fciphers\u002Fmorse","2.ciphers\u002F17.morse",{"title":112,"path":113,"stem":114},"Bacon's cipher","\u002Fciphers\u002Fbacon","2.ciphers\u002F18.bacon",{"title":116,"path":117,"stem":118},"Tap code","\u002Fciphers\u002Ftap-code","2.ciphers\u002F19.tap-code",{"title":120,"path":121,"stem":122},"A1Z26","\u002Fciphers\u002Fa1z26","2.ciphers\u002F20.a1z26",{"title":124,"path":125,"stem":126},"Book cipher","\u002Fciphers\u002Fbook","2.ciphers\u002F21.book",{"title":128,"path":129,"stem":130},"ADFGVX","\u002Fciphers\u002Fadfgvx","2.ciphers\u002F22.adfgvx",{"title":132,"path":133,"stem":134},"Bifid","\u002Fciphers\u002Fbifid","2.ciphers\u002F23.bifid",{"title":136,"path":137,"stem":138},"Straddling checkerboard","\u002Fciphers\u002Fstraddling-checkerboard","2.ciphers\u002F24.straddling-checkerboard",{"title":140,"path":141,"stem":142},"Rail fence","\u002Fciphers\u002Frail-fence","2.ciphers\u002F25.rail-fence",{"title":144,"path":145,"stem":146},"Columnar transposition","\u002Fciphers\u002Fcolumnar","2.ciphers\u002F26.columnar",{"title":148,"path":149,"stem":150},"Route transposition","\u002Fciphers\u002Froute","2.ciphers\u002F27.route",{"title":152,"path":153,"stem":154},"Enigma M3","\u002Fciphers\u002Fenigma","2.ciphers\u002F28.enigma",{"title":156,"path":157,"stem":158},"Block","\u002Fciphers\u002Fblock","2.ciphers\u002F29.block",{"title":160,"path":161,"stem":162},"AES (ECB)","\u002Fciphers\u002Faes","2.ciphers\u002F30.aes",{"title":164,"path":165,"stem":166},"AES (CBC)","\u002Fciphers\u002Faes-cbc","2.ciphers\u002F31.aes-cbc",{"title":168,"path":169,"stem":170},"AES (CFB)","\u002Fciphers\u002Faes-cfb","2.ciphers\u002F32.aes-cfb",{"title":172,"path":173,"stem":174},"AES (OFB)","\u002Fciphers\u002Faes-ofb","2.ciphers\u002F33.aes-ofb",{"title":176,"path":177,"stem":178},"AES (CTR)","\u002Fciphers\u002Faes-ctr","2.ciphers\u002F34.aes-ctr",{"title":180,"path":181,"stem":182},"AES (CCM)","\u002Fciphers\u002Faes-ccm","2.ciphers\u002F35.aes-ccm",{"title":184,"path":185,"stem":186},"AES (OCB)","\u002Fciphers\u002Faes-ocb","2.ciphers\u002F36.aes-ocb",{"title":188,"path":189,"stem":190},"AES (LRW)","\u002Fciphers\u002Faes-lrw","2.ciphers\u002F37.aes-lrw",{"title":192,"path":193,"stem":194},"AES (XTS)","\u002Fciphers\u002Faes-xts","2.ciphers\u002F38.aes-xts",{"title":196,"path":197,"stem":198},"AES (CBC-MAC)","\u002Fciphers\u002Faes-cbc-mac","2.ciphers\u002F39.aes-cbc-mac",{"title":200,"path":201,"stem":202},"AES (passphrase)","\u002Fciphers\u002Faes-passphrase","2.ciphers\u002F40.aes-passphrase",{"title":204,"path":205,"stem":206},"Rijndael (ECB)","\u002Fciphers\u002Frijndael","2.ciphers\u002F41.rijndael",{"title":208,"path":209,"stem":210},"DES (ECB)","\u002Fciphers\u002Fdes","2.ciphers\u002F42.des",{"title":212,"path":213,"stem":214},"DESX (ECB)","\u002Fciphers\u002Fdesx","2.ciphers\u002F43.desx",{"title":216,"path":217,"stem":218},"Triple DES (ECB)","\u002Fciphers\u002Ftriple-des","2.ciphers\u002F44.triple-des",{"title":220,"path":221,"stem":222},"Triple DES (CBC)","\u002Fciphers\u002Ftriple-des-cbc","2.ciphers\u002F45.triple-des-cbc",{"title":224,"path":225,"stem":226},"Blowfish (ECB)","\u002Fciphers\u002Fblowfish","2.ciphers\u002F46.blowfish",{"title":228,"path":229,"stem":230},"IDEA (ECB)","\u002Fciphers\u002Fidea","2.ciphers\u002F47.idea",{"title":232,"path":233,"stem":234},"Lucifer (ECB)","\u002Fciphers\u002Flucifer","2.ciphers\u002F48.lucifer",{"title":236,"path":237,"stem":238},"MARS (ECB)","\u002Fciphers\u002Fmars","2.ciphers\u002F49.mars",{"title":240,"path":241,"stem":242},"Serpent (ECB)","\u002Fciphers\u002Fserpent","2.ciphers\u002F50.serpent",{"title":244,"path":245,"stem":246},"CAST5 (ECB)","\u002Fciphers\u002Fcast5","2.ciphers\u002F51.cast5",{"title":248,"path":249,"stem":250},"OpenPGP (passphrase)","\u002Fciphers\u002Fopenpgp","2.ciphers\u002F52.openpgp",{"title":252,"path":253,"stem":254},"Stream","\u002Fciphers\u002Fstream","2.ciphers\u002F53.stream",{"title":256,"path":257,"stem":258},"Rabbit","\u002Fciphers\u002Frabbit","2.ciphers\u002F54.rabbit",{"title":260,"path":261,"stem":262},"RC4","\u002Fciphers\u002Frc4","2.ciphers\u002F55.rc4",{"title":264,"path":265,"stem":266},"XOR","\u002Fciphers\u002Fxor","2.ciphers\u002F56.xor",{"title":268,"path":269,"stem":270},"Salsa20","\u002Fciphers\u002Fsalsa20","2.ciphers\u002F57.salsa20",{"title":272,"path":273,"stem":274},"XSalsa20","\u002Fciphers\u002Fxsalsa20","2.ciphers\u002F58.xsalsa20",{"title":276,"path":277,"stem":278},"ChaCha20","\u002Fciphers\u002Fchacha20","2.ciphers\u002F59.chacha20",{"title":280,"path":281,"stem":282},"XChaCha20","\u002Fciphers\u002Fxchacha20","2.ciphers\u002F60.xchacha20",{"title":284,"path":285,"stem":286},"ChaCha20-Poly1305","\u002Fciphers\u002Fchacha20-poly1305","2.ciphers\u002F61.chacha20-poly1305","i-lucide-library",{"id":289,"title":68,"body":290,"description":518,"extension":519,"links":520,"meta":521,"navigation":522,"path":69,"seo":523,"stem":70,"__hash__":524},"docs\u002F2.ciphers\u002F07.substitution.md",{"type":291,"value":292,"toc":514},"minimark",[293,297,305,310,329,417,420,424,446,492,501,510],[294,295],"cipher-facts",{"name":296},"substitution",[298,299,300,301,304],"p",{},"The one from the newspaper puzzle page. Every letter gets one stand-in, and it's the same one every time. ",[302,303,48],"a",{"href":49}," does that too, but Caesar only slides the alphabet. Here the alphabet is shuffled any way you like. That's 26! keys, about 2^88. Nobody tries them all.",[306,307,309],"h2",{"id":308},"the-key","The key",[298,311,312,316,317,320,321,324,325,328],{},[313,314,315],"code",{},"key"," comes in two shapes. Exactly 26 letters is a whole cipher alphabet, taken as it is: the first cell is what A becomes, the second is B, and so on. Each letter shows up once. A repeat is an ",[313,318,319],{},"InvalidOptionError",", not a quiet keyword with some other mapping. Anything else is a keyword. Its letters go first, repeats dropped, then the rest of A to Z in order. So ",[313,322,323],{},"ZEBRAS"," turns into ",[313,326,327],{},"ZEBRASCDFGHIJKLMNOPQTUVWXY",", and that's Wikipedia's example:",[330,331,336],"pre",{"className":332,"code":333,"language":334,"meta":335,"style":335},"language-ts shiki shiki-themes ciphers ciphers ciphers","const substitution = create(\"substitution\");\nsubstitution.encode(\"FLEE AT ONCE. WE ARE DISCOVERED!\", { key: \"ZEBRAS\" }).text; \u002F\u002F \"SIAA ZQ LKBA. VA ZOA RFPBLUAOAR!\"\nsubstitution.decode(\"SIAA ZQ LKBA. VA ZOA RFPBLUAOAR!\", { key: \"ZEBRAS\" }).text; \u002F\u002F \"FLEE AT ONCE. WE ARE DISCOVERED!\"\n","ts","",[313,337,338,368,395],{"__ignoreMap":335},[339,340,343,347,351,354,358,361,365],"span",{"class":341,"line":342},"line",1,[339,344,346],{"class":345},"skH_V","const",[339,348,350],{"class":349},"s38Sx"," substitution ",[339,352,353],{"class":345},"=",[339,355,357],{"class":356},"sK71F"," create",[339,359,360],{"class":349},"(",[339,362,364],{"class":363},"shU9J","\"substitution\"",[339,366,367],{"class":349},");\n",[339,369,371,374,377,379,382,385,388,391],{"class":341,"line":370},2,[339,372,373],{"class":349},"substitution.",[339,375,376],{"class":356},"encode",[339,378,360],{"class":349},[339,380,381],{"class":363},"\"FLEE AT ONCE. WE ARE DISCOVERED!\"",[339,383,384],{"class":349},", { key: ",[339,386,387],{"class":363},"\"ZEBRAS\"",[339,389,390],{"class":349}," }).text; ",[339,392,394],{"class":393},"scIB-","\u002F\u002F \"SIAA ZQ LKBA. VA ZOA RFPBLUAOAR!\"\n",[339,396,398,400,403,405,408,410,412,414],{"class":341,"line":397},3,[339,399,373],{"class":349},[339,401,402],{"class":356},"decode",[339,404,360],{"class":349},[339,406,407],{"class":363},"\"SIAA ZQ LKBA. VA ZOA RFPBLUAOAR!\"",[339,409,384],{"class":349},[339,411,387],{"class":363},[339,413,390],{"class":349},[339,415,416],{"class":393},"\u002F\u002F \"FLEE AT ONCE. WE ARE DISCOVERED!\"\n",[298,418,419],{},"Case stays put. Spaces, digits and everything outside A to Z pass through untouched.",[306,421,423],{"id":422},"a-key-with-holes","A key with holes",[298,425,426,427,432,433,436,437,439,440,442,443,445],{},"What if you only know part of the key? ",[302,428,429],{"href":17},[313,430,431],{},"recover"," solves a substitution from the ciphertext alone. But it can only name letters the text actually uses, and the rest come back as ",[313,434,435],{},"?",". Hand that key straight to ",[313,438,402],{},". A ",[313,441,435],{}," cell gives ",[313,444,435],{},", and every letter you do know reads fine:",[330,447,449],{"className":332,"code":448,"language":334,"meta":335,"style":335},"substitution.encode(\"Bad\", { key: \"ZEB?ASCDFGHIJKLMNOPQTUVWXY\" }).text; \u002F\u002F \"Ez?\"\nsubstitution.decode(\"Ez?R\", { key: \"ZEB?ASCDFGHIJKLMNOPQTUVWXY\" }).text; \u002F\u002F \"Ba??\"\n",[313,450,451,472],{"__ignoreMap":335},[339,452,453,455,457,459,462,464,467,469],{"class":341,"line":342},[339,454,373],{"class":349},[339,456,376],{"class":356},[339,458,360],{"class":349},[339,460,461],{"class":363},"\"Bad\"",[339,463,384],{"class":349},[339,465,466],{"class":363},"\"ZEB?ASCDFGHIJKLMNOPQTUVWXY\"",[339,468,390],{"class":349},[339,470,471],{"class":393},"\u002F\u002F \"Ez?\"\n",[339,473,474,476,478,480,483,485,487,489],{"class":341,"line":370},[339,475,373],{"class":349},[339,477,402],{"class":356},[339,479,360],{"class":349},[339,481,482],{"class":363},"\"Ez?R\"",[339,484,384],{"class":349},[339,486,466],{"class":363},[339,488,390],{"class":349},[339,490,491],{"class":393},"\u002F\u002F \"Ba??\"\n",[298,493,494,495,497,498,500],{},"A ",[313,496,435],{}," only counts in a whole alphabet: 26 cells, each letter at most once. Anywhere else it's an ",[313,499,319],{},". Why so strict? A recovered key that lost a cell on the way would turn into a keyword and shift every letter after the gap. Quietly. No thanks.",[298,502,503,505,506,509],{},[302,504,60],{"href":61}," and all 25 Caesar shifts are substitutions too, just with keys you could write down from memory. ",[302,507,508],{"href":17},"Counting letters"," breaks every one of them the same way.",[511,512,513],"style",{},"html pre.shiki code .skH_V, html code.shiki .skH_V{--shiki-light:var(--shiki-token-keyword);--shiki-default:var(--shiki-token-keyword);--shiki-dark:var(--shiki-token-keyword)}html pre.shiki code .s38Sx, html code.shiki .s38Sx{--shiki-light:var(--ui-text-highlighted);--shiki-default:var(--ui-text-highlighted);--shiki-dark:var(--ui-text-highlighted)}html pre.shiki code .sK71F, html code.shiki .sK71F{--shiki-light:var(--shiki-token-function);--shiki-default:var(--shiki-token-function);--shiki-dark:var(--shiki-token-function)}html pre.shiki code .shU9J, html code.shiki .shU9J{--shiki-light:var(--shiki-token-string);--shiki-default:var(--shiki-token-string);--shiki-dark:var(--shiki-token-string)}html pre.shiki code .scIB-, html code.shiki .scIB-{--shiki-light:var(--shiki-token-comment);--shiki-default:var(--shiki-token-comment);--shiki-dark:var(--shiki-token-comment)}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":335,"searchDepth":370,"depth":370,"links":515},[516,517],{"id":308,"depth":370,"text":309},{"id":422,"depth":370,"text":423},"Every letter swaps for its cell in a mixed alphabet. Hand it the whole alphabet or just a keyword, it's 26! keys either way.","md",null,{},true,{"title":68,"description":518},"Rbfwj6y4IwVE5IXpMzjeAFivr4cL1jQ647opEplte38",[526,528],{"title":64,"path":65,"stem":66,"description":527,"children":-1},"E(x) = (a·x + b) mod 26. The multiplier must be coprime with 26, which leaves twelve of them and 312 keys.",{"title":72,"path":73,"stem":74,"description":529,"children":-1},"A keyword picks a different Caesar shift for each letter. Keyspace 26 to the key length, weakness is the period.",1791419053793]