How to Randomly Generate a Pattern Lock

PSA before we begin: if you are using pattern lock on your device as primary method of authentication, find alternatives. Pattern lock is unsafe. There is a reason why password managers don’t try supporting it. Compared to that of PIN, the safety provided by pattern lock is mediocre at best even with the best of practices.

That being said, there are still apps and IoT devices that kept the new, chick, but untested pattern locks as the only way to add authentication. I won’t name names, —frankly there are just too many— but whenever I’m stuck in those situations, my brain seizes for a moment. Because this is not an ordinary password a password manager can generate.

Preface

The script I wrote is in Python as usual. If you wish to run it on smartphones, there are python IDE apps available that allows to run python scripts on the device. I am actually using Pythonista on iOS. Obviously this can be done in different languages and platforms, say, on iOS Shortcuts.

Few things I do want to emphasize: this script will generate a pattern with 8-way direction (i.e. will select dots that are immediately next to the dot), and the pattern may not use all 9 dots. For example, if the script generated [2, 6, 3, 5, 4, 8, 7] as pattern, it will also say Incomplete Pattern as there are still remaining dots. I explicitly wrote the restrictions, so that the inputting the pattern would be more intuitive.

Instructions

You can create and save a text file if you wish to run the script from it. You could also copy the contents into the Terminal while running Python; it will still generate the pattern the same.

#!/usr/bin/env python3

import random

print("1-2-3")
print("4-5-6")
print("7-8-9")
poss = [1,2,3,4,5,6,7,8,9]
numDir = {
	1: [2,4,5],
	2: [1,3,4,5,6],
	3: [2,5,6],
	4: [1,2,5,7,8],
	5: [1,2,3,4,6,7,8,9],
	6: [2,3,5,8,9],
	7: [4,5,8],
	8: [4,5,6,7,9],
	9: [5,6,8]
}
n = random.randrange(1, 9+1)
pattern = [n]
poss.remove(n)
for idx in range(8):
	cand = [i for i in numDir[n] if i in poss]
	if len(cand) == 0:
		print("Incomplete Pattern")
		break
	n = random.choice(cand)
	pattern.append(n)
	poss.remove(n)
	cand.clear()
print(pattern)

In case you are wondering what the numbers represent in patterns, they are the positions of dots. The script will print both the dots-representation (e.g. 1 for top-left corner) and the pattern it generated. If you are still unsure, think of number pads on phones.

Also don’t forget to either memorize or save the pattern in a secure location, such as password managers. It’s still an authentication, and you will need it again in the future.

note: after publishing the piece, I found out random.randint(a, b) produces a < N <= b on Python 3.13. This is not what the documentation says, but I switched out the function just to be sure.

Comments

Leave a comment