Skip to content

Instantly share code, notes, and snippets.

@Nazgolze
Last active November 8, 2020 08:27
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 Nazgolze/6db9d534068e31cfbc89c4e59b09cc89 to your computer and use it in GitHub Desktop.
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
#!/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