Using playing cards to store hidden data:
The Implied Card Method for
Encoding Data Into Playing Cards.
[Last updated: 9th March, 2014 16:12 GMT]
Data, codes and messages can be hidden in the seemingly random order of a deck of playing cards. Here I explain my straightforward method of encoding binary bits into a deck of cards which will result in more bits of data being stored than there are cards. I have no idea if this method already exists, but I haven't seen it anywhere else yet. The method can also be used to encode letters of the alphabet (English or otherwise) in a way that, on average, fewer than two cards are needed to represent one letter. In more straightforward methods these would be impossible. My method also lends itself to encrypting the data held within the cards to the security level of a one-time pad. The concept lends itself to other media outside of the world of cards in a way that allows for carefully chosen, already existing rows of objects to represent newly encoded messages.
Having a vague understanding of binary will help in understanding the following explanations. The basis of my ideas here treat each card as a binary "bit". In this way each card represents either a one or a zero.
How it works:
There are two related methods: the Basic Implied Card Method and the Recursive Implied Card Method. The Basic Implied Card Method is more straightforward to encode and decode, but has a lower capacity for storing data.
The Basic Implied Card Method:
The method involves having a set order for a pack of cards. Each card's position in the pack represents a 1 or 0. If the card is absent from its position, then there is an implied 0; if the card is present then it represents a 1. As we know the order of the pack we can tell if a card is absent. As an example, if the second card of a pack is absent, but the first, third and fourth are present, then the binary bits represented are 1, 0, 1, 1.
If we put the removed cards at the back of the pack as we do the encoding, then we can use those cards again when they next come around. The previously absent cards will have their own calculable order and we can continue to know which cards are absent from their correct position all the way through the pack.
The more 0s in our binary number, the fewer cards we will need to encode it. A 0 bit doesn't reduce the number of cards available for further numbers.
The Basic Method used to encoding letters of the alphabet:
If we map the 26 letters of the English alphabet ordered by frequency onto 5-bit binary numbers ordered by the number of 1s in them, then we can encode text fairly efficiently. To start with, the letter "e" will be represented by 00000 and so every "e" won't reduce the number of cards available to encode further letters. The next most common letters will use the fewest amount of cards. Paradoxically, if we use 7-bit binary numbers to encode cards, despite using longer numbers, we will end up using fewer cards and being able to store longer messages. This is because all the letters of the alphabet can be represented by binary numbers containing two or fewer 1s in them. All the zeroes will be reused for later letters.
The Recursive Implied Card Method:
This is an addition to the Basic Method which can encode even more binary numbers. It takes advantage of the fact that it's possible to deduce which cards were used to represent 1s in the first part of an encoded pack before the point where the "absent" cards were reused, by looking at the state of the pack later on. As we can work this out, we don't actually need those cards to be in the final pack for it still to be decoded correctly. These cards can therefore be used again to represent more binary numbers. A proportion of *these* reused cards can again have their existence and position deduced from later cards, which again means they don't need to be there, and they too can be used again. We can keep reusing cards in this way for several iterations depending on the nature of the binary numbers being encoded into the cards.
The Recursive Method works well when encoding text too.
The two methods can be decoded by anyone who understands the encoding method, however any decoding relies on knowing the original order of the pack of cards. Without knowing the original order of the cards, it would be impossible to decode them. If the cards are shuffled before the encoding starts, the encoded data will end up encrypted to the level of a one time pad. The only way to recover the data would be to know the original order. One way of keeping a record of the original order is to duplicate it with a second pack of cards before the encoding begins.
Using the methods outside of the world of cards:
The methods work not only with playing cards, but also with any series of items that have an implied set order. For example, words in sentences, piles of coins and so on.
Points about the methods:
- The maximum theoretical number of bits that can be encoded into a pack of cards without compression is 225 (actually 225.581 = log2(52!)). This is because there is only a set number of permutations of the cards in the pack (the factorial of 52).
- The number of bits that can be encoded into a pack of cards in practice depends on the nature of the bits being encoded. Therefore predicting how much we can encode is difficult.
- If the number we are encoding consists entirely of 1s then the pack can only contain 52 bits. As there are no 0s, no cards can be reused. We can't use the Recursive Method either as there is nowhere to split the pack.
- I'm only aware of two proper flaws where the basic or recursive methods will fail:
1: If there are multiple 0 bits encoded at the very end of the pack, then these can end up being decoded as nonsense or not decoded at all. If there are ten cards left in the encoding and we want to encode 10 consecutive 0 bits then we would pass them all to the back of the pack where they would end up in exactly the same position as before. Therefore to avoid this, the encoding sometimes has to stop while there are still unused cards left.
2: If there are cards that remain unused at the end of the pack, then they will be decoded as 1s. When decoding text, it is obvious that we have reached the end of the message, but when decoding binary numbers of an uncertain length, there are situations when it might become confusing - it might not be clear if the end of the message is all 1s or if we have finished the message. One way to reduce this problem is to work in 4-bit (or higher) groups rather than with individual bits. If we work with 4-bit numbers and there are three cards left at the end of the pack, then we know for sure to ignore them. Another option, if we are using set bit length numbers, is to select a particular number to act as an escape character.
- On various websites linking here, people have mentioned Bruce Schneier's "Solitaire
" idea as featured in the book "Cryptonomicon" by Neal Stephenson. My and Bruce Schneier's methods are unrelated, save for the fact they both use cards and can be used for encryption. My method stores data *within* a deck of cards, whilst his uses the deck as a key to encrypt data kept elsewhere. His method is more useful if you want to encrypt a lot of data, while mine could be more useful if you want to smuggle a short hidden message without any possibility of detection. Although I was vaguely aware that Bruce Schneier had invented a card encryption system, I didn't really understand what it did until after I had thought this up and decided to make sure I wasn't just copying him.
The rest of these pages give a thorough explanation of the Implied Card Method with various examples.