Created
February 25, 2021 15:38
-
-
Save hughpyle/14a352c6df9d333c225c87646a6165b6 to your computer and use it in GitHub Desktop.
amulet
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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