Skip to content

Instantly share code, notes, and snippets.

@rtraschke
Last active August 29, 2015 14:25
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rtraschke/f15b47ce07f261fff8d2 to your computer and use it in GitHub Desktop.
Save rtraschke/f15b47ce07f261fff8d2 to your computer and use it in GitHub Desktop.
Encouraged by a tweet by Alice Maz (https://twitter.com/alicemazzy/status/623774654772170752), here's my Erlang version of "how to crack a simple crypt" exercise.
-module(magic).
-export([crack/1]).
crack(BaseH) ->
Base = hex_string_to_bytes(BaseH),
Scores = lists:sort([ {score(Base, I), I} || I <- lists:seq(0, 255) ]),
{_, Best_Key} = lists:last(Scores),
<< <<(C bxor Best_Key)>> || C <- Base >>.
score(Base, Poss_Key) ->
lists:sum([ maps:get(C bxor Poss_Key, frequencies(), 0) || C <- Base ]).
hex_string_to_bytes(Hex_String) when is_binary(Hex_String), size(Hex_String) rem 2 =:= 0 ->
[ binary_to_integer(Hex, 16) || <<Hex:2/bytes>> <= Hex_String ].
% Taken from http://norvig.com/mayzner.html "Letter Counts", using percentages, plus 5% for a space.
frequencies() -> #{
$E => 12.49, $e => 12.49,
$T => 9.28, $t => 9.28,
$A => 8.04, $a => 8.04,
$O => 7.64, $o => 7.64,
$I => 7.57, $i => 7.57,
$N => 7.23, $n => 7.23,
$S => 6.51, $s => 6.51,
$R => 6.28, $r => 6.28,
$H => 5.05, $h => 5.05,
$ => 5.00, % Special for the space!!!
$L => 4.07, $l => 4.07,
$D => 3.82, $d => 3.82,
$C => 3.34, $c => 3.34,
$U => 2.73, $u => 2.73,
$M => 2.51, $m => 2.51,
$F => 2.40, $f => 2.40,
$P => 2.14, $p => 2.14,
$G => 1.87, $g => 1.87,
$W => 1.68, $w => 1.68,
$Y => 1.66, $y => 1.66,
$B => 1.48, $b => 1.48,
$V => 1.05, $v => 1.05,
$K => 0.54, $k => 0.54,
$X => 0.23, $x => 0.23,
$J => 0.16, $j => 0.16,
$Q => 0.12, $q => 0.12,
$Z => 0.09, $z => 0.09
}.
@rtraschke
Copy link
Author

And here's how you can run it:

~/tmp $ erl
Erlang/OTP 17 [erts-6.3] [source] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

Eshell V6.3  (abort with ^G)
1> c(magic).
{ok,magic}
2> magic:crack(<<"1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736">>).
<<"Cooking MC's like a pound of bacon">>
3> 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment