Created
October 5, 2009 05:54
-
-
Save cscotta/201918 to your computer and use it in GitHub Desktop.
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 scala.util.Random | |
import scala.actors.Actor | |
import scala.actors.Actor._ | |
import java.security.MessageDigest | |
class HaystackActor extends Actor { | |
val rand = new Random | |
val sha1 = MessageDigest.getInstance("SHA1") | |
// Generates the SHA1 hash of a byte array. | |
def hash(source: Array[Byte]): Array[Byte] = { | |
sha1.reset() | |
sha1.update(source, 0, source.length) | |
sha1.digest | |
} | |
// Returns a random word from a list of words. | |
def randomWord: String = { | |
Haystack.dictionary.apply(rand.nextInt(1000)) | |
} | |
// Generates a random string from a list of words. | |
def generateGuess: String = { | |
var i = 0 | |
var guess = new String | |
while (i < 13) { | |
guess += randomWord | |
i += 1 | |
} | |
// Returns the guess with a trailing space stripped off. | |
guess.substring(0, guess.length - 1) | |
} | |
// Returns a hex string representation of a byte array (Alex Payne) | |
def printHex(digestBytes: Array[Byte]): String = { | |
var hex = new StringBuffer() | |
for (byte <- digestBytes) { | |
val hexByte = byte & 0xFF | |
if (hexByte < 0x10) hex.append("0") | |
hex.append(Integer.toHexString(hexByte)) | |
} | |
hex.toString | |
} | |
// Returns a binary string representation of a byte array (Alex Payne) | |
def bytesToBinary(digestBytes: Array[Byte]): String = { | |
var binary = new String() | |
for (byte <- digestBytes) { | |
var binaryByte = byte & 0xFF | |
var binaryString = Integer.toBinaryString(binaryByte) | |
var size = binaryString.length | |
while (size < 9) { | |
binary += "0" | |
size += 1 | |
} | |
binary += binaryString | |
} | |
binary | |
} | |
def ham(guessHash: Array[Byte]): Int = { | |
var i = 0 | |
var differences = 0 | |
val guessBinary = bytesToBinary(guessHash) | |
while (i < 160) { | |
if (Haystack.sourceBinary.apply(i) != guessBinary.apply(i)) differences += 1 | |
i += 1 | |
} | |
differences | |
} | |
def act() { | |
loop { | |
var guess = generateGuess | |
var guessHash = hash(guess.getBytes) | |
var result = ham(guessHash) | |
if (result < Haystack.bestScore) { | |
Haystack.bestScore = result | |
println(result + " (" + printHex(guessHash) + "): " + guess) | |
} | |
} | |
} | |
} | |
object Haystack { | |
var bestScore = 100 | |
val setup = new HaystackActor | |
val sourceGuess = "string fetch closures reaper pages win32 grove rfc959 standard marking qalqashandi load sccs" | |
val sourceHash = setup.hash(sourceGuess.getBytes) | |
val sourceBinary = setup.bytesToBinary(sourceHash) | |
val dictionary = List("solo ", "flex ", "scalable ", "rubyonrails ", "rails ", "cloud ", "web ", "hosting ", "ec2 ", "aws ", "git ", "3des ", "abbrev ", "accessor ", "actionpack ", "active ", "activereload ", "addon ", "adjoin ", "aes ", "agile ", "ajax ", "alberti ", "algol ", "alias ", "allen ", "allman ", "aloha ", "amazon ", "AMI ", "amp ", "andreessen ", "android ", "apache ", "apple ", "applet ", "apricot ", "ar ", "arcade ", "array ", "assert ", "assoc ", "atbash ", "atkinson ", "awk ", "awsm ", "awstats ", "babbage ", "backus ", "balancers ", "bartle ", "base64 ", "based ", "bash ", "bazeries ", "bdd ", "beck ", "becker ", "behavior ", "behlendorf ", "bell ", "benchmark ", "benchmarks ", "berkeleydb ", "berners ", "beta ", "betas ", "bford ", "bigdecimal ", "bignum ", "bigtable ", "biham ", "bin ", "bina ", "binaries ", "binary ", "bitsweat ", "bizstone ", "blank ", "bletchley ", "block ", "blocks ", "blog ", "blogs ", "boole ", "boolean ", "bot ", "box ", "bricklin ", "bridge ", "brin ", "browser ", "browsers ", "bsd ", "bug ", "bugs ", "build ", "builder ", "builders ", "builds ", "bytesize ", "c10k ", "cache ", "caches ", "caching ", "caesar ", "call ", "camp ", "capistrano ", "cardelli ", "carmack ", "carribault ", "case ", "catalyst ", "center ", "cerf ", "cgi ", "chabaud ", "chain ", "channel ", "chars ", "cheezburger ", "chef ", "chen ", "child ", "chomp ", "chop ", "chore ", "church ", "ci ", "city ", "class ", "classes ", "cleanup ", "clear ", "client ", "clients ", "clone ", "closures ", "cluster ", "clusters ", "cmd ", "cochran ", "code ", "coder ", "codes ", "codex ", "collect ", "collossus ", "colocated ", "colocation ", "combine ", "combines ", "command ", "commands ", "commit ", "commits ", "complex ", "computer ", "computes ", "computing ", "concat ", "config ", "configs ", "console ", "contest ", "controller ", "converge ", "cook ", "cooley ", "core ", "cores ", "count ", "counter ", "counters ", "cows ", "cpu ", "cpus ", "cray ", "creation ", "creator ", "crispin ", "cryptanalysis ", "css ", "csshsh ", "csv ", "cucumber ", "cunningham ", "cvs ", "daemon ", "daemons ", "damgard ", "dastels ", "data ", "db ", "dbfile ", "dbm ", "dclone ", "debug ", "decode ", "decode64 ", "dedicated ", "defect ", "deicaza ", "delayedjob ", "delegate ", "delete ", "demos ", "denmark ", "dependency ", "deploy ", "deployment ", "deprecate ", "des ", "development ", "dhh ", "diffie ", "digest ", "dijkstra ", "dirty ", "disk ", "display ", "div ", "dix ", "django ", "dll ", "dom ", "dongarra ", "driver ", "dry ", "dst ", "ducktype ", "dup ", "dupe ", "dynamic ", "dystopia ", "eager ", "edge ", "editor ", "eff ", "eich ", "eiffel ", "eight ", "eighty ", "elastic ", "element ", "emacs ", "encode ", "encode64 ", "end ", "enebo ", "engine ", "engineyard ", "eniac ", "enigma ", "enum ", "enumerator ", "environment ", "equal ", "erb ", "error ", "escape ", "etc ", "eval ", "event ", "events ", "exception ", "exceptions ", "excerpt ", "excerpts ", "exist ", "exists ", "expert ", "experts ", "expire ", "expo ", "extend ", "ezmobius ", "facets ", "fairchild ", "fastcgi ", "fastxs ", "fcgi ", "fcntl ", "feature ", "fedora ", "feigenbaum ", "ferret ", "fetch ", "file ", "filesystem ", "fileutils ", "filo ", "filter ", "finish ", "fips ", "first ", "fix ", "fixnum ", "fixture ", "flowers ", "floyd ", "flush ", "footer ", "foreign ", "form ", "format ", "formt ", "formula ", "formulas ", "fowler ", "fragment ", "fragments ", "fraser ", "free ", "freebsd ", "freeware ", "freeze ", "friedman ", "front ", "frozen ", "ftools ", "ftp ", "function ", "functional ", "gadget ", "gate ", "gem ", "gems ", "generator ", "generators ", "generic ", "gentoo ", "gets ", "gfs ", "ginsburg ", "github ", "gitignore ", "glob ", "global ", "globals ", "glue ", "godel ", "goldberg ", "golden ", "golub ", "gosling ", "gray ", "greater ", "greenblatt ", "grep ", "grok ", "group ", "groups ", "grove ", "gsub ", "gutmans ", "h1 ", "h2 ", "h3 ", "habtm ", "hack ", "hacker ", "hackers ", "hacks ", "haml ", "hamming ", "handler ", "handlers ", "handling ", "hansson ", "haproxy ", "hash ", "hashing ", "hawkes ", "headers ", "headius ", "heinemeier ", "hejlsberg ", "hellman ", "hello ", "helper ", "hex ", "hexadecimal ", "hibernate ", "hillis ", "hoedown ", "hopper ", "host ", "hosted ", "hosts ", "howcast ", "hpricot ", "href ", "html ", "htonl ", "http ", "https ", "i10n ", "i18n ", "icanhaz ", "icann ", "ichbiah ", "icon ", "iconv ", "id ", "ietf ", "imap ", "include ", "index ", "ingalls ", "inject ", "injection ", "inline ", "inode ", "insert ", "inspect ", "install ", "instance ", "integer ", "integration ", "intern ", "internet ", "internets ", "interpreter ", "interpreters ", "invalid ", "io ", "iphone ", "iphones ", "ipsec ", "irb ", "irbrc ", "is ", "iterators ", "ivarsoy ", "iverson ", "iwatani ", "jacobson ", "jakarta ", "jalby ", "javascript ", "join ", "joshp ", "joux ", "joy ", "jquery ", "jruby ", "json ", "kahan ", "kahn ", "kaigi ", "kapor ", "karpinski ", "kasiski ", "katz ", "kay ", "kconv ", "kemeny ", "kemper ", "kerckhoff ", "kernighan ", "key ", "keyboard ", "kindi ", "king ", "kit ", "knuth ", "koenig ", "koichi ", "korn ", "koster ", "koz ", "kri ", "kurtz ", "label ", "lacida ", "lamport ", "lampson ", "landing ", "last ", "layer ", "layout ", "legacy ", "lehey ", "lemuet ", "length ", "lesk ", "less ", "lib ", "libcrypt ", "library ", "lifo ", "lift ", "lighttpd ", "limit ", "line ", "lines ", "link ", "linus ", "linux ", "lisp ", "load ", "locale ", "locales ", "localize ", "lock ", "locks ", "logger ", "lolcode ", "love ", "lovelace ", "lua ", "macro ", "macromates ", "mailer ", "mailers ", "managed ", "many ", "map ", "maps ", "marking ", "mash ", "master ", "masters ", "match ", "matsumoto ", "matz ", "mccarthy ", "mcdonald ", "mcilroy ", "mckusick ", "md5 ", "memcached ", "memory ", "merb ", "merkle ", "mesh ", "meta ", "metaclass ", "metaprogramming ", "metcalfe ", "method ", "methods ", "mime ", "minam ", "miner ", "minsky ", "mixmax ", "miyamoto ", "mock ", "mocks ", "mod ", "module ", "modules ", "moler ", "mongrel ", "monitor ", "monitoring ", "montulli ", "moolenaar ", "moore ", "moravec ", "morhaime ", "mozilla ", "mri ", "multicore ", "mysql ", "naik ", "named ", "nested ", "netbeans ", "network ", "new ", "newman ", "next ", "nginx ", "nil ", "nine ", "nist ", "nitems ", "node ", "nodes ", "nodoc ", "noradio ", "norton ", "notift ", "nsa ", "nzkoz ", "object ", "objects ", "observer ", "offline ", "oikarinen ", "olson ", "one ", "online ", "open ", "opera ", "opscode ", "optimize ", "optimizes ", "option ", "options ", "order ", "orders ", "oriented ", "oscon ", "oss ", "oswald ", "ousterhout ", "outer ", "output ", "outputs ", "package ", "page ", "pages ", "pair ", "pajitnov ", "papert ", "parameter ", "parameters ", "params ", "parent ", "parents ", "parse ", "parser ", "partition ", "passenger ", "path ", "paths ", "pattern ", "patterns ", "peek ", "peeks ", "penny ", "perform ", "performs ", "perl ", "pgp ", "phoenix ", "php ", "phusion ", "pica ", "pieprzyk ", "pivot ", "pixel ", "plugin ", "poe ", "polybius ", "pop3 ", "pops ", "portable ", "portage ", "postel ", "postgres ", "postgressql ", "private ", "proc ", "process ", "processes ", "procs ", "program ", "programmer ", "programming ", "programs ", "properties ", "proxy ", "pstore ", "puppet ", "puts ", "python ", "qalqashandi ", "quantity ", "query ", "queue ", "rack ", "railsconf ", "railties ", "raise ", "rake ", "rakefile ", "ram ", |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment