Skip to content

Instantly share code, notes, and snippets.

@hughpyle
Created February 25, 2021 15:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hughpyle/14a352c6df9d333c225c87646a6165b6 to your computer and use it in GitHub Desktop.
Save hughpyle/14a352c6df9d333c225c87646a6165b6 to your computer and use it in GitHub Desktop.
amulet
#!/usr/bin/env python3
"""
amulet (https://text.bargains/amulet/)
"""
import sys
import hashlib
from copy import copy
from multiprocessing.dummy import Pool as ThreadPool
# Break a file into "sentences".
# Permute the sentences with capitalization, line breaks, etc;
# Calculate the SHA-256 hash.
# Report any amulets found.
# An amulet has four or more consecutive '8' in the hash.
def check(candidate: str):
"""
Check a hash
"""
sha2 = hashlib.sha256(candidate.encode("utf-8")).hexdigest()
if "8888888" in sha2:
if "888888888" in sha2:
print(f"Mythic: {sha2}:\n{candidate}")
elif "88888888" in sha2:
print(f"Legendary: {sha2}:\n{candidate}")
elif "8888888" in sha2:
print(f"Epic: {sha2}:\n{candidate}")
elif "888888" in sha2:
print(f"Rare: {sha2}:\n{candidate}")
elif "88888" in sha2:
print(f"Uncommon: {sha2}:\n{candidate}")
else:
print(f"Common: {sha2}:\n{candidate}")
def case(words: list):
"""
Variations of case
"""
n = len(words)
yield words
for idx in range(n):
wc = copy(words)
wc[idx] = wc[idx].lower()
yield wc
wc = copy(words)
wc[idx] = wc[idx].upper()
yield wc
wc = copy(words)
wc[idx] = wc[idx].title()
yield wc
def seps(words: list, sep: str):
"""
Variations of a separator
"""
# The plan sentence
yield " ".join(words)
# The sentence with separator injected in the middle
n = len(words)
for idx in range(n):
sps = ([" "] * (n-1)) + [""]
sps[idx] = sep
wc = [words[i] + sps[i] for i in range(n)]
yield "".join(wc)
def punc(opt: str):
"""
Produce some sentence variations with punctuation
"""
yield opt
yield opt + "."
yield opt + "!"
yield opt + "?"
yield "(" + opt + ")"
yield "(" + opt + ")."
yield "'" + opt + "'"
yield '"' + opt + '"'
yield "'" + opt + ".'"
yield '"' + opt + '."'
yield "'" + opt + "'."
yield '"' + opt + '".'
def permute(words: list):
"""
Produce some permutations of the words in 'words'
"""
for sep in ["\n", "-\n", " -\n", ":\n", ",\n", ".\n", "...\n"]:
for words1 in case(words):
for opt in seps(words1, sep):
for opt2 in punc(opt):
yield opt2
def sentences(book: list):
"""
Produce sentences (arrays of words) from the book
"""
for idx in range(len(book)):
for slen in range(20):
words = book[idx:(idx + slen + 1)]
if len(" ".join(words)) > 64:
break
yield words
def load(filename: str) -> list:
"""
Load a whole text file into a list of words
"""
with open(filename, "r") as fd:
data = fd.read()
return data.split()
def run(filename):
"""
Usage: amulet <filename>
"""
# check("If you can't write poems,\nwrite me")
words = "if you can't write poems write me".split(" ")
book = load(filename)
pool = ThreadPool(4)
for words in sentences(book):
# print(words)
#for candidate in permute(words):
# check(candidate)
pool.map(check, permute(words))
run(sys.argv[1])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment