Skip to content

Instantly share code, notes, and snippets.

@postmodern
Created October 5, 2010 06:35
Show Gist options
  • Save postmodern/611125 to your computer and use it in GitHub Desktop.
Save postmodern/611125 to your computer and use it in GitHub Desktop.
Ruby script for enumerating drunq txts.
#!/usr/bin/env ruby
require 'rubygems'
gem 'combinatorics', '~> 0.2.0'
gem 'ffi-hunspell', '~> 0.2.0'
require 'combinatorics/list_comprehension'
require 'ffi/hunspell'
TYPOS = {
'q' => %w[q w s a],
'w' => %w[q w e a s d],
'e' => %w[w e r s d f],
'r' => %w[e r t d f g],
't' => %w[r t y f g h],
'y' => %w[t y u g h j],
'u' => %w[y u i h j k],
'i' => %w[u i o j k l],
'o' => %w[i o p k l ,],
'p' => %w[; o p l ,],
'a' => %w[q w a s z],
's' => %w[q w e a s d z x],
'd' => %w[w e r s d f z x c],
'f' => %w[e r t d f g x c v],
'g' => %w[r t y f g h c v b],
'h' => %w[t y u g h j v b n],
'j' => %w[y u i h j k b n m],
'k' => %w[u i o j k l n m .],
'l' => %w[i o p k l , m .],
',' => %w[o p l , .],
'z' => %w[a s d z x],
'x' => %w[s d f z x c],
'c' => %w[d f g x c v],
'v' => %w[f g h c v b],
'b' => %w[g h j v b n],
'n' => %w[h j k b n m],
'm' => %w[j k l n m .],
'.' => %w[k l , m .]
}
#
# Enumerates over every possible typo of a drunk txt message, in the hopes
# of finding the intended message.
#
# @param [String] mesg
# The drunk txt message.
#
# @param [Hash] options
# Additional options.
#
# @option options [String, Regexp] :space
# The pattern or character deliminating the words of the message.
#
# @yield [possible_mesg]
# The given block will be passed each possibly intended txt message.
#
# @yieldparam [String] possible_mesg
# A possible intended message that was typoed.
#
# @return [Enumerator]
# If no block is given, an enumerator object will be returned.
#
# @example
# drunqtxt('jmiw') { |mesg| puts mesg }
#
# @example
# drunqtxt('jmiw,mwlmwm', :space => ',')
#
def drunqtxt(mesg,options={})
return enum_for(:drunqtxt,mesg,options) unless block_given?
space = (options[:space] || /\s+/)
FFI::Hunspell.dict('en_US') do |dict|
possible_words = mesg.split(space).map do |word|
puts "Bruteforcing #{word}"
possible_letters = word.chars.map { |c| TYPOS[c] }.comprehension
possible_letters.inject([]) do |words,letters|
w = letters.join
words << w if dict.check?(w)
words
end
end
possible_words.comprehension { |words| yield words.join(' ') }
end
end
drunqtxt(ARGV[0]) { |mesg| puts mesg } if ARGV[0]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment