#! /usr/bin/env perl use strict; use warnings; use autodie; use Getopt::Long; use Hash::Util qw(hash_value); my $NUM_COLLISIONS = 1; my $LENGTH = 16; my $REGEX; my $VERBOSE; GetOptions( 'num|n=i' => \$NUM_COLLISIONS, 'length|l=i' => \$LENGTH, 'regex|r=s' => \$REGEX, 'verbose|v' => \$VERBOSE, ) or die "Error in command line options\n"; my $STRING = $ARGV[0] or die "Please supply a string to collide with\n"; my $hash_value = hash_value($STRING); print STDOUT "Finding $NUM_COLLISIONS collisions for '$STRING': '$hash_value'\n"; my @collisions; while ( @collisions < $NUM_COLLISIONS ) { my $random_string = rnd_str( int( rand($LENGTH) ) + 1, 'a' .. 'z', 'A' .. 'Z', 0 .. 9 ); next if $random_string eq $STRING; if ($REGEX) { next unless $random_string =~ /$REGEX/; } print STDOUT "Trying '$random_string': " if $VERBOSE; my $test_hash_value = hash_value($random_string); print STDOUT $test_hash_value, "\n" if $VERBOSE; if ( $test_hash_value == $hash_value ) { push @collisions, $random_string; print STDERR "$random_string $test_hash_value\n"; } } sub rnd_str { join '', @_[ map { rand @_ } 1 .. shift ]; }