generator.rb 1.78 KB
Newer Older
Cool Fire (HN)'s avatar
Cool Fire (HN) committed
1 2 3 4
#!/usr/bin/env ruby
# frozen_string_literal: true

require 'digest'
5
require 'leveldb'
Cool Fire (HN)'s avatar
Cool Fire (HN) committed
6

7
@buffersize = 10000
8
nthreads    = 20
Cool Fire (HN)'s avatar
Cool Fire (HN) committed
9

10 11 12
@md5db    = LevelDB::DB.new 'md5.db'
@sha1db   = LevelDB::DB.new 'sha1.db'
@sha256db = LevelDB::DB.new 'sha256.db'
Cool Fire (HN)'s avatar
Cool Fire (HN) committed
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
Cool Fire (HN)'s avatar
Cool Fire (HN) committed
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!
Cool Fire (HN)'s avatar
Cool Fire (HN) committed
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!'