Last active
August 29, 2015 14:27
-
-
Save dela3499/a0282209602e92aa105a to your computer and use it in GitHub Desktop.
Decode messages where letters are just shifted (i.e 'a' becomes 'b', 'b' becomes 'c', and so on.) You can run this by pasting the code into http://elm-lang.org/try
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Html exposing (Html, Attribute, text, toElement, div, input) | |
import Html.Attributes exposing (..) | |
import Html.Events exposing (on, targetValue) | |
import Signal exposing (Address) | |
import StartApp.Simple as StartApp | |
import String | |
import List | |
import Graphics.Element exposing (show) | |
import Char | |
import Dict exposing (Dict) | |
main = | |
StartApp.start { model = "", view = view, update = update } | |
update newStr oldStr = | |
newStr | |
modifiedGetShiftedStrings string = | |
let shiftedStrings = getShiftedStrings string |> List.tail | |
in case shiftedStrings of | |
Just x -> x | |
Nothing -> [""] | |
view : Address String -> String -> Html | |
view address string = | |
let shiftedStrings = | |
modifiedGetShiftedStrings string |> List.map createView | |
in | |
div [bgStyle] | |
[ div [] | |
([ input | |
[ placeholder "Secret Message Goes Here!" | |
, value string | |
, on "input" targetValue (Signal.message address) | |
, myMainStyle | |
] | |
[] | |
] ++ shiftedStrings) | |
] | |
createView string = | |
div [ myStyle ] [ text string ] | |
myMainStyle = | |
style | |
[ ("display", "block") | |
, ("margin-left", "auto") | |
, ("margin-right", "auto") | |
, ("margin-top", "25px") | |
, ("margin-bottom", "45px") | |
, ("width", "90%") | |
, ("height", "40px") | |
, ("padding", "10px 10px") | |
, ("font-size", "1em") | |
, ("text-align", "left") | |
, ("background-color", "White") | |
, ("color", "Black") | |
, ("opacity", "1") | |
, ("vertical-align", "middle") | |
] | |
myStyle : Attribute | |
myStyle = | |
style | |
[ ("display", "block") | |
, ("margin-left", "auto") | |
, ("margin-right", "auto") | |
, ("margin-top", "25px") | |
, ("width", "90%") | |
, ("height", "40px") | |
, ("padding", "10px 10px") | |
, ("font-size", "1em") | |
, ("text-align", "left") | |
, ("background-color", "#232F47") | |
, ("color", "white") | |
, ("vertical-align", "middle") | |
] | |
bgStyle : Attribute | |
bgStyle = | |
style | |
[ ("background-color", "#000F2E") | |
, ("padding", "25px") | |
, ("height", "100%") | |
] | |
{-- Module exposing (getShiftedStrings) --} | |
alphabet = "abcdefghijklmnopqrstuvwxyz" | |
-- Return list of integers from start to end (not including end) | |
range: Int -> Int -> List Int | |
range start end = | |
if start < end | |
then start :: (range (start + 1) end) | |
else [] | |
-- Apply function to input n times, building up a list of results | |
applyN: (a -> a) -> a -> Int -> List a | |
applyN f x n = | |
List.scanl (\_ y -> f y) x (range 0 n) | |
-- Pair elements from each of two lists | |
zip xs ys = | |
List.map2 (,) xs ys | |
-- Return True if letter, False if special character. | |
isLetter: Char -> Bool | |
isLetter char = | |
char | |
|> Char.toLower | |
|> String.fromChar | |
|> \x -> String.contains x alphabet | |
-- Return new list with each element replaced by the one that | |
-- follows it. Last element is replaced by first. | |
rshift: List a -> List a | |
rshift xs = | |
case xs of | |
head::tail -> tail ++ [head] | |
[] -> [] | |
-- Return dict where keys are from provided | |
-- given list and values from shifted list. | |
getShiftMap: List comparable -> Dict comparable comparable | |
getShiftMap xs = | |
zip xs (rshift xs) |> Dict.fromList | |
-- Dict mapping each letter of the alphabet to the next. | |
letterMap: Dict Char Char | |
letterMap = | |
let lowercase = String.toList alphabet | |
uppercase = List.map Char.toUpper lowercase | |
lowerMap = getShiftMap lowercase | |
upperMap = getShiftMap uppercase | |
in Dict.union lowerMap upperMap | |
-- Given a letter, return next letter in alphabet. | |
shiftLetter: Char -> Char | |
shiftLetter letter = | |
let shiftedLetter = Dict.get letter letterMap | |
in case shiftedLetter of | |
Just x -> x | |
Nothing -> '_' | |
-- Return next letter in alphabet unless special character. | |
shiftCharacter: Char -> Char | |
shiftCharacter char = | |
if isLetter char | |
then shiftLetter char | |
else char | |
-- Shift every letter in string forward one. | |
shiftString: String -> String | |
shiftString string = | |
String.map shiftCharacter string | |
-- Return all 26 shifted versions of string | |
getShiftedStrings: String -> List String | |
getShiftedStrings string = | |
applyN shiftString string 25 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
One improvement to this would be to highlight common bigrams. This should make valid English stand out.
This could be purely visual, or you could assign a score to each string, then show only the top scorers, or perhaps color each string in proportion to its score.