A Go library and CLI tool that converts binary hashes into deterministic human-readable word sequences optimized for verbal communication and error detection.
- π€ Binary to Words: Convert any binary hash into phonetically distinct words
- π Reversible: Perfectly decode words back to original hash
- β Error Detection: Optional checksum words for integrity verification
- π Collision Analysis: Statistical analysis of collision probabilities
- π― Optimized Wordlist: 256 carefully selected words for verbal clarity
- π οΈ CLI & Library: Use as a command-line tool or Go package
go install github.com/BaseMax/go-hashwords/cmd/hashwords@latestgo get github.com/BaseMax/go-hashwordshashwords encode 00010203
# Output:
# 1: aardvark
# 2: absurd
# 3: accrue
# 4: acmehashwords encode -checksum 00010203
# Output includes a 5th checksum wordhashwords decode aardvark absurd accrue acme
# Output: 00010203hashwords decode -checksum aardvark absurd accrue acme adult
# Validates checksum and outputs: 00010203hashwords hash "hello world"
# Hashes the text with SHA256 and encodes to 32 wordshashwords hash -algo sha512 "hello world"
# Use SHA512 instead (produces 64 words)hashwords analyze 32
# Analyzes collision probabilities for 32-byte hasheshashwords hash -file document.pdfpackage main
import (
"fmt"
"github.com/BaseMax/go-hashwords"
)
func main() {
encoder := hashwords.NewEncoder()
// Encode hex string to words
words, _ := encoder.EncodeHexString("00010203")
fmt.Println(words) // [aardvark absurd accrue acme]
// Decode words back to hex
hexHash, _ := encoder.DecodeToHexString(words)
fmt.Println(hexHash) // "00010203"
}import (
"crypto/sha256"
"github.com/BaseMax/go-hashwords"
)
func main() {
encoder := hashwords.NewEncoder()
// Hash some data
hash := sha256.Sum256([]byte("hello world"))
// Encode to words
words, _ := encoder.Encode(hash[:])
// Decode back to binary
decoded, _ := encoder.Decode(words)
}encoder := hashwords.NewEncoder()
// Add checksum
words := []string{"aardvark", "absurd", "accrue"}
wordsWithChecksum, _ := encoder.VerifyChecksum(words)
// Validate checksum
validatedWords, err := encoder.ValidateChecksum(wordsWithChecksum)
if err != nil {
fmt.Println("Checksum invalid!")
}analyzer := hashwords.NewCollisionAnalyzer()
// Analyze for 32-byte hash (SHA256)
stats := analyzer.AnalyzeCollisions(32)
fmt.Println(analyzer.FormatStats(stats))
// Validate word list integrity
issues := analyzer.ValidateWordList()- Each byte of the hash (0-255) maps to exactly one word from the 256-word list
- A 32-byte SHA256 hash produces exactly 32 words
- Words are phonetically distinct to minimize verbal confusion
- Each word maps back to its corresponding byte value (0-255)
- Perfect reversibility - no information loss
- Case-insensitive for convenience
- Optional checksum word derived from SHA256 of the hash
- Detects transcription errors when communicating words verbally
- First byte of the checksum hash becomes the checksum word
The library provides collision analysis tools:
- 256-bit hashes (SHA256, 32 bytes): Cryptographically strong
- Birthday paradox: 50% collision after ~4Γ10^38 hashes for SHA256
- Word list validation: Ensures 256 unique, phonetically distinct words
Example analysis output:
=== Collision Analysis ===
Word List Size: 256 words
Hash Length: 32 bytes (256 bits)
Total Possible Hashes: 2^256
Security Level: Cryptographically Strong (256+ bits)
The 256-word list is optimized for:
- Phonetic Distinctness: Words sound different when spoken
- Memorability: Common, easy-to-remember words
- Brevity: Relatively short words for efficiency
- Uniqueness: No duplicates or confusingly similar words
- π Password verification: Verbally confirm passwords/keys
- π Phone support: Communicate hashes over the phone
- π€ Voice interfaces: Voice-friendly hash representation
- π Human-readable logs: Make hash logs more accessible
- π Hash comparison: Quickly identify hash differences
- π― Two-factor auth: Verbal confirmation codes
package main
import (
"crypto/sha256"
"fmt"
"github.com/BaseMax/go-hashwords"
)
func main() {
encoder := hashwords.NewEncoder()
// Create a hash
original := []byte("important data")
hash := sha256.Sum256(original)
// Encode to words
words, _ := encoder.Encode(hash[:])
fmt.Println("Words:", words)
// Someone reads the words back to you over the phone
// Now decode
decoded, _ := encoder.Decode(words)
// Verify it matches
decodedHash := [32]byte{}
copy(decodedHash[:], decoded)
if decodedHash == hash {
fmt.Println("β Hash verified!")
}
}# MD5 (16 bytes = 16 words)
hashwords hash -algo md5 "data"
# SHA1 (20 bytes = 20 words)
hashwords hash -algo sha1 "data"
# SHA256 (32 bytes = 32 words)
hashwords hash -algo sha256 "data"
# SHA512 (64 bytes = 64 words)
hashwords hash -algo sha512 "data"# Run all tests
go test ./...
# Run tests with coverage
go test -cover ./...
# Run specific tests
go test -run TestEncode# Clone the repository
git clone https://github.com/BaseMax/go-hashwords.git
cd go-hashwords
# Build the CLI
go build -o hashwords ./cmd/hashwords
# Run tests
go test ./...Contributions are welcome! Please feel free to submit a Pull Request.
MIT License - see LICENSE file for details.
Max Base
- GitHub: @BaseMax
- Inspired by PGP word lists for phonetic clarity
- Designed for real-world verbal communication scenarios