generator.rb 1.78 KB
Newer Older
1 2 3 4
#!/usr/bin/env ruby
# frozen_string_literal: true

require 'digest'
5
require 'leveldb'
6

7
@buffersize = 10000
8
nthreads    = 20
9

10 11 12
@md5db    = LevelDB::DB.new 'md5.db'
@sha1db   = LevelDB::DB.new 'sha1.db'
@sha256db = LevelDB::DB.new 'sha256.db'
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47

# Define our read buffer
@buffer = SizedQueue.new @buffersize

# Function to constantly fill our read buffer
def fill_buffer
  File.open('passwordlist.txt', 'r').each_line do |line|
    @buffer.push line.strip
  end
end

# Function to constantly drain our read buffer
def process_buffer(b = [])
  loop do
    password = @buffer.pop
    break if password.nil?

    b.push(
      password: password,
      md5:      (Digest::MD5.hexdigest password),
      sha1:     (Digest::SHA1.hexdigest password),
      sha256:   (Digest::SHA256.hexdigest password)
    )

    # Submit if we've filled our buffer
    if b.size == @buffersize
      submit_results b
      b.clear
    end
  end

  # Submit a partially filled buffer if we're at the end
  submit_results b unless b.size.zero?
end

48 49 50


# Submit calculated hashes to leveldb
51
def submit_results(results)
52 53 54 55 56 57 58 59 60 61 62 63 64 65
  # A little progress indication
  puts results.first

  md5b    = @md5db.batch
  sha1b   = @sha1db.batch
  sha256b = @sha256db.batch
  results.each do |r|
    md5b.put    r[:md5],    r[:password]
    sha1b.put   r[:sha1],   r[:password]
    sha256b.put r[:sha256], r[:password]
  end
  md5b.write!
  sha1b.write!
  sha256b.write!
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
end

# Fill password buffer
producer = Thread.new { fill_buffer }

# Start processing passwords
consumers = []
nthreads.times do
  consumers.push(Thread.new { process_buffer })
end

# Wait for producer to finish
producer.join
puts 'No more passwords in file'

# Signal workers to finish
nthreads.times do
  @buffer.push nil
end

# Wait until all workers are done
consumers.each(&:join)
puts 'All done!'