My 31 Days Passcode Based System for My Sunrise Alarm
Published on:
If I want to stop my Sunrise Pialarm, I have to enter that day’s passcode. I will show you how I generate them.
The individual source code of the script can be found at GitHub Gist: generate_passcodes.py. This is part of a bigger project, which is fully open source. Check out GitHub - 11Firefox11/sunrise-pialarm.
The Goal
I have to generate 31 unique random, hard to remember passcodes. What are the goals?
- Write passcodes into a JSON file as an array.
- Generate passcodes.
- Hash the passcodes and make them unique.
- Write hashes into file and display passcodes for each day.
Implementation
Write Into JSON
Writing into a file is easy, no need to overthink it. The format I want to achieve is: ["code1", "code2" ...]
. The script opens a file, puts in the starting bracket, writes in the passcodes one by one and closes the bracket. This can be achieved with a for loop.
PASSCODES_JSON_PATH = "passcodes.json"
passcodes_file = open(PASSCODES_JSON_PATH, "w") # open the file in write mode
passcodes_file.write("[")
for day_num in range(31):
passcodes_file.write(f"\"code{day_num}\"{',' if day_num != 30 else ''}") # write in "codeX" plus a comma if it isn't the last day_num
passcodes_file.write("]")
Generate Passcodes
To create random passcodes use token_urlsafe
, which creates a random text string based on inputted nbytes
.
from secrets import token_urlsafe as secrets_token_urlsafe
# ...
for day_num in range(31):
passcode_raw = secrets_token_urlsafe(4)
# ...
Hash and Make Them Unique
Hashing is a process of converting input data of any size into a fixed-size output value. This makes a one way tunnel, it can be checked if a hash is the inputted passcode (if we know the hash algorithm), but we can’t get from the hash what is the passcode. In this script the sha1 algorithm is used. To make them unique store all passcodes in a list. If a passcode is already in the list a new one is generated.
from hashlib import sha1
# ...
hashes_generated = []
for day_num in range(31):
passcode_raw = secrets_token_urlsafe(4)
passcode_hashed = sha1(passcode_raw.encode()).hexdigest()
while passcode_hashed in hashes_generated: # if exists, generate new one
passcode_raw = secrets_token_urlsafe(4)
passcode_hashed = sha1(passcode_raw.encode()).hexdigest()
hashes_generated.append(passcode_hashed)
# ...
Save Into File and Print
Just simply change the text inside write
to save the hashes instead of "codeX"
. The script prints out each passcode one by one, waits for an input just so it is more visible which passcode is coming now.
# ...
for day_num in range(31):
# ...
passcodes_file.write(f"\"{passcode_hashed}\"{',' if day_num != 30 else ''}")
print(f"{str(day_num+1).zfill(2)} | {passcode_raw}", end="") # zfill the number so each will be same width
input()
Previous Part
Python Class to Control an RGB LED Strip on a Raspberry Pi
Next Part