synchro / wordhash
Generate hashes in a human-readable format
Requires
- php: ^7.4|^8.0
- ext-hash: *
- ext-json: *
Requires (Dev)
- dealerdirect/phpcodesniffer-composer-installer: ^0.7.0
- ergebnis/phpstan-rules: ^0.15.2
- pestphp/pest: ^0.3.9
- phpcompatibility/php-compatibility: ^9.3.5
- phpstan/phpstan: ^0.12.50
- phpstan/phpstan-strict-rules: ^0.12.5
- squizlabs/php_codesniffer: ^3.5.6
- thecodingmachine/phpstan-strict-rules: ^0.12.1
- vimeo/psalm: ^4.0
README
By Marcus Bointon (@Synchro).
Hashes are functions which map arbitrary-sized data into a fixed-size value. They are effectively very large numbers that are usually presented as hexadecimal (e.g. 5d41402abc4b2a76b9719d911017c592
) or base-64 strings (e.g. XUFAKrxLKna5cZ2REBfFkg
).
While it's easy for a computer to spot differences between such random-looking strings, it's much harder for us humans. For example, it's difficult for you to tell whether Mk3PAn3UowqTLEQfNlol6GsXPe+kuOWJSCU0cbgbcs8
and Mk3PAn3UowqTLEQfNlo16GsXPe+kuOWJSCU0cbgbcs8
are the same simply by looking at them (they're not!). Sometimes you want a human-readable hash function that makes differences more obvious, and that's what this library provides.
This library uses a truncated SHA-512/256 hash, and maps it into words drawn from a dictionary of 4096 common English words (a random subset of this dictionary). The string hello
produces a hash of three-straps-solved-clutch-groove-abode
, and that's fairly easy for humans to tell apart from three-straps-solved-lagoon-groove-abode
.
Like all good hash functions, it produces wildly different output when presented with only very small differences in the input; hellp
produces zlotys-south-remark-lier-rewind-accept
.
You can choose how many words it generates (up to 21, equivalent to a 252-bit hash), and what separators appear between the words. It's also possible to substitute your own dictionary.
Security warning!
This is not intended for high-performance or cryptographic purposes; do not hash your passwords with this function!
Usage
All methods are static, so there's no need to create an instance.
The generate()
method takes three parameters:
- The string to hash (required)
- The number of words to use (optional, between 1 and 21, defaults to 5, the equivalent of a 45-bit hash)
- The separator to use between words (optional, defaults to
-
)
use Synchro\WordHash\WordHash; echo WordHash::generate('hello!', 5, '_');
Example output
boil_rife_crepe_trait_carted
If you don't like the default words, or want to use emoji, HTML snippets, a different language, or something else, you can provide your own dictionary. It must contain exactly 4096 unique return-delimited words (see the provided dictionary.txt
for reference). The words don't need to be in any particular order, though the provided one is sorted alphabetically.
WordHash::loadDictionary('/path/to/my/dictionary.txt');
Developer info
Requires PHP 7.4+
🧹 Lint the code using PHP Codesniffer:
composer lint
⚗️ Run static analysis using PHPStan or Psalm:
composer test:types composer test:psalm
✅ Run unit tests using Pest
composer test:unit
🚀 Run the entire test suite:
composer test
Project layout based on Skeleton PHP by Nuno Maduro under the MIT license.