Hide PIN-code in random matrix

The digits of a PIN-code can be hidden in a message taking the form of a matrix of random digits. The digits of the PIN-code are placed in matrix positions given by a template. The owner of the PIN-code knows the pattern and is therefore able to decrypt the message. This is a simple way to make a paper based PIN-code reminder.

There is 10% probability of success when guessing one PIN-code digit. When the digits are hidden in a 6 by 6 matrix the probability of guessing the right digit (or rather matrix element) is about 3%. A PIN-code hidden in a matrix is therefore more secure than that of pure guessing. Thus, you can carry the matrix with your credit card without compromising the card and still be able to read the PIN … as long as you remember the pattern without writing it down in any way.

To generate the template I use xfig, a versatile drawing program available for most Linux distributions. Xfig uses a very simple ascii file format.

Template

Template matrices

First the template is drawn, say like the figure above, in this case with matrices for up to 6 PIN-codes. The pattern for the PIN-digits is indicated by an ascending sequence of letters, so the PIN-digits of the first code is placed in elements A, B, C and D. Note that the number of digits in each PIN-code  may vary.

The trick is now to replace the letters with PIN-code digits and  ‘*’ matrix elements with random digits.   This is done by the following python program operating on the xfig template file

# Reads a template drawn with xfig and generates a pdf with matrices
# of random digits and pin-codes

import random
import os

def ReplaceAll(filen, pins):
    fi= open("templ.fig", "r") # read template file
    text= fi.read()            # read file as one long string
    fi.close()
    fo= open(filen, "w")       # file to be written
    c= ord('A')                # First char to replace
    for d in pins:             # substitute all chars in pins string
        text= text.replace("%s\\001"%(chr(c)), "%s\\001"%d)
        c= c + 1
    lines= text.split('\n')    # split the text into separate lines
    for line in lines:         # and replace all '*' with random digits
        line= line.replace("*\\001", "%d\\001"%random.randint(0, 9))
        fo.write(line + '\n')
    fo.close()

random.seed(0)

#declare the pin numbers. Number of chars must be >= to chars in the template
pins= "3412"+"3894"+"2332"+"76589"+"****"+"****"
outputFile= "a"

ReplaceAll(outputFile+".fig", pins)

os.system("fig2dev -Lpdf -m0.5  -gwhite %s.fig %s.pdf"%((outputFile,)*2))
#experiment with the scaling factor -m to get the preferred printed size

The resulting PDF-file looks like this.

The resulting matrices with hidden codes

The resulting matrices with hidden codes

The size of the printout is about the size of a credit card and can be laminated for durability. Observe that the PIN-codes are compromised if anyone gets to see the python program. Protect it by  making it readable by the owner only: chmod go-r pinmatrix.py.

You can download the python program and example template. Remember to change the template before you generate your matrices!

1 Response to “Hide PIN-code in random matrix”


  • Such an excellent concept. I wonder if credit card sized alpha/numeric matrix could be used to contain several passwords? Now that would be really useful. Not sure how one would correlate the start of a pattern or its sequence to any
    given requirement. Now write up.

Leave a Reply