I'd like to generate a QR code (or some other 2D barcode) that would include a HMAC of its contents. Since it's a printed QR code, and since it will already contain a fair amount of data, I'd like the HMAC overhead to be as small as possible, while still making it reasonably difficult to crack.
By "reasonably difficult" I mean "for an average guy with a gaming PC". In addition, the content is not super sensitive - it's a ticket with a value of 20€ or less. Mostly less. Plus the HMAC key can be regularly rotated (say, once per day), and the tickets will not be valid for more than 30 days at most. Therefore I'm not worried about people who have access to mainframes and months of cracking time.
With such low security requirements, I think that a fairly short HMAC should do the trick - if it's done right - but I don't know which one to use. The typical ones you see everywhere are based on something no less than SHA1 (preferably SHA256), but that's already 160 bits, which will make a QR code substantially bigger. Are there any shorter options available?
Added:
People have raised many valid questions and I think that I have been too vague. My apologies. I'll clarify:
The tickets in question are for public transportation, so they can potentially include quite a bit of info - ID, routes, weekdays, validity period, stop combinations, fare reductions, ride counts - just to name a few. As such the QR code can easily become pretty big, and therefore the rate of scanning problems will rise too. Hence I'm interested in shaving off as many bits as possible.
I'm also aware that it's all too easy to copy a printed barcode. The main validation method will always be an online one. But as the transport moves, especially through remote areas of the country, mobile networks might not always be available. Or you know, noting is perfect, and the backend validation servers can suffer downtime too. The HMAC then is a fallback method for validation in cases when online validation is unavailable. This is actually another barrier for the potential adversary, because their attacks will only work when the validation device is offline. Plus, even when offline, the validation devices can retain a local history of recently validated tickets, so two people using the same ticket in the same ride would not work.
All in all, I believe that while such a scheme isn't completely watertight, the risks are low enough to be acceptable. The barrier for a successful attack is high enough that it will not be a common occurrence; and even if someone does somehow manage to pull it off, the lost fares are not that large.