Gronsfeld
Gronsfeld
A PIN for a key, every digit one shift.
- Keyspace
- 10^keyLength
- Decode
- same options back
- Works on
- A-Z, the rest passes
- Family
- 9 in polyalphabetic
Options
Access
- Create
create("gronsfeld") - CLI
ciphers encode gronsfeld GRONSFELD --key 1234 - Tryplayground with the sample above
- Kinvigenere, beaufort, porta, autokey +4
Gronsfeld is Vigenère with a number for a key. Each digit shifts one letter by 0 to 9, and the key repeats. So 1234 moves the first letter by one, the second by two, and so on. A PIN, a date, a phone number, the digits of pi. Who looks twice at four digits on a sticky note?
const gronsfeld = create("gronsfeld");
gronsfeld.encode("GRONSFELD", { key: "1234" }).text; // "HTRRTHHPE"
gronsfeld.decode("EEREG", { key: "123" }).text; // "DCODE"
Both are the worked examples from dCode.
Why is the key a string?
Because 0123 and 123 are different keys. A number eats the leading zero, and then every letter gets the wrong shift. So key is a string of digits and nothing else. Spaces, dashes, letters and a plain 1234 number are all an InvalidOptionError. No key at all is a MissingOptionError. On the CLI --key 0123 stays a string, zero included.
The Vigenère inside
Digit d is the Vigenère key letter d places after A. Wikipedia puts it in one line: Gronsfeld 0123 is Vigenère ABCD. The rest is Vigenère too. Spaces, punctuation and anything outside A to Z pass through without moving the key. preserveCase and stripNonAlpha work the same way.
Why it's weak
Ten shifts per key position instead of 26. A five digit key has 100,000 values, fewer than Vigenère has keys of four letters. And every Vigenère attack still works. period finds the key length. recover has no Gronsfeld mode and doesn't need one:
const secret = gronsfeld.encode(englishText, { key: "31415" }).text;
recoverKey(secret, { cipher: "vigenere" }).candidates[0].key; // "DBEBF"
A Vigenère key made only of A to J is a Gronsfeld key in disguise. Read it back as digits and DBEBF is 31415. Pi, of course.