Skip to content

Instantly share code, notes, and snippets.

@aparatext
Last active December 16, 2025 23:19
Show Gist options
  • Select an option

  • Save aparatext/a109b74beb33e1a9f05991bf8c23a8e6 to your computer and use it in GitHub Desktop.

Select an option

Save aparatext/a109b74beb33e1a9f05991bf8c23a8e6 to your computer and use it in GitHub Desktop.
ffprint, ffprint-ck - human-friendly, 128-bit secure, typo-detecting file fingerprints
#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.13"
# dependencies = [ "blake3"]
# ///
from sys import stdin
from blake3 import blake3
from itertools import batched, cycle
ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
COLORS = ['\033[1;36m', '\033[1;33m'] # bright cyan, bright yellow
RESET = '\033[0m'
def to_base58(b: bytes) -> str:
n = int.from_bytes(b, 'big')
chars = []
while n:
n, rem = divmod(n, 58)
chars.append(ALPHABET[rem])
return '1' * (len(b) - len(chars)) + ''.join(reversed(chars))
data = stdin.buffer.read()
hashed = blake3(data).digest()[:16]
cksum = blake3(hashed).digest()[:2]
fprint = to_base58(hashed + cksum)
chunks = map(''.join, batched(fprint, 5))
colored = ' '.join(f"{color}{chunk}{RESET}" for color, chunk in zip(cycle(COLORS), chunks))
print(colored)
#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.13"
# dependencies = ["blake3"]
# ///
from sys import stdin, argv, exit, stderr
from blake3 import blake3
ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
def from_base58(s: str) -> bytes:
n = 0
for c in s: n = n*58 + ALPHABET.index(c)
b = n.to_bytes((n.bit_length()+7)//8, 'big')
pad = 0
for c in s:
if c=='1': pad+=1
else: break
return b'\0'*pad + b
if len(argv)<2:
print("Usage: cat file | ffprint-ck <fingerprint>", file=stderr)
exit(2)
fprint = argv[1].replace(' ','').strip()
try: raw = from_base58(fprint)
except ValueError as e:
print(f"Invalid Base58 fingerprint: {e}", file=stderr)
exit(2)
if len(raw)<18:
print("Fingerprint too short", file=stderr)
exit(2)
hashed, cksum = raw[:-2], raw[-2:]
if blake3(hashed).digest()[:2] != cksum:
print("Checksum invalid", file=stderr)
exit(2)
data = stdin.buffer.read()
if blake3(data).digest()[:16] == hashed:
print("Fingerprint match", file=stderr)
exit(0)
else:
print("Fingerprint mismatch", file=stderr)
exit(1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment