Last active
November 8, 2020 08:27
-
-
Save Nazgolze/6db9d534068e31cfbc89c4e59b09cc89 to your computer and use it in GitHub Desktop.
For if you miswrote your bip39 password and you want to try to recover the real one
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 | |
""" lev3.py """ | |
# pylint: disable=C0200,C0103 | |
import argparse | |
import copy | |
import mnemonic | |
M = mnemonic.Mnemonic("english") | |
WORDLIST = M.wordlist | |
def levenshtein(s, t): | |
# pylint: disable=C0103 | |
""" From Wikipedia article; Iterative with two matrix rows. """ | |
if s == t: | |
return 0 | |
if len(s) == 0: | |
return len(t) | |
if len(t) == 0: | |
return len(s) | |
v0 = [None] * (len(t) + 1) | |
v1 = [None] * (len(t) + 1) | |
for i in range(len(v0)): | |
v0[i] = i | |
for i in range(len(s)): | |
v1[0] = i + 1 | |
for j in range(len(t)): | |
cost = 0 if s[i] == t[j] else 1 | |
v1[j + 1] = min(v1[j] + 1, v0[j + 1] + 1, v0[j] + cost) | |
for j in range(len(v0)): | |
v0[j] = v1[j] | |
return v1[len(t)] | |
def dfs(car, cdr, ret): | |
""" quick and dirty depth-first search """ | |
car = copy.deepcopy(car) | |
cdr = copy.deepcopy(cdr) | |
if len(ret.split()) == 11: | |
for item in car: | |
s = ret + " " + item #car.pop() | |
if M.check(s): | |
print(s) # actual password printing happens here | |
return | |
for item in car: | |
if ret == "": | |
s = item | |
else: | |
s = ret + " " + item | |
dfs(cdr[0], cdr[1:], s) | |
def print_phrase_list(password, distance, first=False): | |
""" get the final list of phrases """ | |
result = [] | |
for i in range(0, len(password)): | |
t = [] | |
for word in WORDLIST: | |
if first and password[i][0] != word[0]: | |
continue | |
if levenshtein(password[i], word) <= distance: | |
t.append(word) | |
result.append(t) | |
# print(result) | |
dfs(result[0], result[1:], "") | |
def main(): | |
""" main function """ | |
parser = argparse.ArgumentParser(description="lev3") | |
parser.add_argument("--password", nargs=1, help="Your password") | |
parser.add_argument("--distance", nargs=1, help="levenshtein distance") | |
parser.add_argument("--first", action="store_true", help="first letter must match") | |
args = parser.parse_args() | |
print_phrase_list(args.password[0].split(), int(args.distance[0]), first=args.first) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment