I plan on doing a "ticketing" system, where a user would buy a "tour ticket" online. The part that I'm puzzled about is: After they buy, what mechanism to use to verify the ticket?

I've been looking at how platforms like EventBrite, TicketMaster, and they use either QR code or bar-code. But I think for something like my tours (where I don't expect more than 1000 people at a time), is an overkill. Why not just use a simple 5-letter combination, with 26^5 combinations, like GFTLH? Is there any disadvantage of doing this from a security perspective vs. a barcode?

The only reason I see these platforms using QR/barcodes is the sheer amount of ticket (millions they sell). Using a simple 5-character code provides some advantages like:

a) Bigger % of people will be able to verify the code. Even people with dumb phones, I could make a system where they just SMS the code and get an SMS in return if the code is valid.

b) Since the code is more "portable" (everyone with a piece of pen can write it), there are options like: Create printed cards with a placeholder for the code, and just have the buying/filling instructions on the card. This is impossible to do with a QR code (and is very cumbersome with a barcode). So basically, I could then distribute those cards to various venues. It's like "your placeholder ticket you can activate online whenever you want".

But my ques was, is there any disadvantage from a security perspective, considering these factors? It's a bit weird to me, I haven't seen any ticketing platform (even self-hosted ones) use this system, they use all use ticket/QR codes vs. convenient pass-phrases.

3 Answers 3


If there's any advantage on breaking your system, someone sooner or later will break your system.

There are not a big difference between generating and managing 5 digit codes versus 64 digit codes. So going with 5 or 64 is the same amount of work. The main difference is the difficulty of bruteforcing 5 or 64 digits.

You could create a structure like that: TICKET_ID:EV_ID:CHECK

Where, for example, TICKETID is 8 chars, EV_ID is 3 chars, and CHECK is 5 chars, with 16 bytes total. CHECK must be calculated using a digital signature, and truncating the result to the first 5 digits. You can make it all caps, and avoid using the numbers 0 and 1, and capital O and I, because they are easily mistaken one for the other with certain fonts.

So the ticket ABCDE456AAA23F78 would be:

Ticket ID: ABCDE456

Event ID: AAA

Check: 23F78

enter image description here

When generating the new tickets, you must hash the ticket ID and event ID, and digitally sign the result. When checking the validity, don't just hash and verify. You must verify if the ticket ID is exact 8 chars long, the event ID is exact 3 chars long, and then hash and check. Verify if the avoided chars are present too. Doing this, the probability of a collision is lowered.


  • Small QR-Code
  • 16 digits are easy to write down
  • Confusing chars removed
  • Dumb phones can check the validity
  • Difficult to forge
  • Checking the code can be done offline, with a small Javascript powered HTML page

The main downside is the small check length. 5 digits is not very difficult to crack, but you can increase this size to a full 64-byte signature.

Using this scheme you can create around 33 million tickets per event, and create 10 events per week for the next 63 years without using all event IDs.

  • I'm not talking about 5 digits, but 5 characters, so that's 26^5 combinations. How would someone "crack" something in this context? The whole "flow" of the process is: a) Someone goes and makes an order for a ticket b) The system gives him a totally random 5-length-long character: eg (AGDFJ). c) He then goes (in person) to the venue, which then checks if his 5-character-length long is "active".
    – anemaria20
    Sep 2, 2018 at 1:58
  • While I appreciate the suggested system, 10+ character is very impractical. Consider that typing is a slow and painful process on dumb phones, and this would take up to a minute to type. So 5 characters is the sweet spot, I'd go 6 max. I'm talking about small scale here, at its peak, there should be no more than 3000 "active" tickets. So is it possible to produce a system similar to what you suggested with just 6 characters?
    – anemaria20
    Sep 2, 2018 at 2:02
  • Checking "offline" is a no-no in this situation, because I'm talking about tour tickets, which "expire" after a certain period. So more like an "access-pass" which must be checked online for whether it's still valid. Maybe this was a source of confusion, these codes will be checked against a central database, they are simple IDs. There will be no particular pattern of generating them, the flow is: User purchases a pass -> A random ID is generated -> ID is added to the DB.
    – anemaria20
    Sep 2, 2018 at 2:10

I agree with ThoriumBR's answer, and would only like to address the "security perspective".

Five letters, 26 characters each, gives you the total number of 12M combinations (11,881,376). This might sound like a large number. However if someone writes a scraper trying to brute-force your codes which uses 50 concurrent connections, and runs ten instances of such scraper, they would try 500 codes per second, and will go through ALL your codes in less than 7 hours. And running 10x50 scraper is available to pretty much everyone.

This could of course be countered by other means (for example captcha), but this creates other issues, notably usability.

  • The number quickly increases to 308 million if I introduce 1 more character. What you're describing is a DDoS-like attack that could easily be mitigrated using CloudFlare + Google ReCaptcha, without the means to sacrifice usability, because ReCaptcha can be configured to show only to people which Google considers to be bots (especially with v3: developers.google.com/recaptcha/docs/v3).
    – anemaria20
    Sep 2, 2018 at 10:24
  • Indeed, adding more characters increases the security against brute force attack.
    – George Y.
    Sep 3, 2018 at 20:47

The first thing to consider is if this is an online only redemption, or if you have humans checking in at a gate. An online system can be brute-force attacked by millions of machines, but people won't allow one customer millions of retries.

In the case of a human system, you can set the minimum size based on the risk you're willing to take: typically a ticket forger won't risk it for a 1:1000 chance. So if you are issuing 1000 tickets, your number space would be 1000*1000, or 1 million (6 digits).

If you try to compress that to 4 or 5 characters by using a digit/text scheme, you then have to think of the humans using it, and the environment they will be in. Don't make it case sensitive. Print the tickets in upper-case bold letters. Don't allow confusing/ambiguous symbols - eliminate letter I and digit 1, 0 and o, B and 8, etc., or make them synonymous. If the ticket takers are in a dark theater, this becomes even more important. If customers are printing their passes at home, a damp/wet environment will cause the printing to run. And you may want to scan your generated codes with a bad word detector.

Note that by themselves, barcodes don't make anything secure. They exist only to make data entry easier. Because a QR code can deliver many bytes of data accurately and quickly, they can pass bigger payloads; but they are easy to copy regardless of their size.

Check digits are optional, but consider them for entry of more than 5 digits.

If your ticket takers are using a phone app to enter the codes, also consider that an alpha keyboard is smaller, and harder to accurately type on than a 10-digit numeric pad. The 7 digit codes might be faster to tap in than 5 letters, and almost certainly faster than a 5 character mixed alphanumeric code.

  • I'm thinking of only alpha-characters. Typing only numeric has an usability hinderance in some Phones, they're showed by you activating a "numeric" keyboard on the default letter keyboard, and the moment you type a number, the keyboard is back to its default "letters" mode.
    – anemaria20
    Sep 3, 2018 at 1:59

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .