index.md (3796B)
1 --- 2 title: "OTP: a Language-Agnostic Programming Challenge" 3 date: 2015-01-26T00:00:00+00:00 4 draft: false 5 canonical_url: https://www.viget.com/articles/otp-a-language-agnostic-programming-challenge/ 6 --- 7 8 We spend our days writing Ruby and JavaScript (and love it), but we're 9 always looking for what's next or just what's nerdy and interesting. We 10 have folks exploring Rust, Go, D and Elixir, to name a few. I'm 11 personally interested in strongly-typed functional languages like 12 Haskell and OCaml, but I've had little success getting through their 13 corresponding [animal books](http://www.oreilly.com/). I decided that if 14 I was going to get serious about learning this stuff, I needed a real 15 problem to solve. 16 17 Inspired by an [online course on 18 Cryptography](https://www.coursera.org/course/crypto), I specced out a 19 simple [one-time pad](https://en.wikipedia.org/wiki/One-time_pad) 20 encryptor/decryptor, [pushed it up to 21 GitHub](https://github.com/vigetlabs/otp) and issued a challenge to the 22 whole Viget dev team: write a pair of programs in your language of 23 choice to encrypt and decrypt a message from the command line. 24 25 ## The Challenge 26 27 When you [exclusive or](https://en.wikipedia.org/wiki/Exclusive_or) 28 (XOR) a value by a second value, and then XOR the resulting value by the 29 second value, you get the original value back. Suppose you and I want to 30 exchange a secret message, the word "hi", and we've agreed on a secret 31 key, the hexadecimal number `b33f` (or in binary, 1011 0011 0011 1111). 32 33 **To encrypt:** 34 35 1. Convert the plaintext ("hi") to its corresponding [ASCII 36 values](https://en.wikipedia.org/wiki/ASCII#ASCII_printable_code_chart) 37 ("h" becomes 104 or 0110 1000, "i" 105 or 0110 1001). 38 39 2. XOR the plaintext and the key: 40 41 Plaintext: 0110 1000 0110 1001 42 Key: 1011 0011 0011 1111 43 XOR: 1101 1011 0101 0110 44 45 3. Convert the result to hexadecimal: 46 47 1101 = 13 = d 48 1011 = 11 = b 49 0101 = 5 = 5 50 0110 = 6 = 6 51 52 4. So the resulting ciphertext is "db56". 53 54 **To decrypt:** 55 56 1. Expand the ciphertext and key to their binary forms, and XOR: 57 58 Ciphertext: 1101 1011 0101 0110 59 Key: 1011 0011 0011 1111 60 XOR: 0110 1000 0110 1001 61 62 2. Convert the resulting binary numbers to their corresponding ASCII 63 values: 64 65 0110 1000 = 104 = h 66 0110 1001 = 105 = i 67 68 3. So, as expected, the resulting plaintext is "hi". 69 70 The [Wikipedia](https://en.wikipedia.org/wiki/One-time_pad) page plus 71 the [project's 72 README](https://github.com/vigetlabs/otp#one-time-pad-otp) provide more 73 detail. It's a simple problem conceptually, but in order to create a 74 solution that passes the test suite, you'll need to figure out: 75 76 - Creating a basic command-line executable 77 - Reading from `STDIN` and `ARGV` 78 - String manipulation 79 - Bitwise operators 80 - Converting to and from hexadecimal 81 82 *** 83 84 As of today, we've created solutions in [~~eleven~~ ~~twelve~~ thirteen 85 languages](https://github.com/vigetlabs/otp/tree/master/languages): 86 87 - [C](https://viget.com/extend/otp-the-fun-and-frustration-of-c) 88 - D 89 - [Elixir](/elsewhere/otp-ocaml-haskell-elixir/) 90 - Go 91 - [Haskell](/elsewhere/otp-ocaml-haskell-elixir/) 92 - JavaScript 5 93 - JavaScript 6 94 - Julia 95 - [Matlab](https://viget.com/extend/otp-matlab-solution-in-one-or-two-lines) 96 - [OCaml](/elsewhere/otp-ocaml-haskell-elixir/) 97 - Ruby 98 - Rust 99 - Swift (thanks [wasnotrice](https://github.com/wasnotrice)!) 100 101 The results are varied and fascinating -- stay tuned for future posts 102 about some of our solutions. [In the 103 meantime](https://www.youtube.com/watch?v=TDkhl-CgETg), we'd love to see 104 how you approach the problem, whether in a new language or one we've 105 already attempted. [Fork the repo](https://github.com/vigetlabs/otp) and 106 show us what you've got!