Created
October 21, 2017 12:49
-
-
Save ysbaddaden/fccf87d4ca22082c7d645b9f547a9713 to your computer and use it in GitHub Desktop.
Search for collisions and display distribution (libsdl2) of hashes for a list of patterns (e.g. words, uuids, numbers, ...) from STDIN
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Requires https://github.com/ysbaddaden/sdl.cr | |
require "sdl" | |
# Depends on the Crystal::Hasher implementation. | |
# Adjust to match the type of `"".hash` | |
alias HashType = UInt64 | |
word_count = 0 | |
maximum = 0 | |
collisions = 0 | |
print_collisions = ARGV.any?(&.==("--collisions")) | |
hashes = Hash(HashType, Array(String)).new | |
while word = STDIN.gets | |
word_count += 1 | |
hash = word.hash #.to_u64 | |
hashes[hash] ||= [] of String | |
hashes[hash] << word | |
end | |
hashes.each do |hash, words| | |
next if words.size == 1 | |
puts "COLLISION: #{words.join(' ')}" if print_collisions | |
maximum = words.size if words.size > maximum | |
collisions += 1 | |
end | |
minimum_hash = hashes.keys.min | |
maximum_hash = hashes.keys.max | |
puts " WORDS = #{word_count}" | |
print " COLLISIONS = #{collisions}" | |
print " (1:#{maximum - 1})" if collisions > 0 | |
puts | |
puts " SPAN = #{maximum_hash - minimum_hash} (#{minimum_hash}..#{maximum_hash})" | |
puts "\nPress 's' to take a screenhost, 'q' to quit." | |
# create GUI | |
SDL.init(SDL::Init::VIDEO) | |
at_exit { SDL.quit } | |
window = SDL::Window.new("Distribution", width = 800, height = 600) | |
renderer = SDL::Renderer.new(window) | |
pixels = width * height | |
ratio = HashType::MAX / pixels.to_f | |
# clear image | |
renderer.draw_color = SDL::Color[255, 255, 255, 255] | |
renderer.clear | |
# render each hash as a point in image | |
renderer.draw_color = SDL::Color[255, 0, 0, 255] | |
hashes.each_with_index do |(hash, words), index| | |
pixel = hash / ratio | |
y = (pixel / width).to_i | |
x = pixel.remainder(width).to_i | |
renderer.draw_point(x, y) | |
end | |
# display distribution | |
renderer.present | |
format = window.surface.format | |
buffer = Bytes.new(width * height * format.bytes_per_pixel) | |
loop do | |
case event = SDL::Event.wait | |
when SDL::Event::Quit | |
break | |
when SDL::Event::Keyboard | |
if event.sym.q? | |
break | |
end | |
if event.sym.s? && event.type.keyup? | |
# save screenhost | |
renderer.read_pixels(SDL::Rect[0, 0, width, height], format, buffer) | |
screenshot = SDL::Surface.from(buffer, width, height, format) | |
screenshot.save_bmp("screenshot.bmp") | |
puts "Saved screenshot.bmp" | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment