This is my first post using Python, but I’m not going to explain all of the basics of Python syntax here. If you aren’t familiar with Python, you may want to read a tutorial or introduction to the language first.
Here is what
genpw.py
looks like:#!/usr/bin/python3
import random
import sys
chars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_', '`', '{', '|', '}', '~' ]
length = 13
pw = ""
for i in range(1, len(sys.argv)):
if sys.argv[i] == "--alnum":
chars = chars[0:62]
elif sys.argv[i] == "--length":
length = int(sys.argv[i+1])
elif sys.argv[i] == "--forbidden":
forbiddenchars = sys.argv[i+1]
for ch in forbiddenchars:
chars.remove(ch)
end = len(chars) - 1
for i in range(0, length):
index = random.randint(0, end)
ch = chars[index]
pw += ch
print(pw)
First, we start with a list of printable ascii characters. Since it has been sorted into numbers, letters, and symbols; we can get the alphanumeric subset with a simple slice operation. And we can remove any forbidden characters by simply calling the
remove()
method of the list of characters. Then, we find how many characters are in the resulting list and generate a random number within that range for each character in the final password. We simply use that number as the index to choose one of the characters from our list and then print the completed password string.The approach here is slightly different from the one that I used in the Bash script. There, we generated a stream of random numbers and filtered out only the desired characters until we had the desired length. Here, we create a list of desired characters and select the desired number of characters randomly.
And here is what
setpw.py
looks like:#!/usr/bin/python3
import sys
import os
import hashlib
if len(sys.argv) > 1:
name = sys.argv[1]
else:
name = "default"
pw = input().encode('ascii')
pwhash = hashlib.sha512(pw).hexdigest()
hashfile = os.path.expanduser("~/." + name + "pwhash")
print("\033[1A\033[0K", end="")
with open(hashfile, 'w') as f:
f.write(pwhash)
This one is even more similar to the Bash version, it’s approach does not substantially differ.
Finally, here is what
ppw.py
looks like:#!/usr/bin/python3
import sys
import os
import hashlib
import getpass
if len(sys.argv) > 1:
name = sys.argv[1]
else:
name = "default"
pw = getpass.getpass("").encode('ascii')
pwhash = hashlib.sha512(pw).hexdigest()
hashfile = os.path.expanduser("~/." + name + "pwhash")
with open(hashfile, 'r') as f:
storedhash = f.read()
if pwhash == storedhash:
print("Correct")
else:
print("Wrong\a")
Again, the approach here is essentially the same as the Bash version. You may notice that instead of
input()
, I used getpass.getpass("")
. This prevents it from echoing the characters to the terminal. By default, getpass()
uses the prompt Password:
, so to make it more consistent with the Bash version I passed it an empty string instead.Hopefully you found this little exercise entertaining and educational.