The password generation algorithm used in this application is intentionally simple and transparent. Below is a very simplified Python reference implementation demonstrating how dice faces, directions and dice order are combined into a large number and converted into a password.
This version omits input/output validation and other safeguards present in
the application. Nevertheless, it is fully functional and reflects the core
algorithm used by dicendo.
Its purpose is to make the algorithm easy to inspect and independently verify. For the same inputs, it produces exactly the same outputs as the application.
#!/usr/bin/python3 from math import factorial, floor, log import re def lehmer(permutation): n = len(permutation) lehmer_code = [0] * n for i in range(n): count = 0 for j in range(i + 1, n): if permutation[j] < permutation[i]: count += 1 lehmer_code[i] = count n = len(lehmer_code) lehmer_number = 0 for i in range(n): lehmer_number += lehmer_code[i] * factorial(n - 1 - i) return lehmer_number ALPH = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()<>-_=+;:,./?" # faces = "551421565161262454131223114221644461" # directions = "" # order_str = "" faces = "646512242554" directions = "WWENSNWESESE".translate(str.maketrans("NESWnesw", "01230123")) order_str = "12-3-9-6-4-10-8-11-7-5-2-1" rnd_num = 0 order = [] if order_str != "": order = [eval(i) for i in re.split("[-+*/=:;., ]", order_str)] rnd_num = lehmer(order) for f in faces: rnd_num = 6 * rnd_num + (eval(f) % 6) for d in directions: rnd_num = 4 * rnd_num + eval(d) eff_len = floor( log( factorial(len(order)) * (6 ** len(faces)) * (4 ** len(directions)), len(ALPH) ) ) passwd = "" for _ in range(eff_len): passwd = ALPH[rnd_num % len(ALPH)] + passwd rnd_num = rnd_num // len(ALPH) print(passwd)