- #!/usr/bin/env ruby
- def pattern_generator(length, set = ('A'..'Z').to_a + ('a'..'z').to_a + ('0'..'9').to_a)
- parts = []
- signal_set = set.slice!(0, set.length / 4)
- set.each {|a| set.each {|b| set.each {|c| signal_set.each {|d|
- return parts[0, length].join if parts.length > length
- parts << a << b << c << d
- }}}}
- return "Out of combinations"
- end
- def pattern_gen(set = ('A'..'Z').to_a + ('a'..'z').to_a + ('0'..'9').to_a)
- signal_set = set.slice!(0, set.length / 4)
- set.each {|a| set.each {|b| set.each {|c| signal_set.each {|d|
- yield a
- yield b
- yield c
- yield d
- }}}}
- end
- def digitize_sets(length, sets)
- state = Array.new(sets.length) {0}
- rev_sets = sets.reverse
- result = []
- while result.length < length do
- carry = false
- state.length.times {|i|
- state[i] += 1 and carry = false if carry
- if state[i] >= rev_sets[i].length then
- state[i] = 0
- carry = true
- end
- }
- raise "Exhausted sets" if carry
- (state.length-1).downto(0) {|i|
- result << rev_sets[i][state[i]]
- }
- state[0] += 1
- end
- return result[0, length].join
- end
- def digitize_sets2(length, sets)
- parts = []
- rev_sets = sets.reverse
- combinator_output = Proc.new {|pre|
- parts.concat(pre)
- return parts[0, length].join if parts.length > length
- }
- combinators = [combinator_output]
- sets.length.times {|i|
- combinators.push(Proc.new {|pre|
- rev_sets[i].each {|p|
- combinators[i].call(pre + [p])
- }
- })
- }
- combinators[-1].call([])
- return "Out of combinations"
- end
- def pattern_generator2(length, set = ('A'..'Z').to_a + ('a'..'z').to_a + ('0'..'9').to_a)
- signal_set = set.slice!(0, set.length / 4)
- sets = [set, set, set, signal_set]
- return digitize_sets(length, sets)
- end
- def pattern_generator3(length, set = ('A'..'Z').to_a + ('a'..'z').to_a + ('0'..'9').to_a)
- signal_set = set.slice!(0, set.length / 4)
- sets = [set, set, set, signal_set]
- return digitize_sets2(length, sets)
- end
- require '/opt/metasploit3/msf3/lib/rex/text.rb'
- def pattern_generator4(length, set = ('A'..'Z').to_a + ('a'..'z').to_a + ('0'..'9').to_a)
- signal_set = set.slice!(0, set.length / 4).join
- set = set.join
- sets = [set, set, set, signal_set]
- return Rex::Text::pattern_create(length, sets)
- end
- require 'benchmark'
- def benchmark(length = 1024*1024)
- template = pattern_generator(length)
- Benchmark.bm do |x|
- x.report { puts template == pattern_generator(length) }
- x.report { puts template == pattern_generator2(length) }
- x.report { puts template == pattern_generator3(length) }
- x.report { puts template == pattern_generator4(length) }
- end
- end