创建一个小的(<10位)、不(非常)安全的“哈希”的想法
-
23-08-2019 - |
题
我正在开发一个在线活动票务系统,用户可以自行打印门票并出现在活动现场,门票将被扫描(条形码),理想情况下该人将进入。我的问题是如何创建满足以下要求的“票证代码”:
- 每个“票证代码”需要彼此足够不同(即不按顺序编号)
- 理想情况下,票证将根据中央数据库进行检查,以防止重复使用,但它也需要能够离线工作,在这种情况下,系统必须检查“有效”票证代码,并且它尚未被使用 这 门。
- “票证代码”必须足够小,以便在需要时方便键入
- 持票人只需凭票即可入场(即无需检查身份)
数据范围很小,4天内只会有大约20个活动,每个活动大约5,000张门票(大约100,000个不同的门票代码)
现在,我有几个未打印在票证上且用户不知道的字段,我可以使用它们对“票证代码”的一部分进行编码,因此我可以使用 EventId、OrderId、EventDate 和一些盐来创建一个小的“ hash”作为部分代码(想法?),但我仍然坚持使用连续的票证 ID 或 GUID(会太长)
那么关于如何做到这一点有什么想法或指示吗?
其他提示
为什么要重新发明轮子?只需做这样的事情(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
我建议你给 Verhoeff算法 尝试一下。
我可以看到两种方式:
- 生成一个随机数,或者至少是一个数字的随机部分,并将其存储在中央数据库中。然后将数据库下载到所有门禁系统中进行检查。
- 数量必须是自给自足的。换句话说,该号码必须能够在没有保存列表的情况下结帐。这听起来像是某种校验和系统。例如,您可以发出 1 及以上的数字,将其设置为 5 位数字(00000-99999 = 100.000 个数字),并在前面添加 1-3 个字母,确保最终得到可以检验的校验和。
对于离线验证,我只看到一种简单的解决方案。
将票证 ID 的哈希值和每个事件的盐附加到票证 ID 上。您可以将任何加密哈希截断为所需的大小。除了基本票证 ID 本身的随机数之外,我想不出使用任何其他内容的具体原因。
这允许您限制票证 ID 的大小,并具有与票证 ID 大小相关的明确比例的安全性。
您可以进行 CRC 计算。
基本上,只需开始添加字符串中的每个字符,并将长度限制为长整数。
您可以从一个已知的随机数开始,并将其存储在前 4 个字节中,然后将后 4 个字节作为我之前描述的计算。
这将是两个整数,或八个字节。
这是一种方案,其优点是可以让您根据上一张票计算下一张票的哈希值(这样您就可以验证一张票是否丢失),但不允许外人计算下一张票:
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 也不是不可能,并且为您提供了 256 倍的票证 ID)
不隶属于 StackOverflow