想要创建一个小的(<10位数),而不是(非常)安全的“哈希”

时间:2009-05-21 00:33:49

标签: encryption hash checksum encode

我正在开发一个在线活动票务系统,在这个系统中,用户可以自行打印他的票据并出现在将被扫描的事件(条形码),理想情况下,这个人会进入。我的问题是如何创建满足以下要求的“票证代码”:

  • 每个“票证代码”需要彼此充分不同(即不按顺序编号)
  • 理想情况下,将针对中央数据库检查故障单以防止重复使用,但是它也需要能够脱机工作,在这种情况下系统必须检查“有效”的故障单代码并且它还没有用于门。
  • “票证代码”必须足够小,以便在需要时进行键控
  • 门票持有人只需要门票进入(即没有身份证检查)

数据范围非常小,4天内只有大约20个活动,每个活动约5,000张门票(约100,000个不同的门票代码)

现在我有几个字段未打印在故障单上,用户不知道我可以使用它来编码部分“故障单代码”,因此我可以使用EventId,OrderId,EventDate和一些盐来创建部分代码(想法?)的小“哈希”,但我仍然坚持顺序或GUID(太长)的票证ID

关于如何做到这一点的任何想法或指示?

7 个答案:

答案 0 :(得分:12)

为什么重新发明轮子?做这样的事情(Python代码,问我是否需要澄清):

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]

示例:

活动编号1

票号123

createticket(1,123)
# output: 2d7f242597

先生售票员带着他的验证员到场,并输入事件/票号和哈希:

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

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

答案 1 :(得分:5)

我建议你试试Verhoeff algorithm

答案 2 :(得分:3)

我可以看到两种方式:

  1. 生成一个随机数,或至少为数字的随机部分,并将其存储在中央数据库中。然后将数据库下载到所有门系统中进行检查。
  2. 这个数字必须是自给自足的。换句话说,该号码必须能够在没有保存列表的情况下结账。这听起来像某种校验和系统。例如,你可以发出1和更高的数字,使它们成为5位数字(00000-99999 = 100.000数字),并预先输入1-3个字母,确保你最终得到一个可以结账的校验和。

答案 3 :(得分:1)

考虑一个基于Feistel网络的非常简单的方案来置换票证ID号码。 This message(恰好在PostgreSQL列表中,但与PostgreSQL没有太大关系)描述了一个简单的Feistel network。在每个票证上,您可以打印票证ID号码(按顺序选择),然后打印“票证密码”,这是通过Feistel网络输入ID号的结果。可能的变化包括在密码上附加一个校验位,并将输入基于Feistel网络,而不仅仅是顺序生成的数字(数字+ 10,000 *事件ID号等)。

答案 4 :(得分:0)

对于离线验证,我只看到一个简单的解决方案..

在故障单ID中附加故障单ID和每事件salt的哈希值。您可以将任何加密哈希截断为所需的大小。我想不出有什么特别的理由可以使用除随机数之外的任何基本票ID本身。

这允许您限制故障单ID的大小,并且与故障单ID的大小具有明显成比例的安全性。

答案 5 :(得分:0)

您可以进行CRC计算。

基本上,只需开始在字符串中添加每个字符,并将长度限制为一个长整数。

您可以从已知的随机数开始并将其存储在前4个字节中,并将最后四个作为我之前描述的计算。

这将是两个整数,或八个字节。

答案 6 :(得分:0)

这是一个方案,它的优点是可以让你从前一个计算下一个票证哈希值(这样你就可以验证是否缺少一个),但不允许外人计算下一个:

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

,其中

  • HASH是任何散列函数,它在输出字符串
  • 中相对均匀地分配其熵
  • SALT是你保密的常数;为每个活动使用不同的活动
  • 是个好主意
  • IV是你保密的另一个常数
  • LENGTH是您想要的故障单ID的长度(问题中的10个,但12个不是不可能的,并且给您的票证ID是256倍)