This challenge was part of 2020's qualifiers, but should still be solvable.

Where code golf challenges are concerned, tradition seems to imply it's never crypto. But you know what? This year it's indeed cryptography, of the classic, simple, variety.

Your task will be to implement a Beaufort Cipher in the shortest, crazyest, JavaScript code you can possibly write. With no external code or remote connections whatsoever.

If you're in a hurry to start coding, jump directly to the task description.

Some History

You've probably heard of the Enigma machine, used by the germans during the second world war and broken by Alan Turing at Bletchley Park — there's even a movie about it. But you may have never heard about the Hagelin M-209, used by the american forces around the same time period.

The M-209 — while woefully insecure by our modern standards — remained useful throughout the later Korean War. Often you only need encrypted messages to resist codebreakers for long enough, until the hidden information becomes old news.

The machine itself is intricate, with pins, lugs, and a complicated protocol of internal and external keys. But we don't care about that here. What we do care about is the simple Beaufort Cipher within it, which can be traced back hundreds of years.

The Beaufort Cipher

The Beaufort Cipher is a reciprocal cipher, meaning the exact same steps are used for enciphering and deciphering messages. The only difference is the text that goes in.

Start by building a tabula recta, a square table where an (arbitrary) alphabet in the first row is repeated in the following rows while incrementally shifting it towards the left.

Now take the input text and pair it with a secret key known by both parties. You may need to repeat or truncate the key to match the text's length. Then, for each input text character, find it in the first row of the tabula recta, then follow that column down until you find the matching secret key character. The output text character is on the far left.

Input:  MOVEYOURTROOPSATZEROTHREEHUNDRED
Key:    SECRETSECRETSECRETSECRETSECRETSE
Output: GQHNGFYNJAQFDMCYFPBQJKNPOXIEBCOB

Now let's try it in the other direction: the G from the encrypted text is in column 6, and the S from the key is in row 12, then the deciphered character is the original M. Bingo!

Input:  GQHNGFYNJAQFDMCYFPBQJKNPOXIEBCOB
Key:    SECRETSECRETSECRETSECRETSECRETSE
Output: MOVEYOURTROOPSATZEROTHREEHUNDRED

If you're wondering, the M-209's secret sauce was changing the shift in the tabula recta as characters were processed, based on its internal pin-and-lug configuration.

Task Description

For this challenge you must write a JavaScript function "f" taking three parameters: the alphabet, the secret key, and an arbitrary string of text. The return value must be a new string with the result of applying the Beaufort Cipher as described above.

function f(alphabet, key, text) {
    return "";
}

The alphabet is guaranteed not to have any duplicate characters, but these can be any character and appear in any order.

The input text may contain any characters whatsoever, but characters not part of the provided alphabet must be ignored.

The key is guaranteed to only have characters from the provided alphabet, but each character may appear multiple times. It can also be the empty string, in which case the output will have only the valid characters from the input text, as themselves.

The output text must not have any extra spaces or other unwanted characters.

Testing Your Code

The following alphabet, key, and text are passed to the code you write in the answer box. Figuring out what you can get away with is part of the game: you may want to be conservative until you get your first accepted answer. Be wary of the bleeding edge.

The runtime enviroment used by the quizmaster to validate answers is classified, but you can safely assume it will remain unchanged throughout the whole challenge.

Challenge Answer

Submit your code for review below. You can submit another answer at any time, but beware that only your last submission will count in the end, regardless of verdict.

Length: 0 bytes

If you have questions, join the #quizshow channel on Slack and ask away.