Workshop: Building the Unbreakable Code Whose Breaking Won WWII

Summarized using AI

Workshop: Building the Unbreakable Code Whose Breaking Won WWII

Aji Slater • November 14, 2024 • Chicago, IL • Workshop

Workshop Summary: Building the Unbreakable Code Whose Breaking Won WWII

In this engaging workshop hosted at RubyConf 2024, Aji Slater delves into the history and technology of the Enigma machine, a critical component of World War II cryptography. The workshop emphasizes how the Enigma machine operated through object-oriented programming (OOP), illustrating how its features can be emulated through modern coding practices in Ruby.

  • Introduction to the Enigma Machine:

    • The Enigma machine was larger than a typewriter and encoded messages using a series of rotors and switches, making it difficult to decipher.
    • German communications utilized this device to secure military communications, while British code-breakers operated from Bletchley Park, where thousands worked to crack its codes, significantly shortening the war.
  • Technical Functionality of the Enigma:

    • The machine used electrical circuits to encrypt messages, turning user input into ciphered output through physical and symmetrical mechanisms of the rotors and a reflector.
    • It employed both substitution ciphers and complex rotational systems to ensure there were 150 quintillion possible settings.
  • Lessons in Object-Oriented Programming:

    • Slater draws parallels between the physical Enigma machine and programming principles. He outlines OOP concepts, including:
    • Single Responsibility Principle: Classes should encapsulate distinct functionalities without overlapping responsibilities.
    • Abstraction and Encapsulation: These principles help manage complexity in changes, promoting flexible and maintainable design.
    • Dependency Injection: To decouple classes, making the codebase cleaner and maintenance easier.
  • Workshop Activities:

    • The hands-on section encouraged participants to engage directly with coding the Enigma emulator, applying the OOP principles discussed. Aji encouraged exploring concepts through a series of tests, enabling participants to understand how changes propagate through the code smoothly.
    • Key components such as the keyboard, rotors, and lamp board were modeled as individual classes, emphasizing collaborative interactions where instances send messages to one another rather than having rigid dependencies.
  • Conclusion:

    • The workshop concluded with an emphasis on the practical applications of the discussed principles, encouraging participants to explore further developments, such as adding a plugboard which operates before the rotors to enhance encryption complexity.
    • Aji invited participants to explore this fascinating area of cryptography and coding further, highlighting the historical significance and modern relevance of the Enigma.[Music]

This workshop provided a blend of historical insight, practical coding experience, and a solid understanding of OOP principles, focusing on the unbreakable code that played a crucial role in altering the direction of a world conflict.

Workshop: Building the Unbreakable Code Whose Breaking Won WWII
Aji Slater • November 14, 2024 • Chicago, IL • Workshop

After the last carrier pigeon but before digital encryption algorithms, there was the Enigma machine. An ingenious piece of pre-atomic age technology encoded German military secrets during World War II, baffling code-breakers with mere physical rotors, and switches, without elliptic curves or private keys.

Delve into object-oriented programming and bring the Enigma machine back to life with an emulator built in Ruby. Use Test Driven Development to unravel the secrets of this nigh-unbreakable cipher device, witness OO principles unlock its mysteries, discover the power and versatility of the patterns we use as developers and how they mirror the Enigma's inner workings.

RubyConf 2024

00:00:15.920 how's everybody's uh conference going so far good
00:00:23.439 yeah cool all right
00:00:31.400 yeah so I like long titles that are almost tongue twisters so this is the unbreakable code who's breaking one
00:00:36.719 World War II and because it's a workshop I got to add another word so I'm very excited it's building the unbreakable C
00:00:42.000 who's breaking one World War II um so H as as Mina said my name is
00:00:52.800 AI I work at a place called thoughtbot and today we're going to be
00:00:58.120 working with enigma uh just kind of a baseline to see where we're all at who here has heard of the
00:01:04.280 Enigma machine nice cool and know about the place Bletchley Park little bit
00:01:12.080 great so um we're all operating with some shared understanding I'm going to briefly go through the story and kind of
00:01:18.920 the functionality of the Enigma machine so you may have learned that in the 1930s and 40s there was a war involving
00:01:27.280 many nations and peoples across the globe so many in fact they called it a World War it was the second of its
00:01:37.200 kind the particulars of the conflict are not what we're going to discuss today if you're interested in the period I
00:01:43.640 believe there have been a few movies and TV shows even books where you can find out
00:01:53.719 more just a few
00:02:00.840 for our purposes today all that's important is that you know that on posing sides of the conflict were Germany and the United
00:02:10.280 Kingdom and at the time longdistance communication was done in Morse code
00:02:15.879 over radio and could be intercepted by your opponents in much the same way that we intercept radio stations in our cars
00:02:23.480 the messages needed to be encrypted so the German solution for
00:02:29.400 encryption was this the Enigma machine not that much bigger than a typewriter
00:02:34.599 Enigma would encipher a given message before it was sent over the
00:02:40.040 airwaves the receiver of the message would also have an enigma given the same settings that encoded the transmission
00:02:46.560 they Could reconstruct the original message the British solution for
00:02:52.640 decrypting was this Bletchley Park housed at this estate in buckinghamshire
00:02:58.680 was Britain's GC C and CS government code and Cipher School their work was
00:03:04.519 kept secret until the 1970s but several thousand men and women
00:03:09.599 mostly women mostly college aged were tasked with cracking the German enciphering
00:03:16.040 system so if you know of Bletchley the story you've likely heard is his this is
00:03:21.560 Alan touring of the touring test touring machines touring patterns the negative
00:03:27.080 proof of the anid problema or maybe you've seen him on the 50b
00:03:35.120 Note building in the work of Polish code breaker Marian rusi and his precursor
00:03:40.319 machine called bmba tring realized that a quirk of the
00:03:45.480 Enigma wiring could be exploited and designed a special- purpose computational Engine That Was Made Real
00:03:51.040 by the engineering Brilliance of Harold Keane and the British tabulating machine
00:03:57.000 company after incorporating a crucial insight by English mathematician Gordon
00:04:04.720 Welshman bletch ley's secret weapon was Christen christened bomb on 108 cacais
00:04:12.319 rotating drums bomb crunched through 17,576 possible Enigma settings in just
00:04:19.600 20 minutes depending on who you asked the work at Bletchley shortened the war by
00:04:26.639 two to four years and if you're interested in hearing more about what it was like to be a part of
00:04:33.280 bletch ley's operation I would recommend the Secret Lives of code Breakers by Sinclair
00:04:40.720 McKay so the Enigma was operated by German Communications agents working in pairs one to operate the keyboard
00:04:48.280 entering the message as a key was pressed the corresponding letter would light up on the lamp board and re be
00:04:54.520 written down by the second it worked like this a simple electronic circuit if
00:05:00.039 you're unfamiliar with this type of thing uh think of the wire as a tube that carries electricity that's close enough for our what we're doing today
00:05:06.960 when the switch is down the signal flows when that signal touches a light it will
00:05:13.479 illuminate now imagine that there are more of these simple circuits 26 of them in all A to B A to a b to B and so
00:05:24.000 on if the connections between the key and the light are changed
00:05:32.120 then the signal would be encoded you press the a key and B lights up knowing
00:05:37.960 what letters were connected you'd be able to decode it as well that's the job of enigma's encryption mechanism it
00:05:44.160 physically swaps the electrical connection between the key and the light so maybe you've made a code like
00:05:51.199 this before when one letter is replaced by another like this it's known as a
00:05:56.960 substitution Cipher but no matter how much the key is scrambled substitution ciphers are
00:06:03.199 trivial to break Enigma was more the heart of the enigma's
00:06:08.800 encryption engine are several
00:06:16.360 rotors each had 26 electrical contacts on each side and could be turned to set
00:06:22.520 the machine at any of those positions internally a wire goes from a
00:06:30.000 contact on one side to a different contact on the
00:06:36.240 other so the signal might come in to index zero on the right side and be
00:06:41.400 wired to index 8 on the left then 2 to 21 3 to 14 and so
00:06:48.400 on if it remained as a simple substitution Cipher it would be just as easy to
00:06:56.879 decode so Enigma accepted three rotors each with different internal
00:07:02.400 connections and there weren't only three rotors but a set of five to choose from
00:07:07.680 and those five could be entered in any order for 60 possible
00:07:13.360 combinations and when mounted on the internal spindle the rotor's 26 connection points lined up and a signal
00:07:19.280 would be sent through them coming in from the keyboard we switched to different indexes by each rotor in
00:07:27.879 turn oops and after three rotors came a special symmetric rotor called a
00:07:33.120 reflector here if one becomes 10 10 becomes one after passing through the
00:07:39.000 reflector the signal would be carried back on a different path of
00:07:48.159 connections this is how Enigma both encrypted and decrypted because the path of the signal is symmetrical typing the
00:07:55.080 cipher character will return the original but no matter how many times letter is changed it's weak if a always
00:08:02.120 becomes e so the rotors rotated after each character the signal
00:08:09.400 Taking A New Path through the same key pressed twice in a row would yield two different encoded
00:08:17.000 letters techniques that make a substitution Cipher therefore uh easy to break uh they rely on repetition and
00:08:23.400 therefore they're useless now a key that changes not once a day not once a message but every keystroke
00:08:30.960 and they didn't all rotate at the same speed the second wheel wouldn't advance until the first one made a full
00:08:36.279 Revolution and so on
00:08:43.039 whoops back there we go that means Enigma is a polyalphabetic cipher with new key every letter based on the
00:08:49.920 starting settings so each rotor has 26 positions there are three rotors makes
00:08:56.760 17,576 possible starting positions for any given combination of three
00:09:02.240 rotors 60 different possible rotor combinations means 1,
00:09:08.200 54560 possible settings permutations but the German military
00:09:13.279 enigmas had another layer of encryption that commercial versions did not at the front of each device was a plug board
00:09:20.519 with a connection for each letter up to 10 combinations could be made with short
00:09:25.560 jumper cables cables that would change the signals value between the keyboard and
00:09:31.360 the rotor mechanism effectively making small arbitrary changes to the cipher
00:09:37.839 key in order for the German military to be all speaking the same Cipher a chart
00:09:42.880 would be sent out from high command prescribing which settings should be used on a given day essential
00:09:48.399 coordination because only by sharing the same starting settings would agents be able to communicate the chart included
00:09:55.399 which of the five rotors to use and in which order the starting positions of
00:10:00.480 the rotors and the 10 pairs of plugboard
00:10:05.800 connections combining all of these options takes the possible settings to an astronomical
00:10:11.120 150 million million million portable electromechanical
00:10:17.680 encryption equivalent to a 67 bit encryption key Enigma has a practical link to early
00:10:24.959 Computing history and because of the events of its time we can directly connect Enigma and bletchly to what we
00:10:31.040 do and why we are here it's a remarkable object and that's a key word for today
00:10:37.880 object because Enigma will be our platform to explore principles of objectoriented programming oop
00:10:46.440 oop a strength of which is said to be how it models the real world but objects
00:10:51.639 in the real world are very different than objects in a code base Enigma on the other hand is a physical device it
00:10:59.480 has moving Parts actual objects that each perform a part of the larger Hole
00:11:05.200 by sending messages along a wire to other objects if the image were're supposed to
00:11:12.240 have of oop as object sending messages will Enigma might as well be its mascot
00:11:17.680 we can recreate this mechanism in code without abstracting our conception of an object beyond
00:11:24.720 recognition because we could literally hold in our hands the pieces of an encryption
00:11:30.240 algorithm so let's go big right from the start with two truths of software
00:11:36.920 development requirements will change and this is good if nothing needs to change
00:11:42.240 there probably aren't any users and we need to find another job and we will never know less than we
00:11:50.040 do right now because we don't know how things will change and it's frustrating when we
00:11:56.760 can't make changes right when a new feature request comes along long and we can't deliver it or we can't deliver it
00:12:02.440 fast because it's too hard to implement that's an awful feeling right
00:12:07.839 we don't want to be there but if we don't know anything and it's all going to change how do we build anything at
00:12:15.880 all objectoriented design is one strategy to do just that oh design is
00:12:22.720 about making change Easier by managing dependencies so what principles might we
00:12:32.440 explore single responsibility principle we'll gather together the things that change for the same reasons and separate
00:12:39.480 those that change for different reasons abstraction will manage the
00:12:44.760 complexity of implementation by substituting a more easy to reason about
00:12:51.360 representation excuse me encapsulation an object's internal data should change
00:12:56.440 on that object's own terms dependency inversion conventional
00:13:04.199 architecture would have utility modules low level ones consumed by higher level ones but will invert this thinking and
00:13:11.199 increase reuse from top to bottom through interfaces and the open closed principle
00:13:18.760 an object should allow Its Behavior to be extended without modifying its own
00:13:25.320 code all of this in service of small simple objects sending
00:13:34.240 messages question so far doing good
00:13:39.839 great okay A little quick Poll for me uh we're kind of out of the like talkie bit and we're going to be doing more of the
00:13:46.160 workshopy bit now um so raise your hand if you know or you can Define how you would use at least one of these phrases
00:13:53.240 at least cool so keep your hand up if there are two that you would know
00:14:00.759 about three all five now let's switch it up if you're
00:14:06.360 not familiar or comfortable with any of them raise your hand okay all right so uh everybody of
00:14:14.639 course is welcome uh but I do think you'll that you'll get more out of the workshop if you're on the lower number
00:14:20.279 end of that Spectrum but I hope that we're going to have some fun together uh today on hack day and well I think
00:14:27.160 Enigma also is a fun small project to build when you're picking up a new language try to build this little toy
00:14:34.560 app in the idioms of the new language that you're learning and know that's how I use it and I keep coming back to it so
00:14:41.160 it's something to that at least should be something to take away even if o is you're complete in total jam
00:14:48.320 already so how are we going to work um this also is the GitHub repo URL for the
00:14:56.000 U the repo to clone down Hotel Wi-Fi's been pretty good so far but I do have like physical copies if we need it um
00:15:03.199 this will mostly just save you some typing but how are we going to work uh yeah so everybody should get the repo uh
00:15:09.839 if you want to start from an empty folder that's great we're not going to go into too much detail about writing the tests specifically so you might not
00:15:17.000 have those uh along but if you want to follow along any level of participation
00:15:22.240 with the repo perfectly good uh I'm going to code I'm going to
00:15:27.440 talk a little bit and you're welcome to use that time how you work the best listening and watching following along
00:15:33.600 typing in your editor checking out commits from the repo as we go along whatever's your
00:15:39.519 jam and at least twice I will stop up here after going over some Concepts and
00:15:45.240 you'll have time to work out the next steps for yourself try your own solution think about the oo principles that we've
00:15:51.480 gone over and I'll be around for questions and help and whatnot and you can take breaks and things like that
00:15:58.360 then after that I'm going to come back up here show yall how I did it and we'll sort of loop that until we're out of
00:16:04.759 time code code and talk code and no talk
00:16:10.399 repeat um so if you got questions or concerns as we go and you think they might be helpful to someone else in the
00:16:15.959 group raise them we're all in this together um the only risk is me losing my train of thought and I have no doubt
00:16:22.360 that that's going to happen pretty much anyway so I do reserve the power to resend that
00:16:28.440 right at at any point without explanation but I think we'll be okay and I also reserve the power to
00:16:34.480 rafo any question rafo is borrowed from an author I love who borrowed it from another author who I don't know and it
00:16:40.880 stands for read and find out it's when a fan asks a question that is so spot on it's about to be covered in the material
00:16:48.880 anyway good questions great essentially we're just
00:16:55.800 going to mob pair on this little challenge together uh so let's
00:17:04.400 start now I want to mirror
00:17:19.280 you okay and the display is different so we're going to do
00:17:25.199 that okay cool no don't want to close
00:17:31.400 that awesome so if you've got the repo down make sure that you can check out initial
00:17:39.919 commit so we get started let me fire up my iPad here how is the font size do we need to
00:17:47.039 go bigger I know the tables are the best place to be small okay
00:17:55.480 great looking better better cool good
00:18:08.200 aesome load it there we go cool um okay so uh the initial commit
00:18:15.200 there's not really much here yet um it's just kind of getting us started but the
00:18:20.840 one that might be interesting is wiring. RB uh because these are the arrays for
00:18:26.960 the rotors that we'll be using you'll have to like come up with your own on the fly if you don't have that or anything um these are the actual
00:18:34.360 positions for the World War II Army Enigma rotors so those first four five
00:18:40.280 are the the rotors that would go in the Enigma machines the etw rotor is the
00:18:46.200 init Wala which is the entrance rotor that's basically just the alphabet and the ukw is
00:18:55.240 theala which are the reflectors remember those are special because they have to
00:19:00.400 be symmetrical going each way but the other rotors do
00:19:05.720 not cool um so as we're talking about these
00:19:10.799 kind of things a lot of language that we use while we're talking about oh talking about code modules uh we kind of like
00:19:16.679 personify code modules a little bit right they know things they talk to each other they have collaborators and so if
00:19:23.760 one of those is kind of fuzzy you don't know really what we're talking about when we say one of those I would like to stop and and kind of unpack that a
00:19:29.600 little bit so that we're all on the same page so if uh one of those phrases come up and I don't stop and kind of talk
00:19:36.159 about it a little bit then we'll unpack it together cool does anyone who is furiously typing
00:19:44.480 down these arrays want me to keep this up for a second cool all right
00:20:05.200 already I didn't think live coding would fail so
00:20:17.640 fast oh yeah I didn't have that tag
00:20:24.960 cool oh goodness cool um so we're going to start with a
00:20:31.799 couple of tests we're going to use mini test which is the Ruby's built-in testing framework um if you're not too
00:20:38.280 familiar with it all you have to do is require mini test auto run at the top of the file and use kind of a the mini test
00:20:45.760 convention and inherit from mini test test so first few tests here are kind of
00:20:52.440 starting out as that substitution Cipher right that a doesn't equal a and that
00:20:59.480 yeah A and B don't go to the same thing basically so we'll run these tests oops
00:21:07.120 just by Ruby and the name of our file they failed we
00:21:15.320 haven't written any code yet so if they passed I'd be
00:21:20.919 worried ah I probably down to like
00:21:27.200 18 yeah uh yeah it should be like there there's not anything uh super complicated or
00:21:33.360 anything going on in here so and if you want to challenge yourself with a different Ruby or you want to use the one that you use at work like
00:21:44.200 awesome cool all right so I'm G to open
00:21:50.600 up Enigma RB I've got a cipher method here which is what I'm going to be calling uh our entry into enciphering
00:21:58.320 here so we're thinking about how the Enigma machine works there are some basic parts
00:22:04.679 there's the keyboard that like takes the input and turns it into the electrical signal we've got the rotors which are
00:22:11.240 our Cipher key changes the letters uh Enigma Ed three so we're going to model that here um let's see I think I've got
00:22:19.240 a commit for this though
00:22:34.640 cool okay yeah so I've got the alphabet here that we can work with uh we've got uh a character coming
00:22:42.080 in and we're turning it into the index on that alphabet array that's kind of I'm thinking about that like the
00:22:47.799 keyboard right it's taking the input in and it's turning it into our electrical signal we've got uh a couple of our
00:22:54.120 rotors this is using those arrays from the wiring B and then we're going to put it back uh
00:23:03.120 using the alphabet again we're taking that index and we're switching it back to a character so that the person who is
00:23:09.360 reading the lamp board uh is going to be able to write that down
00:23:15.360 so uh I'm using the array method at here
00:23:21.320 uh and this is uh this is instead of doing something like rotor
00:23:26.760 3 index right so these are equivalent but I just think
00:23:32.919 the kind of at for this example makes it a little more clear as we're going along that uh you're sending a message this
00:23:40.360 index through to that
00:23:46.640 array cool that's also actually equivalent to I don't know if Drew uh did anything like this here
00:23:54.000 but you can do that too if you want but uh I think the at is is a little cleaner
00:24:00.039 than dot square brackets cool all right so we have now
00:24:07.480 the uh the three parts the keyboard the rotors the lamp board we're going to run
00:24:12.679 those tests
00:24:18.000 again they pass okay still pretty easy substitution
00:24:24.279 Cipher so we've got some green tests though while our tests are green we're
00:24:29.720 going to refactor and one of the first things that I want to kind of uh use and talk
00:24:35.120 about is dry Dr y That's don't repeat yourself everybody's familiar with this
00:24:42.200 yeah um so I think a lot of the times the way that it's sort of taught to us and the way that we sort of first
00:24:48.559 interact with that it means merge any repeated code but I think we should take a look
00:24:54.240 at the single responsibility principle to help us decide what repeated code
00:24:59.360 should be merged the single responsibility principle talks about a module being responsible to one and only
00:25:06.720 one
00:25:13.720 actor um another wording for the single responsibility principle is like we had before gather things that change for the
00:25:20.000 same reasons separate the things that change for different reasons so this file has four of those at method calls
00:25:28.480 and we could extract a method right to uh take away some of these repeated um
00:25:34.760 array method calls it also might allow us to be like a little more descriptive about what's
00:25:41.399 going on here right rather than just like a bar array method so if we made like
00:25:47.559 translate um we could let's see we're going to need to have our rotor we're
00:25:54.960 going to have to have our index and then we'll return Rotor at
00:26:03.120 index and now which of these uh I may have kind of given away a little bit
00:26:08.640 calling it rotor but like which of these do you think that we're going to collapse which of these are going to be
00:26:15.039 the same thing
00:26:20.080 so it's all just variable assignment or return value that is uh changing a value
00:26:26.039 based on an index and an array the alphabet array the rotor array it's doing the same sort of thing but if we
00:26:31.640 change the way that we represent the cipher key like if it wasn't an array anymore if it was a hash would all four
00:26:38.320 of these change they wouldn't right the alphabet one would stay the same because we're
00:26:44.760 changing the cipher key we're not changing the alphabet and the way that that's going to work so the concept of
00:26:49.840 those purposes are a little bit different so if we
00:27:02.320 why is RO one not in oh because I took it out of the file if we're going to do our
00:27:13.559 translate I always feel like it's the Heisenberg uncertainty principle like I can type fine except when people are
00:27:24.960 observing right okay we've got translate now we're using our rotors and we were
00:27:30.120 passing in our indexes let's make sure that our tests still pass okay thank God
00:27:38.279 uh so we have kind of collapsed together these things um that are going to move
00:27:44.679 in unison right we've created a single source of Truth here and that's really what dry is kind of getting at we want
00:27:51.519 to collapse all of the things so that we have just one place to change it if something's going to need to go and
00:27:56.840 change if we have three ATS there like we had before and we need to update that because we made our hash and we it's
00:28:04.600 this example is a little contrib for it but you only change two of them then you've got problems and everything and
00:28:09.960 if you put all four of them in and you need to change for one reason but not
00:28:15.200 the other then you've got to extract the abstraction that you've already put together so you're making extra work for yourself in the
00:28:26.039 future cool good so far yeah all right I
00:28:32.559 hot um so single responsibility also applies at the class level uh as well as
00:28:39.039 in the the kind of code as you're going along and so what's our Enigma responsible for here uh we've got a
00:28:45.880 couple of different things going on we've got the input translating to an index we've got the
00:28:52.840 ciphering uh and then we've got the index going back into the output so if any of these changed like we wanted to
00:29:00.120 OCR an image of a letter and pass it in then should that go in Enigma and would
00:29:06.399 like the Enigma class code have to change for that it would right because this this translation is happening right
00:29:12.799 inside the Enigma class and so we can separate out those responsibilities by
00:29:18.640 making some collaborator classes collaborator is one of those those kind of words uh we're talking about just
00:29:24.880 different code modules that work together is essentially what col collaborators are so let's uh let's separate out those
00:29:34.799 responsibilities uh yeah because oop is all about architecting for future change by mitigating dependencies and our
00:29:41.600 dependencies are right here baked into Enigma Enigma has to change if those dependencies change so how can we
00:29:47.559 insulate Enigma from having to
00:29:54.919 update go to another commit and uh we could type it out too if that would be
00:30:00.240 more helpful for everybody but let's go here nope that is
00:30:05.480 the wrong key that's the one cool all right so we've changed this
00:30:12.399 up a little bit uh we've still got our translate method that we were using before but now we're going to extract
00:30:18.480 some of the uh functionality that we had right in line and we're going to make
00:30:23.960 some new classes we've got a keyboard class and a lamp board class because I'm thinking about our domain right we're
00:30:30.320 not doing this in a vacuum I'm thinking about the Enigma machine how are we going to model the Enigma machine it's like oh there's a keyboard that does
00:30:36.320 that part lamp board that does that part and gave me some names right off the bat um we are and I know probably some
00:30:44.360 of you are cringing at this but we'll get there we'll get there um we are making an instance variable for that
00:30:50.600 keyboard for that lamp board and if we go take a look at either of these
00:30:55.639 classes they're pretty simple because we had the one thing that was going on for
00:31:01.200 now uh we took that out we put it into its own file it can have its own tests
00:31:06.840 if it changes this process like we need to use a different alphabet or something that alphabet's no longer baked into the
00:31:12.919 Enigma it's kind of separated out we've uh separated those concerns we've separated those
00:31:19.399 responsibilities so this is a step in the right
00:31:25.080 direction looks pretty similar but they are in different directions right one is going from letters to numbers and so
00:31:31.919 you're indexing and uh another one is the the other way around um so now the changes in either
00:31:39.480 of these conversion processes are able to stay on their own classes and their own
00:31:45.720 files oh okay cool we're already at the first
00:31:54.720 mission I mean I yeah cuz unless you knew that the setup was that you
00:32:00.760 were changing it into like an alphabet of emojis to be a further level of encryption right but if you had the same
00:32:06.120 alphab like you could right the use case is round yeah exactly yeah they have to
00:32:11.919 be right yeah it's hard to Morse code uh
00:32:17.279 Unicode for emojis anyway so
00:32:28.919 cool okay so if you check out the commit that is called first Dash
00:32:42.720 Mission and look at the Enigma tests so we've got some new tests in here so we
00:32:49.159 are going to add the uh repeated character changing into
00:32:54.320 a different character because right now as it is built you send in a it'll send back whatever but then if you send in a
00:33:00.720 again it'll give you the same letter all over again and so we need to add a
00:33:06.080 mechanism that will advance those rotors right because we're thinking of those rotors turning um you don't need to get
00:33:12.880 super complicated into the like uh full rotation advances the next one unless you're you're you know fully ready to go
00:33:19.720 after that then by all means do um so
00:33:24.840 the the job right now is we'll give you a few minutes um and make this test
00:33:31.960 pass think about how uh we extracted some classes before likely this is
00:33:38.559 something that you've done plenty of times and uh yeah cool I'm gonna turn this off for a
00:33:46.200 sec and uh give you a few minutes I wrote down 20 but I don't know that we'll end up using all that we'll see
00:33:58.000 um well there was initial Dash commit had the like empty files and then this one with these tests is first-h Mission
00:34:06.080 I'll write that up here good call
00:34:13.280 out all right there that'll give you those three tests no co-pilot go
00:34:21.800 away um that'll give you these three tests here and that commented out one at the bottom if you want to uh make it uh
00:34:29.280 encipher and uh a phrase if you've done the first little part and you want to go forward with that then you can uncom at
00:34:35.639 that and and move along
00:34:43.000 sweet yeah there's a tag so yeah get checkout first Das
00:34:53.359 Mission this third one will not yeah
00:35:06.960 yeah no problem not only can you keep Enigma in your head it can still pretty much all fit on the screen here
00:35:25.560 too how are we doing feeling like I can talk a little bit more as as we're wrapping up if you're
00:35:33.440 still going
00:35:38.960 so we've got our test that expects that uh we're going to have a behavior of an
00:35:44.160 an advancing rotor so that two repeated letters are not the same Cipher text so
00:35:50.160 um the kind of thought that we're putting into play here is I think we're really uh leaning into encapsulation and
00:35:57.960 abstraction because take a look back here at our um
00:36:04.720 Enigma where we extracted our keyboard and our lamp board so before we made the
00:36:10.319 keyboard and the lamp board Enigma had the alphabet in it it also used the at
00:36:16.599 message and what that means is that our Enigma class depended on those rotors
00:36:23.359 being uh arrays right so the at method would have had to change like we talked
00:36:29.400 about if we were using hash or something different uh so that's that's kind of what I mean when I
00:36:36.480 say that Enigma knows about something being an array right there's something in Enigma that is
00:36:43.280 assuming one of its collaborators is a certain way has a certain method is doing a certain thing and the way that
00:36:50.119 we can kind of separate out and allow for a little more freedom a little uh
00:36:55.640 easier changes is to instead of relying on specific things like that that would
00:37:03.400 require a certain thing is to kind of put a layer in between right and abstracting it away that's what we're
00:37:09.200 talking about when we're abstracting so something like making a new class that
00:37:14.520 would have a method and you'd call that uh that method instead of just assuming
00:37:19.839 it it's an array because then whatever class you have as long as it has that method Enigma knows how to work with it
00:37:26.880 right that duct typing we're doing all of our uh fantastic uh Ruby things and
00:37:33.560 so with the keyboard and the lamp board uh pulled out Enigma doesn't know about
00:37:38.839 the alphabet you can make it whatever alphabet that you want yeah uhhuh yeah oh abstraction I
00:37:45.640 wrote that I talked about that great um so we've made a nigma into a
00:37:52.200 simpler uh object it's sending messages to its collaborators rather than
00:37:58.000 um telling its collaborator what to do it's saying hey keyboard I need you to convert this rather than keyboard you
00:38:04.599 convert this by doing X Y and Z so let's take a look at
00:38:13.160 how I went to do this so we know that we want to extract a rotor class
00:38:25.040 right uh I've got some test here that are in the next commit if you
00:38:32.160 want to get them as well
00:38:37.599 let's Okay so uh now what we've got is this is I'm writing the test first and
00:38:44.240 I'm kind of uh thinking about how I want the interface how I want to be using the
00:38:50.079 rotor and what that's going to look like once I've written it so we're going to have a rotor and we're going to be able
00:38:56.280 to pass in the key right so we can use this class for any of the different rotors so we'll
00:39:03.359 have that as an argument and knowing that if we uh are going to send in zero
00:39:09.960 based on this key that we have right now I'm going to expect one back and so on and so
00:39:19.839 forth all right okay check out rotor position good good notes good notes me
00:39:36.079 except maybe
00:39:43.880 not great all
00:39:49.079 right don't know that this will be as readable but let's see not great
00:39:57.960 cool so let's take uh a look first just at the kind of initial
00:40:04.040 um initial pass at a rotor class so we're just extracting it right we're not
00:40:09.119 uh moving on to the advancing part of the logic yet we just want to set up this relationship between the rotor and
00:40:15.200 the Enigma classes and so I'm just taking what the rotors were doing in Enigma already and making that in
00:40:22.200 another class and in a collaborator like this so we're passing in the wiring which would be the same as that we were
00:40:27.319 we're just using that array directly we're going to pass in that array like we saw in our tests and then we're calling add so it's the same exact thing
00:40:34.960 that we were doing an enigma but we're removing the specificity from Enigma and putting the specificity into the rotor
00:40:43.319 class and how does that change our Enigma again we'll get to
00:40:50.119 this um so in much the same way that we did with the keyboard and the lamp board because this is kind of the skill this
00:40:56.040 is the thinking that we had just used we're going to use the same uh apply the same steps the same logic we're going to
00:41:01.400 have rotor 1 2 and three they're going to be uh instances of our new class and
00:41:06.960 we're setting them up like we had before with rotors 1 two and three come on
00:41:13.720 in the water's fine um and like we uh
00:41:18.920 were doing before we're just kind of moving that same um operation that at we
00:41:24.720 moved it into the rotor class we saw that already and that at is now behind the translate method on the rotor now
00:41:32.079 instead of in the Enigma class so we actually get to remove remember that translate method that was inside Enigma
00:41:38.640 because translate is happening inside our rotors now and so we can just instead of calling that within the
00:41:44.240 Enigma we are sending a message to one of our collaborators to call its translate
00:41:50.400 method but it's still operating the same way right we're not advancing not keeping track of the position of the
00:41:57.599 rotors or anything like that so our
00:42:04.520 test
00:42:10.160 that's is still failing right so this is that failing test that we were uh working to get passing so we need to
00:42:17.280 teach the rotor about how to think about its position and so we'll go into
00:42:24.480 rotor and we are going to make this an instance variable Let's see we want a
00:42:31.920 position and we'll start it out at zero so when you make a new rotor it's just starting right out at that first index
00:42:40.400 so um we are making the RoR the only thing that knows about that position
00:42:45.760 change right now and the rotor is going to handle all of that
00:42:53.000 itself but we're gonna have to end up using that position right now because at we've got this wiring at it's not
00:43:00.800 regarding we're not doing anything with that position so I'm going to make a method called
00:43:07.520 Step adjusted key and we'll have our key
00:43:14.960 rotate thanks
00:43:21.800 mats going to rotate the number of positions that we've got so rotate and
00:43:27.160 instead of D rotate bang it's not modifying our array it's going to give
00:43:32.359 us back a new array with the index is shifted over a certain number and that's
00:43:37.760 that's exactly what we need to do it's even called the thing that the the rotor is doing in Enigma so that's
00:43:44.200 nice the key oh yeah right okay cool I called it wiring over here and key over
00:43:50.400 there thank you pair program
00:43:58.319 cool all right so we're rotating but this position is still not changing right we're not having an accessor we're
00:44:03.480 not letting uh Enigma reach into the rotor class and change that position
00:44:09.240 because it would be the same thing as before right it's specifically telling the rotor how to do its job so we want
00:44:15.480 to uh keep that away from
00:44:21.200 Enigma so we're going to have to update how this translate works well first of
00:44:26.400 all we are going to want to use the step adjusted key instead of the uh just the
00:44:33.640 straight wiring that we've set up let's call it actually let's just
00:44:40.119 make that the same all
00:44:46.079 around um yeah so uh now it's going to be using
00:44:51.800 that um position but there's still nothing that is moving the position of this rotor
00:44:57.839 and so we'll we'll have it advance but now we want to make sure that we uh return this this so let's do
00:45:06.160 Cipher text equals and then so we can bring our Cipher text back out okay and this is
00:45:14.079 modeling the way that the Enigma worked it would Advance after the key press so really you could you could have
00:45:20.760 that go any way that you want if you don't like that intermediate variable yeah sure Advance first
00:45:27.760 uh we're going to need that advanced method now
00:45:36.839 though
00:45:43.359 nope just add one just mooving along one tick and we need to control for the end
00:45:50.559 of the thing so it falls off of the end
00:46:00.359 typing so deliberately great so if we've fall uh
00:46:07.240 fallen off the end of our key we'll jump back and start over from the beginning especially for that first rotor that's
00:46:13.079 turning after every press that's probably going to happen quite often so we want to make sure that we're controlling for
00:46:19.040 that okay we're advancing we are keeping
00:46:24.240 uh track of our position we are using that position to modify our key as we
00:46:29.480 translate so I'm expecting that those tests are going to
00:46:37.920 pass ding ding ding
00:46:43.440 nice um I know there were some some issues and stuff getting started for some folks how many people got that test
00:46:48.800 to pass start going along nice cool awesome
00:46:57.640 all right so with all of this here we've
00:47:04.599 added this advancing we've added this position we have updated that so that
00:47:09.720 our test is uh showing us that we're operating a little bit more like the real Enigma machine we are uh setting up
00:47:17.920 that 17,576 different positions instead of just 26 so we're on the
00:47:23.920 way well actually right now it's still just 26 but we'll get there and we did all of that without Enigma
00:47:31.160 having to change Beyond extracting the rotor class right so we've changed the
00:47:37.000 behavior we've extended the behavior of our rotor class but nothing here in Enigma had to be modified and so if you
00:47:43.920 can think about this in all of the different ways that your requirements might change one module might sort of change and need to do the uh at a
00:47:50.640 different way because of new business rules or whatever is going on if they're
00:47:55.920 encapsulated and they're separated through abstractions properly it's going to be an easy change that's not going to
00:48:01.559 spread across multiple files have to update tests everywhere that sort of thing and so this is one of the ways
00:48:07.160 that these oo principles are protecting ourselves for the future making change
00:48:12.839 easier through managing
00:48:21.359 dependencies yeah and another thing that uh another kind of term and uh way that
00:48:26.440 we talk talk about um the interaction between collaborators in an O ways we
00:48:32.079 talk about coupling right and so coupling is a term that means that two
00:48:38.000 modules are they don't have their own responsibilities right they work really closely together and a change in one is
00:48:45.319 going to require a change in the other so where we had the Enigma directly
00:48:50.559 accessing array methods that would be tightly coupled to that array class but now here we're Loosely coupled with our
00:48:58.520 rotors um I like to personify uh my code modules so we've got our small simple
00:49:04.160 objects sending messages and it's the way we talked about it before Enigma is asking a rotor hey can you translate
00:49:10.599 this so if you think about that uh I play board games with my friends I would
00:49:15.880 say like hey can you bring over that board game we played instead of hey can you go over to your living room pull out that game we played from the third shelf
00:49:22.480 go outside and put it in your car before you come over I don't care how they got that game
00:49:27.520 over here right uh that's their responsibility and it's that same sort of thing that we're uh creating with
00:49:32.720 these two classes all right so the next thing that
00:49:39.599 we're going to do we're advancing and we want to encipher a whole phrase We want
00:49:45.000 to be able to pass in a long string so that we are not just doing it one at a
00:49:50.480 time right it's the Enigma machine had to do it that way we're in code it can be a little bit easier for us so we're
00:49:58.200 going to modify this Cipher method here a little
00:50:10.079 bit we're going to separate out all of the characters again we have a nice
00:50:16.079 little method that'll do that for
00:50:23.400 us we got multiple enciphered characters over the message characters we will do
00:50:38.119 map this is all kind of the same thing that we want to do move that over
00:50:55.000 great oops nope still did the same thing that's
00:51:01.480 fine all right so that's you know fairly easy change or
00:51:06.960 fairly um not very complex change to make we're just doing the same thing that we were already doing for one
00:51:13.240 letter it was working for us so we're going to do it over every single letter that we're passing in in our message
00:51:19.839 let's take a look at that make my test file
00:51:28.200 comment it and I think I've got the right setup here but I might
00:51:33.359 not I've got a oh yeah okay all right I was on the
00:51:40.079 Fly thought I could adapt for the small screen size but I ruined it anyway thank
00:51:52.520 you nice
00:52:04.119 okay that might just be because I uh no let's
00:52:12.319 see uh yeah I can't remember where I changed that in here but um so we are uh
00:52:17.920 enciphering a phrase we're not like erroring out or anything like that but um we are operating a little bit
00:52:24.839 differently than the the actual Enigma did because every single one of our
00:52:30.040 translate calls is advancing our rotor once and so every single one is still
00:52:35.839 moving in lock step we're changing the key every letter but there's only 26 of them now instead of our 177,000
00:52:43.000 possibility right that's where my notes end so like we're just going going for
00:52:49.359 it is it have state right or theet
00:52:59.760 tical uh it would not be like currently it is right because they're all moving they're all getting the Advan command
00:53:05.960 and so those positions are they're independent but they're all moving kind of in lock step yeah and uh what we need
00:53:13.079 to do is to have one rotor go a full Revolution and then send a message up to
00:53:18.680 the second rotor I've gone a full Revolution we need to move on forward step in advance that
00:53:25.160 one so just discard these for now oh no
00:53:34.040 discard that was
00:53:39.160 terrifying uh ads position and ciphers of phrase I think this
00:53:47.880 is okay so um we've updated a little bit here because like we were saying our
00:53:55.000 rotors are kind of communicating across each other now so they can't just manage
00:54:01.599 their own State because they need to be sent a message from the rotor in front of it have you moved to full Revolution
00:54:06.839 okay great then I need to have you moved to full Revolution no then I'm going to stay put so that needs to move up into
00:54:13.640 kind of a scope above right where is the place that can see all three of those rotors that's in our Enigma our Enigma
00:54:20.880 is the orchestrator right now right so it can see all of our rotors and it's
00:54:26.000 going to handle the advancing so what I've got here is we've still got our um message we have uh the map same as it is
00:54:36.200 and what am I doing here yeah and Cipher index so we've extracted because this is
00:54:41.599 starting to get a little complex I've extracted a method here in Cipher index and if we go down here this looks like
00:54:48.640 what we had before we're Shifting the index translating through rotor Shifting the index translating it through the
00:54:53.839 rotor same as before then we come long we're going to advance the rotors
00:54:59.079 because Enigma is uh taking on this respons should not uh taking on this
00:55:04.720 responsibility and so we've got this Advanced rotors method here too so if rotor one Advance if rotor 2 Advance
00:55:11.720 rotor three advance so there's obviously something more going on with advance than we had before right so we've moved
00:55:20.000 this responsibility up a level into Enigma and let's take a look at how
00:55:25.160 we've changed rotor to do do it so the same as before position is our
00:55:30.880 instance variable inside rotor it's still not something that we are allowing someone to edit directly right we didn't
00:55:38.200 see that Enigma is saying rotor position plus equals 1 we're still doing that
00:55:43.960 inside the rotor we've still encapsulated the responsibility for directly changing that variable within
00:55:50.440 the rotor instances um this all looks the same
00:55:55.559 here with the transl but we've um moved the advance uh We've modified the advance a little bit that we're going to
00:56:01.960 be sending back the message true or false if it has completed a full rotation so now Advance is being called
00:56:08.880 from the outside and it's getting some feedback from the rotor the rotor uh sending up have I completed a full
00:56:15.359 Revolution essentially the rest uh Remains the Same so step adjusted key is
00:56:20.520 working on translate in just the same way so if we take this Advanced method
00:56:26.000 and we go back to where it's called in the Enigma we can see how this uh this if
00:56:32.960 statement is working so if the rotor one Advance has gone a full Revolution it's
00:56:38.000 going to return true and will advance rotor 2 and if rotor 2 has gone a full Revolution
00:56:44.480 itself we'll go in advance rotor 3 isn't good follow
00:56:52.760 along great so let's see if I set these tests up
00:56:57.920 right or
00:57:03.039 not no because there's a typo I remember this one one of these commits has a typo that's supposed to be a v but I typed G
00:57:10.319 so let's fix that so watch out for
00:57:22.880 that okay great so um basically went manually into
00:57:29.079 hello world and went through all my rotors to make sure that it was coming out in the phrase that I expected and here we go we're asserting on the actual
00:57:36.640 like manually checked although who am I um that those strings are what we're
00:57:42.839 going to expect if it's operating the way that I want it to be correctly advancing the way that we just set
00:57:53.559 up okay but what's changed in our
00:58:01.839 Enigma some of this responsibility has bled back up into Enigma right like it
00:58:07.839 was so nice before when the rotor was doing all of its stuff itself and Enigma
00:58:13.280 didn't need to know about any of that right we could change rotor we modified it we did the advancing and Enigma
00:58:19.839 didn't have to change its calls to translate at all but now they're coupled
00:58:25.160 again right so they're a little tighter more tightly coupled than they were a moment ago and
00:58:31.839 that's not necessarily a bad thing right coupling is going to happen coupling is what makes a system work right if your
00:58:37.880 code modules are not talking to each other they're probably not doing very much or they're doing everything right
00:58:43.119 in there and you're just working in one file and yikes um yeah so what can we do to get
00:58:54.039 our Enigma back to that kind of clean place where we were where a change in
00:58:59.079 one of these subsystems right the enciphering kind of subsystem what can we do to encapsulate
00:59:06.960 or abstract that away from Enigma well what did we do to encapsulate and extract and uh away the
00:59:15.240 the lamp board the keyboard we made a new collaborator because our Enigma has
00:59:21.160 picked up another responsibility right we had before that
00:59:26.359 was turning letters into indexes then it was doing all of the translate stuff and
00:59:32.319 then it was turning that index back into a letter and we were able to kind of separate out those concerns so that the
00:59:38.520 Enigma was just orchestrating it was just kind of moving things along but now it's moving things along and being the
00:59:46.119 one to advance our rotors right so as I'm thinking about how I want to model
00:59:52.160 this and how I want to extract this and get back to that state that we had a little while ago I'm thinking about the
00:59:58.160 actual Enigma machine so we've got our keyboard it's going in through the rotors it's coming out through the lamp
01:00:03.440 board but there's another part of the mechanism there right there's a spindle
01:00:09.640 that those rotors are sitting on and it's doing the little kind of advancing and moving the rotors along because if
01:00:15.599 you think about it the rotors have their own positioning and everything like that but there's another
01:00:21.240 mechanism that's pushing them along they don't have a little internal motor moving them along so
01:00:26.640 I'm starting to think we've got the orchestration in Enigma and we've got the advancing and kind of the
01:00:32.960 orchestration between the rotors so let's take one of those responsibilities and make it its own
01:00:38.799 class make it its own
01:00:44.799 object let's see do I have a yeah cool let's go take a look at my commits
01:01:00.440 hope this is the one yeah cool Okay so we've got
01:01:06.599 something that looks pretty different now we've removed the rotors from the Enigma
01:01:11.799 completely and this gives us a lot of stuff that we might not have thought about at first before Enigma was locked
01:01:18.720 into three rotors you had to give it three rotors that's all it would work with now because we're in code we don't
01:01:25.400 have to build a bigger physical device we can put in nine rotors we can put in 13 whatever Enigma doesn't care it is
01:01:33.240 just sending a message to its collaborator the spindle could you transform this can you do the cipher for
01:01:39.240 me uh just the same way as asking our friend to do the board game it doesn't care how it's doing that we've separated
01:01:46.520 those concerns so let's take a look through our Cipher method um doing the same map just like we were
01:01:53.599 before uh keyboard is still conver in we're asking our spindle to transform
01:01:59.319 there's only one call to it we're converting back and we're joining so our Enigma class has gotten a
01:02:07.839 lot simpler by removing that complexity out we've abstracted it we talking about
01:02:13.240 before in the slides that abstraction was removing complexity to have an easier to reason about
01:02:21.480 um process or uh thing in its place that's the spindle
01:02:29.680 now cool let's take a look at our spindle and our spindle is going to look really
01:02:36.279 similar to what we were doing in Enigma just the same way that our keyboard our lamp board looked really similar to what
01:02:43.160 we were doing in those steps in the Enigma class we're just starting out by pulling it into a new place we're
01:02:49.640 abstracting that away but the behavior doesn't have to change very much so our spindle
01:02:56.119 currently we're still initializing it with three rotors we are doing the transform the Translating just the same
01:03:03.119 as we were then we're advancing we're using that true false so to do this abstraction nothing in the rotor changed
01:03:10.480 we simplified the Enigma and we put that complexity into the spindle class another thing that I love is that you
01:03:16.279 can write tests about this one specific thing this one part of the process gets a little more test coverage gets a
01:03:22.240 little more reliable in that way that uh adding uh more specific tests can without having to test internals right
01:03:29.640 you're not testing the how of enigma but you're testing the inputs and the outputs of
01:03:37.039 spindle do I have spindle test on here no of course not that'd be that'd be
01:03:42.680 great so I didn't
01:03:49.599 awesome cool let's make sure that those tests still pass
01:03:58.319 okay good awesome let's double check that's BEC because I fixed the typo in this
01:04:04.799 commit too yeah it is great cool questions we're seeing what we're doing
01:04:10.400 we're kind of getting picking up uh picking up the uh the methodologies that we're starting to work with
01:04:16.640 here awesome cool now there's something in
01:04:21.839 here that I've been kind of alluding to as we've been um moving along uh that I
01:04:28.799 was saying that there's something that might be giving some of our uh more experienced programmers like a little a
01:04:35.319 little uh cringe because there's still a lot of coupling going on here we've extracted out these responsibilities but
01:04:42.400 there's coupling between the Enigma and specific classes of its collaborators
01:04:47.920 it's collaborating with a keyboard a lamp board and a spindle but it's only
01:04:53.000 ever collaborating with a keyboard a lamp board and a spindle right it is
01:04:58.279 depending on those three classes specifically so what can we do to
01:05:05.319 abstract and kind of tease those apart we're going to use dependency
01:05:14.839 injection uh let's yeah let's actually we're g
01:05:21.720 to what did I call this Transformer okay so we're going to um pass in some
01:05:28.880 um keyword arguments and this is going to look a little bit
01:05:35.079 different just for now we can keep those uh keyboard
01:05:47.920 Lampard and now there's another way that we know that's gotten a little simpler thing
01:05:56.240 actually do we even need the wiring we don't even need the wiring in here do we oh look at
01:06:04.799 that so instead of having those classes directly in enigmo and coupling those
01:06:11.440 together we've separated that out we've made change easier for ourselves once again because now instead of having to
01:06:18.079 go in and change the keyboard if something needs to update we can give it a different kind of keyboard right the
01:06:25.680 Enigma on the inside doesn't know about specifically how something is being done
01:06:31.240 so you can change how that thing is being done at your will if you might say that the keyboard is going to change
01:06:37.440 well we're going to go change the keyboard but what if you need still need that keyboard for some of your users and
01:06:42.680 a different set of the users need a different keyboard say some need cilc and some need uh kanji different uh uh I
01:06:51.359 don't know how the Japanese enciphering device is completely different but um yeah you can change that up to your
01:06:58.640 heart's uh content so let's take a look at what that makes our
01:07:05.520 um but that does the way that we're using the Enigma is going to have to change for that right everything isn't
01:07:12.520 baked into it I cannot tell where anything
01:07:21.319 is cool yeah all right I did not so so so we're looking at the tests here for
01:07:27.720 enigma and instead of just enigma. new since that initialize has those keyword arguments we're passing in we're using
01:07:34.119 dependency injection we're telling uh Enigma about its dependencies when it's
01:07:39.920 being initialized the the way that Enigma is going to be used is different
01:07:44.960 there are a lot of things that you can do to not have uh this if you think that this makes your do new look messy may
01:07:51.039 there's a lot of complexity going on in there you can have defaults in your enigma things like that but kind of for
01:07:57.200 just straightforwardness um and fitting it all on the screen uh we're going this way here so we're testing basically the
01:08:04.599 same thing but we're initializing our rotors we are uh passing that test rotor
01:08:10.680 into spindle because now spindle uh if we'll take a look at that is doing the same dependency injection that we're
01:08:16.239 doing in Enigma we're decoupling these classes as we go
01:08:21.759 along um yeah I think that that is the majority of what's going on there
01:08:28.759 looking good let's take a look at spindle
01:08:35.359 too yeah okay so um spindle is looking a little bit different here as well so we
01:08:42.480 are um passing in rotors like I said we wanted to get to that place where you can have three rotors you can have five
01:08:47.920 rotors you can have nine rotors anything like that and uh so we're passing them in an array we've got an array of rotors
01:08:54.159 here this is just so that you can have them as uh arguments they'll get splatted into that array and so now our
01:09:00.480 transform is going to look a little bit different we get to use one of my favorite methods but uh one that uh a
01:09:05.839 lot of people are not really fans of I think uh if you if you use it a little bit more it comes easier to reason about
01:09:12.440 but we're reducing so we're taking that array of rotors and we're iterating iterating
01:09:18.040 that uh over and we're kind of passing information along between each iteration so uh we can do translate which is
01:09:26.159 giving us our true false oh wait no sorry that's the advanced step so we're still doing the transformed index but
01:09:31.880 we're doing it in a way that doesn't care about the number of them we're not setting a variable and translating over
01:09:38.600 specifics again we've extracted the specifics away we're reducing over them we're doing the same sort of idea with
01:09:44.920 our Advanced uh step and uh reduce here we are saying if there is a true that
01:09:52.000 comes back from that rot or Advance then we're going to pass that along to the next one to know that it should Advance
01:09:57.800 as well uh what's going on here with the reduce has an
01:10:03.120 argument uh the argument here of true is because we want that first rotor always
01:10:09.880 to advance and so if a rotor needs to have a true from something to tell it to
01:10:14.920 advance if uh the spindle tells the first rotor every single time true then
01:10:20.760 that first rotor is going to advance and it'll pass its uh true falses up the rest of the chain through this
01:10:34.120 reduce good sound nice let's take a look what do we got
01:10:39.679 here we are g a spindle spindle is not depending
01:10:47.640 on cool um and we're taking a look the same way that uh the way that we used Enigma changed uh the way that we're
01:10:54.159 using the spindle is Chang changing to here we've only got two rotors they're a lot simpler than rotor one rotor two
01:11:00.239 rotor 3 the actual Enigma rotors so that we can kind of Reason about it a little bit better uh during our
01:11:07.159 tests and uh we're even mocking out a rotor to make sure that we're as sending
01:11:12.400 the uh the true false from the advance uh the way that we want so we can we can test on that as
01:11:20.760 well so let me see
01:11:27.719 okay so the the sort of last not really last but the the last crucial part of
01:11:34.640 how an enigma operates is you need to be able to send the same the the cipher phrase into it and get the original
01:11:41.880 message back out right and so that is going to require our reflector rotor and
01:11:49.159 that's if you uh check out second mission
01:11:57.159 we should have the tests that we need to do that right here we go this is uh it's
01:12:02.400 updated the um tests to uh work with the way that we've changed the spindle and injected that
01:12:09.840 into the enigmas and everything so they're getting a little bit more complicated as the way that we use the Enigma gets more complicated but the
01:12:16.679 code modules have simplified so we've got this test now of
01:12:22.080 a starting phrase VCT this is and I don't know if my pronunciation is good or bad so we'll
01:12:27.880 just say it's good and move on um this was one of the phrases that uh showed up
01:12:34.679 a lot in messages because German um control would send out a weather report
01:12:41.800 wet brick to veter Brick to uh the field agents as they were going along and so
01:12:47.760 there were some messages they were like let's try this phrase can we find this phrase and that's one of the ways that
01:12:52.840 they would kind of have a hook into encrypting it so we're using that same phrase here we are starting with a V
01:12:59.920 we're ciphering it we're initializing a new Enigma with the same settings
01:13:05.960 because the Enigma we used to encipher it has advanced its rotors a bit we're
01:13:11.400 making a new one starting at the same starting position and we are going to see if our
01:13:17.199 deciphered phrase turns back into the uh the starting phrase
01:13:25.320 all right so um we'll have probably a little bit more time with this one this one's a little more complicated than
01:13:31.239 before but um take a crack at it uh you see here oh one little hint is like I
01:13:37.199 was saying before you could change the keyboard uh and still keep the old keyboard around you don't necessarily
01:13:43.719 need to make a new or change that spindle how it works you can have a reflector spindle that will do
01:13:50.400 that uh back and forth yeah
01:13:59.600 yeah that was uh a great question does the advance happen at the reflector like
01:14:05.239 where does the advance happen so the advancing of the rotors that step uh is
01:14:10.800 going to happen after the lamp board has lit up so like the full process through from key press to lamp board then we'll
01:14:17.800 Advance the rotors once yeah so we've got a lot of
01:14:23.800 questions about how the reflector rotor uh Works to make this
01:14:29.239 symmetrical and so I'm going to try and find that slide um so in the wiring. RB um the
01:14:38.800 reflector rotors are the ukw rotors and whereas rotors 1 2 3 4 5 are
01:14:47.159 essentially randomized you could throw in really whatever indexes you want in
01:14:52.360 there um I just used the ones from the the the World War II rotors because I thought it was cool
01:14:59.920 um what are you doing but the reflector rotor is
01:15:06.440 specific in the way that those numbers are laid out so if you send in a one
01:15:12.199 it'll become a Seven just throw numbers out there but if you send in seven it'll become a one so they they're matched
01:15:19.560 pairs whereas in the other rotors if you sent in a seven it could become a nine
01:15:24.679 but if you sent in a nine it could be a 22 right they're not pointing to each
01:15:29.840 other the way that the uh reflector rotor does
01:15:55.239 see how the the wiring in that last one the reflector
01:16:00.440 rotor they match each other there's kind of only one side to the rotor if you
01:16:05.800 want to think about it that way
01:16:11.400 too and I probably should have made this so that they didn't cross so it would be a little easier to to understand at
01:16:17.320 first glance but you see the way that if you took the path instead of going from
01:16:23.239 a to E if you sent in E it would follow the same path and end up back at a and
01:16:31.600 that's how the encryption decryption with the same setup works so it'll go rotor one two 3 through the reflector
01:16:40.000 rotor 321 and you'll have your your
01:16:48.760 result uh more is there more questions that are kind of coming to your mind as you're trying to grock this cu I know
01:16:55.440 this is can be a little twisty in the yes in the Enigma set up
01:17:02.880 like the the actual machine there's only one reflector rotor um yeah and that
01:17:08.000 one doesn't rotate
01:17:13.280 either yes there were multiple reflector rotors that you could set um and especially like the Army Navy had
01:17:20.960 different ones Al together so again just more wiring possibilities but that one would just kind of sit
01:17:26.639 stationary and make sure that it was
01:17:39.600 symmetrical you're doing two hours would it took me months to do for this talk so you're doing
01:17:46.400 great yeah yeah so the the question is about is the reflect essentially is the
01:17:52.159 reflector the Special Sauce that makes it able to to use the same settings to
01:17:57.719 decrypt and encrypt right so the way it would work is uh every Enigma would know
01:18:04.840 that today we are set to rotors 1 two and three at positions four five and six with this reflector and so you could
01:18:11.360 encode a message so you've got your Cipher text and then someone else would have an enigma set that there's up to 1
01:18:17.400 2 3 4 5 6 in the same way and because of that reflector that's the special uh
01:18:24.000 rotor that makes it symmetrical right and when I mean symmetrical is the a will turn into e
01:18:31.000 and e will turn into a in that particular
01:18:41.760 click yeah exactly so if you you'd receive your Morse code operator would get your your garbled up Cipher text and
01:18:49.239 you would just type those into your Enigma to uh decrypt and have the mess
01:18:55.199 so it was remarkably simple and like just a fantastic idea the the Fatal flaw
01:19:02.880 was also the reflector though because a letter could never become
01:19:08.600 itself because if you see if it's cut has to be symmetrical and has to go both ways the wire can't
01:19:16.800 converge so that mathematically eliminated a whole like tree of
01:19:22.440 possibilities and uh the mathematician at bch Le were able to utilize that and
01:19:28.120 then Turing built a machine that essentially brute forced it and so that
01:19:33.280 was the thing that makes the encryption decryption happen but it was also the thing that made it weak each operation
01:19:39.440 yes correct so the the number of transits through rotors uh in this
01:19:44.560 format of three rotors and a reflector is seven because it'll go one 2 three
01:19:49.800 reflector 3 2 1 so each key press is making it is touching
01:19:55.440 seven times uh rotors rotors seven times different rotors yeah
01:20:03.679 words and probably like a lot of problems that we do at work when you see the solution you'll slap your forehead
01:20:11.040 and say that's so easy but it's not easy to get there
01:20:23.159 so yeah that's a great um thought came up that the test will only pass if you
01:20:29.920 use the ukwa
01:20:34.960 reflector so it is tightly coupled to
01:20:41.840 that okay we've only got a few minutes left so I'm uh going to kind of show you what I did and um there's still so much
01:20:49.400 more that you can do with this Enigma so if you don't have a hack Day project try
01:20:54.679 building that plugboard remember that that will before it even gets to the rotors you can
01:21:00.719 switch individual letter pairs but let's take a look at well I
01:21:06.159 got to get to the right
01:21:13.520 commit cool all right so we've got the reflector spindle that we see right here
01:21:19.560 let's take a look at what is different about the reflector spindle than the spindle on it
01:21:25.840 own so passing in the rotors that's the same we could inherit some of this stuff
01:21:32.199 if we wanted to instead of duplicating this code um but here in our
01:21:39.360 transform we are going through the rotors we're
01:21:45.320 reflecting and then we're reversing through the
01:21:51.080 rotors the only other part of this that's a little Trixie as you see on line 16 we have
01:21:59.159 translate and on line 22 we have adal snart which is a backwards
01:22:06.639 translate because if you think about uh if going from uh what is this
01:22:14.239 right to left is at on an array going
01:22:19.719 from left to right is what index is this at
01:22:25.199 instead of what value is at this Index right so going through the reverse way
01:22:31.040 is the reverse operation on those rotor
01:22:36.880 arrays so if we look at the rotor we've got edles snart the
01:22:44.040 difference is just at versus
01:22:52.120 index I would not just just so you know I would not name that edel snard at
01:22:59.320 work
01:23:09.679 absolutely ah yeah it's just down
01:23:15.480 here so yeah this is again uh like we were passing in specifically a keyboard or specifically rotor one 123 we've got
01:23:23.320 it tightly coupled to this specific rotor in here to use a different reflector rotor the way that this is the
01:23:29.600 reflector spindle class would have to change and so my first tool that I would reach for would be dependency injection
01:23:35.679 like the other ones and uh this is where inheritance on initialize wouldn't work
01:23:40.719 anymore because you'd have to also pass in uh your
01:23:51.000 reflector yeah let's take a look at um so we're looking at
01:23:58.000 whoops this one right here so if you look uh so say we pass in zero we see
01:24:04.920 the value at index Zer is four then if we pass in four at index 4 it's zero so
01:24:12.960 the way the reflector um rotors are different is that they will always be
01:24:18.920 paired the index and the value are paired it's not
01:24:29.840 no I mean it could it could be is right yeah like it it could be as long as they
01:24:35.600 are
01:24:42.480 paired right right no that's yeah that's like a simplified blown out way so that you could see it because if it's a
01:24:49.600 tangle of wires it would be harder to see but yeah yeah uh understood that's good
01:24:59.679 feedback yeah that's how those uh the UK W rotors are are different is that the
01:25:05.040 index and the value always go back to each
01:25:13.280 other yeah and so we're down to uh about just a couple minutes left so I'll kind
01:25:18.840 of leave you with that um I would love to you know extend this with anybody if
01:25:25.239 you want to try building out the uh the plugboard and stuff that'd be a fun project to do um I've always wanted to
01:25:31.719 just like kind of go crazy with this and see what you want to add elliptic curve cryptography to the Transformers great
01:25:38.560 let's do it um so there's there's so much that you can do now that you have all of these things Loosely coupled and
01:25:44.360 working between uh an interface rather than uh knowing about the internals of
01:25:49.480 each of these different steps you can make those steps whatever you want and uh yeah I would I would love to see if
01:25:55.639 you if you do something that just seemed like fun and you wonder if you can do it and you made it work I would love to see
01:26:02.639 it so thank you everybody for being uh guinea pigs at my first ever Workshop
01:26:15.400 um I I think this Enigma thing is uh really super cool so I would uh love if you want to talk about it more or talk
01:26:21.280 about Bletchley or um you know anything at all have a have a great rest of your hack day
Explore all talks recorded at RubyConf 2024
+64