HomeBlogAbout UsWorkContentContact Us

De Bruijn Sequences

Last year I wrote an article about 4-digit PIN codes. It became quite popular, and I even got asked to give a TEDX talk about it which you can watch here (shameless plug).

The basis of the talk was that people are very predictable in the selection of their codes. Mathematically, whilst there are 10,000 ways that the digits 0-9 can be arranged into a four digit PIN, people’s selections are not random. Only 426 distinct codes are needed to guess over half the PINs in use!

Perfect World

Imagine, instead of being predictable, that people selected their codes entirely at random. If you wanted to guess the PIN of a four digit combination lock, you might have to walk through all 10,000 four digit combinations. Since there are four digits in each number, the worst case is that you’d have to type 40,000 key presses, and on average it would take you half this number.

That’s a lot of key presses.

Can you do better? Can you do it with less key presses?

Well, if the lock is smart, no, you can’t do better. But some systems that accept PINs are less sophisticated. These less secure mechanisms don’t quantize the inputs in batches of four (or however long the code is), but instead simply look at just the last four keys pressed.

An example of this in use is shown below. Imagine you entered the six digits 123479 into one of these systems. As the system examines just the last four digits entered, this string would give you three distinct (overlapping) unlock attempts.

This simpler system has the advantage of not having to worry about what state you are in when you start, or having to code in time-outs into the entry system. Without this simplification, if your code was 1234, but just before you tried to enter it, unbeknownst to you, someone else had entered 99 on the keypad. When you entered your PIN, the lock would interpret this as 9912 (fail), and then 34 (still a fail and waiting for more digits before telling you it failed). Examining just the last four digits solves this problem.

If our system supports overlapping numbers we can be more efficient in guessing. We can create an input stream that goes through all permutations, but requires less key presses. The question is, how much more efficient? What is the shortest sequence of numbers that we can go through in order to ensure that all possible combinations of the digits are seen? Is it possible to create a sequence that does not repeat any sub-sequence of codes?

Nicolaas Govert de Bruijn

The mathematics, number theory, combinatronics and logic of these types of problems were studied extensively by a Dutch Professor called Nicolaas Govert de Bruijn (9 July 1918 – 17 February 2012).

Sequences of these numbers are named after him as De Bruijn Sequences.

The quick answer is that, yes, it is possible to make a non-repeating sequence of numbers that covers ever sub-sequence internally, just once. However, before we look at the PIN number solution, let's look at some simpler versions of the problem …

Image Credit: Konrad Jacobs

Simpler Sequences

De Bruijn sequences can be described by two parameters:

  • k  the number of entities in the alphabet e.g. {0,1,2,3,4,5,6,7,8,9} for k=10

  • n  the order (length of sub-sequence required) e.g. n=4 for a four digit long PIN.

These are typically describe by the representation B(k,n).

For our PIN example, the notation would be B(10,4)


Let's start with a really simple example: B(2,2)

We'll use the dictionary {0,1} for the possible values. We want to generate a string that contains substrings each possible combination of two digits. Here is a solution:


The first two digits give us 00, the next two 01, then 11. To get to 10, we need to 'Wrap Around' taking the last digit from the string, and the first digit. (If this is not appropriate to do, like the key-press example, then we can simply append the first character from the string to the end to make 00110).

 NOTE:  There can be multiple De Bruijn solutions to any problem. You can easily see this using even simple rotations of the string. Since every adjacent pair of digits in this string is unique, it does not matter what the starting position is. As k and n increase, the number of possible solutions grows rapidly. The hairy looking equation on the left shows the number of distinct solutions.


Here's a solution for B(2,3):


Starting from the front, we have 000, 001, 010, 101, 011, 111, then staring to wrap around, we have 110 and finally 100. All eight possible combinations are present in this string.


Here's a solution for B(2,4):


You can see we have 0000, 0001, 0010, 0100, 1001

And here it is as a pretty ribbon. We can now hint at some of the awesome potential uses for these sequences. Imagine this De Bruijn sequence is written onto a looped tape, which passes past a reader head.

Each increment of the tape one position along gives a unique output. We have found an efficient mechanism of encoding position as there is a distinct code for any contiguous set of four digits (in this case, as n=4). How cool is that?

This sequence also walks through all permutations of combinations from 0000-1111. If you are a software engineer or tester, I'm sure this is giving you interesting ideas for how you can implement this as test cases to walk through all binary inputs to your functions. Each shift of one bit gives a unique binary word (of length of the substring size n), which does not repeat, goes through each possible number, then returns to the start again.


Skipping ahead a couple, here is a solution for B(2,6):



Of course, we can also change the size of the dictionary. In this example rather than simple binary k=2, I've increased this to k=6 to use possible values {0,1,2,3,4,5}. Here is the output for B(6,2):


Reading this from left to right we can see that we have: 00, 01, 10, 02, 2041, 1533, 3455, 50


One last example, here's a sequence for B(5,3):


Back to PIN

Returning to our PIN cracking, the B(10,4) is 10,000 digits long, and contains every single substring for each combination of digits. As we have to type in this string, the concept of Wrap-Around is meaningless, so rather then wrap-around, we simply add the first three numbers again to the end of the strong. So, the maximum number of keypress events is 10,003. Far fewer than the 40,000 that would be required if typing them in completely!

For no useful reason at all, here are all 10,003 digits of this string:


How do these things work?

I glossed over how to calculate a De Bruijn sequence earlier. I'll make up for it now by explaining the principles for how these things work. The concept is not complicated, just tedious; things that computers can do easily. We're going to look at this problem using Directed Graphs.

For this example, I'm going to use B(2,3). This sequence is simple enough to get the concept without being too complex and busy.

Every sub-string in the sequence can be described as a node on a directed graph. From each node, it is possible to add either a 0 or a 1 to make the next number in the sequence.

Similarly, each state/node on the graph could have been formed from adding a digit from one of two earlier states.

First we write down all the nodes that are possible using our data dictionary.

In this case these are 000 - 1111.

Then we connect the nodes with lines showing which possible next states are achievable from each location. Each node has two outbound links corresponding to the addition of a 1 or 0 from that state.

These edges are directed. They have a direction (depicted by the arrows)

Note - For States 000 and 111, the addition of a 0 or 1, respectively, takes you back to the same node.

In order to make sure every substring is present in the solution, we need to make sure each node is passed through once (and only once). We need to trace a path through the graph (following the arrows) to connect the nodes.

A path that traverses a graph and visits each node exactly once is called a Hamiltonian Path.

One such Hamiltonian Path on the B(2,3) graph is shown in red on the left.

This highlights why there are many different solutions (not just rotations). There is more than one way to walk through this graph.

The way to create a De Bruijn sequence is to find a Hamiltonian Path through a graph their nodes.

As the values of k and n increase, so does the complexity of the graph, but the principle is the same.

Here's a slightly more complex one using a dictionary {1,2,3) for a sequence B(3,2)

Find a path through the graph the passes through each node just once, and you have your solution.

Other uses

We already hinted that De Bruijn sequences can be used for encode/decode positions, and that they can be used by savvy computer programmers. What are some other applications?

I’ve seen magicians use a similar principle in various card tricks. By pre-arranging (loading) a deck with a known sequence of red and blacks cards in a De Bruijn sequence, it allows him/her to know what the position is, and thus, what the next card will be. Using a binary encoding of the red/black cards to generate a unique number, which can then, be used to encode the value of what the next card will be.

Because of the wrap-around nature of De Bruijn sequences, a loaded deck can be cut as many times as desired without upsetting or disturbing the encoding. I don't want to link directly examples, as I don't want to ruin the tricks for others that might be performing them, but I'm sure if you know how to use a web search tool, you can find some strategies.


The concept of Hamilton cycles and De Bruijn are used extensively in modern DNA sequencing techniques.

A large DNA chain can be broken up into smaller pieces (The smaller pieces being easier to process and sequence). Then, the results of these smaller pieces can be 'glued' back together like some kind of giant jigsaw because the individual sub-pieces contain overlaps with other partial strings.

This technique is called Shotgun Sequencing.

Below you can see a representation of a long chain of DNA. This is smashed into smaller sub-pieces (of different sizes), which are easier to classify. The classified pieces can then be joined back together to form the complete sequence by looking at the overlaps between the substrands.

In some cases, the shotgun sequencing technique generates multiple canonical sequences. Of course, only one of these can be the real sequence. There are a variety of tests that can narrow down which of these sequences is the original one. Shotgun sequencing, although it does not necessarily define the exact sequence, greatly speeds up the process by reducing the number of possible candidates.

The advent of shotgun sequencing techniques advanced the initial mapping of the human genome by years, and it has provided biologists, geneticists, and doctors with a powerful new tool. The ability to sequence genetic data rapidly has potential benefits not only for life and health science professionals, but also for the public at large. It's pretty cool.


Computer programs that play chess make use of De Bruijn sequences. A chess board is conveniently 8 x 8 squares, and these can be represented by the numbers 0-63, which is a nice fit for a six bit long De Bruijn sequence.

De Bruijn Toroids

OK, prepare your mind for something cooler still. We can expand a De Bruijn one dimensional sequence into two dimensions! We call these Toroids because every row and column wraps around onto itself.

Sliding a window over this surface creates a unique matrix for a well-formed De Bruin array.

Things get much more complicated because not only do we need to specify the number of items in the dictionary, but also the two dimensions of the window.

Below is a simple example of an array that has a dictionary of two {red, yellow}, and a (2 x 2) window:

If you look carefully, you will see that every combination of red/yellow dots appears all possible combinations of (2x2) sub-matrices. Remember, you need to wrap-around (for instance to get a matrix containing four yellow dots you need the matrix that is the four corners wrapped around the outside!)

I'm sure you can see instant applications for something like this in determining (x,y) position. Each window is unique and determines coordinate position.

Of course, we're not restricted to using just a dictionary of two items. Below are two larger De Bruijn toroids. The one on the left has a dictionary size of three, and matrix window of (2 x 2). The one on the right has the same matrix window and this time has a dictionary of size four.

The grid on the left is (9 x 9) and that on the right is (16 x 16), allowing representation of all 256 possible combinations that a dictionary of order four into a (2 x 2) matrix. De Bruijn Toroids also don't have to be square; for instance there is a solution the four dictionary solution that fits in a matrix (8 x 32) instead of (16 x 16).

Of course there are multiple equivalent translations of these solutions as any combination of row or column shift is a valid solution. It's also possible to tesselate these tiles perfectly edge to make a map the repeats with the same order frequency.

Digital Paper

Anoto, a Swedish company, has invented, and has numerous patents, concerning the use of digital pens and paper. The Anoto concept is based around a distinct pattern of dots that can be printed onto paper stock. Using a special pen, which contains a small camera, the dot pattern can be read, and exact position on the paper determined.

Whilst not quite the same concept, the Anoto system works by small changes in the displacement in the position of dots from a nominal mean position.


You can find a complete list of all the articles here.      Click here to receive email alerts on new articles.

© 2009-2013 DataGenetics    Privacy Policy