Last active
July 5, 2020 01:21
-
-
Save gto76/1fc2e9de893226b8c4dd1bb2c4d6cedd to your computer and use it in GitHub Desktop.
A little Python script that helps you remember a forgotten PIN number
This file contains hidden or 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 | |
# | |
# Usage: ./pin_guesser.py | |
# Tool that helps you remember a PIN code. | |
# It starts by giving you suggestions containing the first two decimals, then middle | |
# two and last two. Then it takes the answers and generates the suggestions | |
# containing the first three decimals, followed by the last three and finally all four. | |
# You answer to the proposed PIN number with 'j' for yes and 'f' for no. | |
# At the end it prints out all the affirmative answers. | |
# It is also saving the answers along the way into pickle files, so they can | |
# be retrieved if something goes wrong. | |
# DELETE THE PICKLE FILES AFTER USE! | |
# Will not work on the Windows command prompt because it uses Curses library. | |
from collections import namedtuple | |
from dataclasses import make_dataclass | |
from enum import Enum | |
from sys import argv | |
import re | |
from curses import wrapper, curs_set, ascii | |
from curses import KEY_UP, KEY_RIGHT, KEY_DOWN, KEY_LEFT | |
import pickle | |
N_DECIMALS = 10 | |
def main(): | |
wrapper(draw) | |
print_results() | |
def print_results(): | |
out = read_pickle_file('out.pickle') | |
out_2 = read_pickle_file('out_2.pickle') | |
out_3 = read_pickle_file('out_3.pickle') | |
for a_dict in [out, out_2]: | |
for line in a_dict.values(): | |
for nums in line: | |
print(format(nums)) | |
for nums in out_3: | |
print(format(nums)) | |
def draw(screen): | |
curs_set(0) | |
screen.nodelay(True) | |
screen.clear() | |
out = {0: [], 1: [], 2: []} | |
for i in range(3): | |
for j in range(N_DECIMALS): | |
for k in range(N_DECIMALS): | |
nums = [j, k, None, None] if i == 0 else \ | |
([None, j, k, None] if i == 1 else [None, None, j, k]) | |
if draw_and_get_answer(nums, screen): | |
out[i].append(nums) | |
write_to_pickle_file('out.pickle', out) | |
out_2 = {0: [], 1: []} | |
for a in out[0]: | |
for b in out[1]: | |
if a[1] == b[1]: | |
nums = [a[0], a[1], b[2], None] | |
if draw_and_get_answer(nums, screen): | |
out_2[0].append(nums) | |
for a in out[1]: | |
for b in out[2]: | |
if a[2] == b[2]: | |
nums = [None, a[1], a[2], b[3]] | |
if draw_and_get_answer(nums, screen): | |
out_2[1].append(nums) | |
write_to_pickle_file('out_2.pickle', out_2) | |
out_3 = [] | |
for a in out_2[0]: | |
for b in out_2[1]: | |
if a[1] == b[1] and a[2] == b[2]: | |
nums = [a[0], a[1], a[2], b[3]] | |
if draw_and_get_answer(nums, screen): | |
out_3.append(nums) | |
write_to_pickle_file('out_3.pickle', out_3) | |
def draw_and_get_answer(nums, screen): | |
b = get_border(screen) | |
screen.addstr(b.y // 2, b.x // 2 - 2, format(nums)) | |
ch = screen.getch() | |
while ch not in (ord('f'), ord('j')): | |
ch = screen.getch() | |
return ch == ord('j') | |
def format(nums): | |
return ''.join(str(a) if a is not None else '.' for a in nums) | |
### | |
## UTILS | |
# | |
def get_border(screen): | |
from collections import namedtuple | |
P = namedtuple('P', 'x y') | |
height, width = screen.getmaxyx() | |
return P(width-1, height-1) | |
def read_pickle_file(filename): | |
with open(filename, 'rb') as file: | |
return pickle.load(file) | |
def write_to_pickle_file(filename, an_object): | |
with open(filename, 'wb') as file: | |
pickle.dump(an_object, file) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment