VANITYHASH(1)

πŸ“¦ version 1.1, in fedora 43, fedora 44

πŸ’– VANITYHASH πŸ’–

okay bestie, sit down, because vanityhash is literally the hex hash fragment creation tool and i am obsessed with it πŸŽ€


✨ NAME ✨

vanityhash β€” a hex hash fragment creation tool πŸ¦‹


🌸 SYNOPSIS 🌸

vanityhash [ options ] hexfragment < inputfile

vanityhash --append [ options ] hexfragment < inputfile > outputfile

πŸ’… DESCRIPTION πŸ’…

so vanityhash is that girl who will hunt down data you can slap onto the end of a file until the hash comes out looking exactly how you want it. it searches a whole message space, runs a hashing algorithm against your original data plus the extra data it's trying, and checks whether the desired hex fragment is in there. and like, it can run multiple parallel workers so it actually uses all your processors/cores/threads, and it supports a bunch of hash digest types (MD5, SHA1, SHA256, etc). multitasking queen πŸ‘‘

you use it to append data to files that are chill about ignoring garbage at the end (think ISO images, and some types of graphic images) so you can get yourself a "vanity" hash. and the way it's fast?? it only reads the base input data once, then reverts back to that base state over and over while it permeates the search space, instead of re-hashing the whole source every single time. no cap, that's efficient πŸ’«

here's the concept, because it's giving ✨search space✨: say you've got 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 that hash value for the hex fragment pattern you asked for. and yes, a desired hex fragment can be bigger than the search space (like 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. so like, dream big but know the odds πŸ™ˆ

default behavior, real talk: vanityhash searches the entire search space you specified and outputs all matching results to STDOUT, one result per line, in the form "extradata hash", where both "extradata" and "hash" are in hex form.

but when --append is in the mix, everything changes:

  • if a match is found, the original input data plus the extra data (in byte form) get outputted, and searching ends after the first successful match πŸ›‘
  • if no matches are found, the original data only is outputted.

πŸŽ€ OPTIONS πŸŽ€

  • -b bits, --bits=bits β€” the space to be searched, in bits. allowed values range from 1 to 64. default is 24. and heads up: search spaces larger than 32 bits require a 64-bit operating system, plus a version of Perl compiled with 64-bit integer support. so check ur setup before u go big πŸ’€
  • -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, so don't even try it bestie 🚫
  • -y, --any-position β€” when enabled, this overrides --position and returns hashes that contain the desired fragment in any position within the hash. chaotic good energy, honestly 🌈
  • -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. (yes, "disabled", that's the manpage's wording, we're keeping it 😭)
  • -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. so if u got 16 threads, feed the girl 16 workers πŸ‘‘
  • -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 β€” no module, no vibe check ✨
  • -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. it's giving pipeline princess 🫢
  • -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. shhh 🀫
  • -?, --help β€” print a synposis and exit. (yes, "synposis". the manpage said it, so we're saying it πŸ’–)

πŸ¦‹ BUGS / LIMITATIONS πŸ¦‹

okay so, the caveats, because we keep it real:

  • search spaces larger than 32 bits require a 64-bit operating system, and a version of Perl compiled with 64-bit integer support. this one's important, don't skip it ⚠️
  • 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. lowkey wasteful, but not a dealbreaker πŸ’€
  • extra bytes are packed according to system endianness. thus, search results will be different between big and little endian systems. so don't go comparing notes across architectures and getting confused 😭
  • 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 πŸ™

⭐ CREDITS ⭐

vanityhash was written by Ryan Finnie <ryan@finnie.org>. and vanityhash was inspired by Seth David Schoen's 2003 program, hash_search. legends inspiring legends, we love to see it 🫢


bestie reminder: every flag, every default, every byte count and every endianness warning up there is load-bearing. read the warnings. periodt πŸ’…

and that's the whole page, mwah πŸ’– this version of the manual is dated 2010-12-11, it's the VANITYHASH(1) one, and honestly? iconic. go make some pretty hashes 🌸✨

πŸ“¦ where this page comes from