Ideas to create a small (<10 digits), not (very) secure “hash”

这一生的挚爱 提交于 2019-11-28 17:06:13
kquinn

Consider a very simple scheme based on a Feistel network to permute, say, the ticket ID number. This message (which happens to be on the PostgreSQL lists but doesn't really have much to do with PostgreSQL) describes a simple Feistel network. On each ticket you could print a ticket ID number (sequentially chosen), then a "ticket secret code" that's the result of putting the ID number through a Feistel network. Possible variations include appending a check digit to the secret code, and basing the input to the Feistel network on more than just the sequentially generated number (number + 10,000 * event ID number, et cetera).

Why reinvent the wheel? Just do something like this (Python Code, ask me if you need clarification):

import hashlib

secretpassword = "blah"

def createticket(eventnum, ticketnum):
    m = hashlib.md5() # or any crypto hash you like
    m.update("%s%s%s" % (eventnum, ticketnum, secretpassword))
    return m.hexdigest()[:10]

Example:

Event Number 1

Ticket Number 123

createticket(1,123)
# output: 2d7f242597

Mr ticketman comes around with his verifier and enters in the event/ticket number and the hash:

def verifier(eventnum, ticketnum, hash):
    return hash == createticket(eventnum, ticketnum)

verifier(1,123, "2d7f242597")
# ouput: True

I suggest you give the Verhoeff algorithm a try.

Two ways I can see:

  1. Generate a random number, or at least a random part for a number, and store it in a central database. Then download the database into all the gate systems to check against.
  2. The number has to be self-sufficient. In other words, the number has to be able to check out without the saved list. This sounds like some kind of checksum system. For instance, you could issue numbers from 1 and upwards, make them 5 digits (00000-99999 = 100.000 numbers), and prepende 1-3 letters, making sure you end up with a checksum that would check out.

For offline verification, I see only one easy solution..

Append to the ticket ID a hash of the ticket ID and a per-event salt. You can truncate any cryptographic hash to the size desired. I can't think of a particular reason to use anything but a random number for the base ticket ID itself.

This allows you to limit the size of the ticket ID and have a clearly proportional security in relation to the size of the ticket ID.

You could do a CRC calculation.

Basically, just start to add each character in the string, and limit the length to a long integer.

You may start with a known random number and store it in the first 4 bytes, and have the last four be a calculation as I described earlier.

This would be two ints, or eight bytes.

Here's a scheme that has the advantage of letting you calculate the next ticket hash from the previous (so you can verify whether one is missing), but doesn't let outsiders calculate the next one:

Ticket.0 = substring(HASH(SALT + IV        ), 0, LENGTH)
Ticket.i = substring(HASH(SALT + Ticket.i-1), 0, LENGTH)

where

  • HASH is any hashing function that distributes its entropy relatively evenly across the output string
  • SALT is a constant you keep secret; it's a good idea to use a different one for each event
  • IV is another constant you keep secret
  • LENGTH is the length of the ticket ID you want (10 in your question, but 12 is not out of the question and gives you 256 times as many ticket IDs)
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!