Skip to content

Instantly share code, notes, and snippets.

@gto76
Last active July 5, 2020 01:21
Show Gist options
  • Save gto76/1fc2e9de893226b8c4dd1bb2c4d6cedd to your computer and use it in GitHub Desktop.
Save gto76/1fc2e9de893226b8c4dd1bb2c4d6cedd to your computer and use it in GitHub Desktop.
A little Python script that helps you remember a forgotten PIN number
#!/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