Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save redterror/f4156ff4f617a7dd27bdf226fc5451d5 to your computer and use it in GitHub Desktop.
Save redterror/f4156ff4f617a7dd27bdf226fc5451d5 to your computer and use it in GitHub Desktop.
Ruby dropped-key generator, for when your broken keyboard loses 1+ keys while typing a password
#!/usr/bin/env ruby
#
BASEWORD = ARGV[0] || raise("No baseword specified")
base_chars = BASEWORD.split('')
rv = []
(1..(base_chars.length - 1)).each do |permutation_len|
possible = base_chars.permutation(permutation_len).to_a
filtered = possible.find_all do |chars|
# A word is legal if it doesn't violate the ordering of the original letters, e.g.
# BASEWORD: foobar OK: oobar oob ooba NOT: rab roo abf
if chars.length == 1
true
else
# For every character being tested, we should be able to find it as we scan along
# the baseword, starting at the position of the character in the set we're testing.
# E.g. BASE: foobar TEST: fbr - we want to find 'f' at position 0, 'b' at position 1 or later,
# and 'r' at position 2 or later
legal = true
last_pos = 0
chars.each_with_index do |c, idx|
#puts "testing: #{c} from #{chars.join('')}"
pos = base_chars[0..-1].index(c)
if pos.nil?
legal = false
break
elsif pos < last_pos
legal = false
break
else
last_pos = pos
end
end
#puts "legal: #{legal} - #{chars.join('')}"
legal
end
end
rv += filtered.collect{|chars| chars.join('')}
end
rv << BASEWORD
puts rv.join("\n")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment