vanityhash [ options ] hexfragment < inputfile
vanityhash --append [ options ] hexfragment < inputfile > outputfile
vanityhash is a tool that can discover data to be added to the end of a file to produce a desired hex hash fragment. It searches a message space and runs a hashing algorithm against the original data plus the appended data to determine if the desired hash fragment is present. vanityhash can run multiple parallel workers to effectively make use of multiple processors/cores/threads, and supports multiple hash digest types (MD5, SHA1, SHA256, etc).
vanityhash can be used to append data to files that are capable of ignoring garbage data at the end of the file (such as ISO images and some types of graphic images), in order to produce a “vanity” hash. vanityhash is fast, as it only reads the base input data once, and then reverts back to that base state over and over while it permeates the search space, rather than hashing the entire source during each permeation.
vanityhash operates on the concept of a “search space”. For example, given a 24-bit search space, vanityhash will run from 0x00000000 to 0x00ffffff, append the 4-byte packed version of each number to the end of the input data, calculate the resulting hash, and search the hash value for the desired hex fragment pattern. A desired hex fragment can be larger than the search space (for example, searching for “abcdef” in a 16-bit search space), but the chances of finding a match reduce drastically the larger the desired hex fragment is.
In its default operation, vanityhash will search the entire specified search space and output all matching results to STDOUT, one result per line, in the form “extradata hash”, where both “extradata” and “hash” are in hex form. When the --append option is specified, this behavior changes. If a match is found, the original input data plus the extra data (in byte form) are outputted, and searching ends after the first successful match. If no matches are found, the original data only is outputted.
- -b bits, --bits=bits
Space to be searched, in bits. Allowed values range from 1 to 64. Default is 24. Search spaces larger than 32 bits require a 64-bit operating system, and a version of Perl compiled with 64-bit integer support.
- -p position, --position=position
The position within the hex hash to look for the desired fragment, in hex digits. The beginning starts at 0. Default is 0. A position that extends the fragment beyond the length of the hash is not allowed.
- -y, --any-position
When enabled, this option will override --position and will return hashes that contain the desired fragment in any position within the hash.
- -s seconds, --progress=seconds
The number of seconds between printing of progress lines, default 5 seconds. A decimal value may be specified. A value of 0 disabled printing progress lines.
- -w workers, --workers=workers
The number of workers to be spawned. Default is 1. Recommended value is the number of logical processors on the running system.
- -d digesttype, --digest=digesttype
The hashing digest type to use. Default is “md5” Allowed values are “md2”, “md4”, “md5”, and "shaN" where N is a valid SHA digest value. “sha1alt” is accepted to use Digest::SHA1 instead of Digest::SHA. Note that for many digest types, the appropriate Perl module must be installed and available.
- -a, --append
When enabled, the original data is outputted back to STDOUT. Then, when/if the first matching hash is found, the data fragment used to produce the matching hash is outputted to STDOUT. STDOUT can then be redirected to another file to produce the modified file.
- -q, --quiet
Normally vanityhash sends a fair amount of status information to STDERR during operation. When enabled, all non-error status information is instead suppressed.
- -?, --help
Print a synposis and exit.
Bugs / Limitations
Search spaces larger than 32 bits require a 64-bit operating system, and a version of Perl compiled with 64-bit integer support.
A block of computed data is added equal to the size of the integer type the search space fits into (1 byte for 8 bits or less, 2 bytes for 9 through 16 bits, 4 bytes for 17 through 32 bits, 8 bytes for 33 through 64 bits), even if the search space could fit into a smaller raw byte block (say, 3 bytes for a 20-bit search space). While this does not reduce (or increase) the possibility of finding a match in a given search space, the extra null byte(s) in the block are technically wasteful.
Extra bytes are packed according to system endianness. Thus, search results will be different between big and little endian systems.
vanityhash should work fine on any POSIX operating system, and has been tested on Linux and Mac OS X. It mostly works with Strawberry Perl for Windows, but crashes at the end. Suggestions to fix this would be welcomed.
vanityhash was written by Ryan Finnie <email@example.com>. vanityhash was inspired by Seth David Schoen's 2003 program, hash_search.