Skip to content

Instantly share code, notes, and snippets.

@cscotta
Created October 5, 2009 05:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cscotta/201918 to your computer and use it in GitHub Desktop.
Save cscotta/201918 to your computer and use it in GitHub Desktop.
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