@@ -0,0 +1,359 @@
1+:- :~ navhome/'/docs/'
2+ next/'true'
3+ sort/'1'
4+ title/'Caesar Cipher'
5+ ==
6+;>
7+
8+# Caesar Cipher
9+
10+A Caesar cipher is a very simple way to obfuscate a message. The technique
11+takes a string and swaps out each component letter with another letter that is
12+a specified number of positions up or down in the alphabet. For example, with a
13+"right-shift" of 1, `a` would become `b`, `j` would become `k`, and `z` would
14+wrap around back to `a`.
15+
16+Consider the message below, and the cipher that results when we Caesar-shift the
17+message to the right by 1.
18+
19+```
20+Plaintext message: "do not give way to anger"
21+Right-shifted cipher: "ep opu hjwf xbz up bohfs"
22+```
23+
24+Note that the Caesar cipher is completely unsuitable for actually securing
25+information. Implementing it in a program is just a fun exercise.
26+
27+### A Caesar Cipher In Hoon
28+
29+Below is a generator that performs a Caesar cipher on a tape. This example
30+isn't the most compact implementation of such a cipher in Hoon, but it
31+demonstrates important principles that more laconic code would not. Save it as
32+`caesar.hoon` in your `/gen` directory.
33+
34+```
35+!:
36+:- %say
37+=+ ^= caesar
38+ |%
39+ ++ alpha "abcdefghijklmnopqrstuvwxyz"
40+ ++ shift
41+ |= [message=tape key=@ud]
42+ (operate message key (encoder key))
43+ ++ unshift
44+ |= [message=tape key=@ud]
45+ (operate message key (decoder key))
46+ ++ operate
47+ |= [message=tape key=@ud encoder=(map @t @t)]
48+ ^- tape
49+ %+ turn message
50+ |= a=@t
51+ (~(got by encoder) a)
52+ ++ encoder
53+ |= [key=@ud]
54+ =/ keytape=tape (rott alpha key)
55+ (coder alpha keytape)
56+ ++ decoder
57+ |= [key=@ud]
58+ =/ keytape=tape (rott alpha key)
59+ (coder keytape alpha)
60+ ++ coder
61+ |= [a=tape b=tape]
62+ (~(put by (zipper a b)) ' ' ' ')
63+ ++ zipper
64+ |= [a=tape b=tape]
65+ ^- (map @t @t)
66+ =| chart=(map @t @t)
67+ ?. =((lent a) (lent b))
68+ ~| %uneven-lengths !!
69+ |-
70+ ?: |(?=(~ a) ?=(~ b))
71+ chart
72+ $(chart (~(put by chart) i.a i.b), a t.a, b t.b)
73+ ++ rott
74+ |= [m=tape n=@ud]
75+ =/ length=@ud (lent m)
76+ =+ s=(trim (mod n length) m)
77+ (weld q.s p.s)
78+ --
79+|= [* [msg=tape key=@ud ~] ~]
80+:- %noun
81+=. msg (cass msg)
82+:- (shift.caesar msg key)
83+(unshift.caesar msg key)
84+```
85+
86+This generator takes two arguments: a `tape`, which is your plaintext message,
87+and an unsigned integer, which is the shift-value of the cipher. It produces
88+a cell of two `tapes`: one that has been shifted right by the value, and another
89+that has been shifted left. It also converts any uppercase input into lowercase.
90+
91+Try it out in the Dojo:
92+
93+```
94+> +caesar "test" 2
95+["vguv" "rcqr"]
96+
97+> +caesar "test" 26
98+["test" "test"]
99+
100+> +caesar "test" 28
101+["vguv" "rcqr"]
102+
103+> +caesar "test" 104
104+["test" "test"]
105+
106+> +caesar "tESt" 2
107+["vguv" "rcqr"]
108+
109+> +caesar "test!" 2
110+nest-fail
111+
112+```
113+
114+##### Examining Our Code
115+
116+Let's examine our `caesar.hoon` code piece by piece. We won't necessarily go
117+in written order; instead, we'll cover code in the intuitive order of the
118+program. For each chunk that we cover, try to read and understand the code
119+itself before reading the explanation.
120+
121+```
122+!:
123+:- %say
124+=+ ^= caesar
125+ |%
126+```
127+
128+The `!:` in the first line of the above code enables a full stack trace in the
129+event of an error.
130+
131+`:- %say` begins to construct a cell with `%say` as the head, and the code that
132+follows as the tail. This causes the Arvo to interpret the file as a
133+[`%say` generator](/docs/tutorials/generators).
134+
135+`=+` adds a noun the subject, `=^ caesar` names that noun, and `|%` is used
136+to create a core that contains the following arms. This results in having a core
137+with the face `caesar` that we can call.
138+
139+Now let's look at the rest of the program that is outside of our core:
140+
141+```
142+|= [* [msg=tape key=@ud ~] ~]
143+:- %noun
144+=. msg (cass msg)
145+:- (shift.caesar msg key)
146+(unshift.caesar msg key)
147+```
148+
149+The top line creates a gate with `|=`. The sample of that gate follows the
150+scheme used by `%say` generators: it's a 3-tuple whose parts allow for different
151+kinds of data. We only need non-optional arguments, though, so we only fill in
152+the second part. There we take a `msg` argument and a `key` argument. We use a
153+`*` and a `~` in the first part (Arvo data) and third part (optional arguments),
154+respectively, because we aren't using them here. See the
155+[generator documentation](/docs/tutorials/generators) for more information.
156+
157+`:- %noun` simply labels the output of this program as the `%noun` mark.
158+
159+`=. msg (cass msg)` changes the input string `msg` to lowercases. `=.` changes
160+the leg of the subject to something else. In our case, the leg to be changed is
161+`msg`, and the thing to replace it is `(cass msg)`. `cass` is a standard-library
162+gate that converts uppercase letters to lowercase.
163+
164+`:- (shift.caesar msg key)` and `(unshift.caesar msg key)` simply composes a
165+cell of a right-shifted cipher and a left-shifted cell. This is the final output
166+of our generator.
167+
168+```
169+ ++ rott
170+ |= [m=tape n=@ud]
171+ =/ length=@ud (lent m)
172+ =+ s=(trim (mod n length) m)
173+ (weld q.s p.s)
174+```
175+
176+The `rott` arm takes takes a specified number of characters off of a tape and
177+puts them on the end of the tape.
178+
179+`|= [m=tape n=@ud]` creates a gate that takes two arguments: `m`, a `tape`,
180+and `n`, a `@ud`.
181+
182+`=/ length=@ud (lent m)` stores the length of `m` to make the following
183+code a little clearer.
184+
185+`trim` is a a gate from the standard library that splits a tape at into two
186+parts at a specified position. So `=+ s=(trim (mod n length) m)` splits the
187+tape `m` into two parts, `p` and `q`, and stores it in `s`. We call the modulus
188+operation `mod` to make sure that we split our `tape` at the correct place, even
189+if `n` is larger than `length`.
190+
191+`(weld q.s p.s)` uses `weld`, which combines two strings into one. In this
192+instance, we are switching the two parts: the second part `q.s` is welded to the
193+front, and the first part `p.s` is welded to the back.
194+
195+```
196+ ++ zipper
197+ |= [a=tape b=tape]
198+ ^- (map @t @t)
199+ =| chart=(map @t @t)
200+ ?. =((lent a) (lent b))
201+ ~| %uneven-lengths !!
202+ |-
203+ ?: |(?=(~ a) ?=(~ b))
204+ chart
205+ $(chart (~(put by chart) i.a i.b), a t.a, b t.b)
206+```
207+
208+The `zipper` arm takes two tapes and creates a `map` out of them -- an
209+an association between their elements.
210+
211+So then if `tapes` are easier to manipulate, why then are we producing `cords`?
212+In this case what we are going to to be doing is mapping a single element of a `
213+tape` to another element of a `tape`, which as we have established as being a
214+`cord`. This will simplify our use of this method and we don't need to
215+manipulate the keys or values, simply look them up.
216+
217+`|= [a=tape b=tape]` builds a gate that takes two tapes, `a` and `b`, as its
218+sample.
219+
220+`^- (map @t @t)` casts the gate to a `map` with a `cord` key and a `cord`
221+value. A `map` is a type equivalent to a dictionary in other languages: it's a
222+data structure that associates a key with a value. If, for example, we wanted
223+to have an association between `a` and 1 and `b` and 2, we could use a `map`.
224+
225+`=| chart=(map @t @t)` adds a noun to the subject with the default value of
226+the `(map @t @t)` type, and gives that noun the face `chart`.
227+
228+`?. =((lent a) (lent b))` checks if the two tapes are the same length. If not,
229+the program crashes.
230+
231+`|-` creates a trap, a gate that is called immediately.
232+
233+`?: |(?=(~ a) ?=(~ b))` checks if either tape is empty. If this is true, we
234+the program is finished and can return `chart`, the the `map` that we have been
235+creating.
236+
237+If the above test finds that its condition to be false, we trigger a recursion
238+that constructs our `map`: $(chart (~(put by chart) i.a i.b), a t.a, b t.b)`.
239+This code recursively adds an entry in our `map` where the head of the tape `a`
240+maps to the value of the head of tape `b` with `~(put by chart)`, our calling
241+of the `put` arm of the `by` map-engien core. The recursion also "consumes"
242+those heads with every iteration by changing `a` and `b` to their tails.
243+
244+Perhaps now you can understand why this arm is named `zipper`. It's putting two
245+tapes together by matching pieces from each side, something akin to a jacket zipper.
246+
247+We have three related arms to look at next, `coder`, `encoder`, and
248+`decoder`. `coder` is the foundation of the other two, so we'll look at it
249+first.
250+
251+```
252+ ++ coder
253+ |= [a=tape b=tape]
254+ (~(put by (zipper a b)) ' ' ' ')
255+```
256+
257+`|= [a=tape b=tape]` creates a gate that takes two `tapes`.
258+
259+We use `put by` on the next line, giving it a `map` produced by the `zipper`
260+arm that we created before. This adds an entry to the map where the space
261+character (called `ace`) simply maps to itself. This is done to simplify
262+the handling of spaces in `tapes` we want to encode, since we don't want to
263+shift them.
264+
265+```
266+ ++ encoder
267+ |= [key=@ud]
268+ =/ keytape=tape (rott alpha key)
269+ (coder alpha keytape)
270+ ++ decoder
271+ |= [key=@ud]
272+ =/ keytape=tape (rott alpha key)
273+ (coder keytape alpha)
274+```
275+
276+`encoder` and `decoder` are implemented in terms of the `coder` arm. These gates
277+are essentially identical, with the arguments reversed. They simplify the two
278+common transactions you want to do in this program: producing `maps` that we can
279+use to encode and decode messages.
280+
281+In both cases, we create a gate that accepts a `@ud` named `key`.
282+
283+`=/ keytape=tape (rott alpha key)` creates a `keytape` noun by calling `rott`
284+on `alpha` our `key` input. `alpha` is our arm which contains a `tape` of the
285+entire alphabet.
286+
287+`(coder alpha keytape)`, for `encoder`, and `(coder keytape alpha)`, for
288+`decoder`, produce a `map` that has the first argument as the keys and the
289+second as the values.
290+
291+If our two inputs to `coder` were `"abcdefghijklmnopqrstuvwxyz"` and
292+`"bcdefghijklmnopqrstuvwxyza"` We would get a `map` where `'a'` maps to `'b'`,
293+`'b'` to `'c'` and so on. By doing this we can produce a `map` that gives us a
294+translation between the alphabet and our shifted alphabet, or vice versa.
295+
296+Still with us? Good. We are finally about to use all the stuff that we've
297+walked through.
298+
299+```
300+ ++ shift
301+ |= [message=tape key=@ud]
302+ (operate message key (encoder key))
303+ ++ unshift
304+ |= [message=tape key=@ud]
305+ (operate message key (decoder key))
306+```
307+
308+Both `shift` and `unshift` take two arguments: our `message`, the `tape` that we
309+want to manipulate; and our `key`, the value that we want to shift our message
310+by.
311+
312+`shift` is for encoding, and `unshift` is for decoding. Thus, `shift` calls the
313+`operate` arm with `(operate message key (encoder key))`, and `unshift` makes
314+that call with `(operate message key (decoder key))`. These both produce the
315+final output of the core, to be called in the form of `(shift.caesar msg key)`
316+and `(unshift.caesar msg key)` at the bottom of the program.
317+
318+```
319+++ operate
320+ |= [message=tape key=@ud encoder=(map @t @t)]
321+ ^- tape
322+ %+ turn message
323+ |= a=@t
324+ (~(got by encoder) a)
325+```
326+
327+`operate` produces a `tape`. The `%+` rune allows us to pull an arm
328+with a pair sample. The arm we are going to pull is `turn`. This arm
329+takes two arguments, a `list` and a `gate` to apply to each element of the
330+`list`.
331+
332+If we then give our arm Caesar's famous statement, and get our left- and
333+right-ciphers.
334+
335+```
336+> +caesar "i came i saw i conquered" 4
337+["m geqi m wea m gsruyivih" "e ywia e ows e ykjmqanaz"]
338+```
339+
340+Now, to decode, we can put either of our ciphers in with the appropriate key and
341+look for the legible result.
342+
343+```
344+> +caesar "m geqi m wea m gsruyivih" 4
345+["q kium q aie q kwvycmzml" "i came i saw i conquered"]
346+
347+> +caesar "e ywia e ows e ykjmqanaz" 4
348+["i came i saw i conquered" "a usew a kso a ugfimwjwv"]
349+```
350+
351+### Exercises
352+
353+
354+1. Take the example generator and modify it to add a second layer of shifts.
355+
356+2. Extend the example generator to allow for using characters other than a-z.
357+
358+3. Build a gate that can take a Caesar shifted `tape` and produce
359+possible unshifted `tapes`.