Encryption 创建一个小的(<;10位数字),不(非常)安全的”的想法;“散列”;

Encryption 创建一个小的(<;10位数字),不(非常)安全的”的想法;“散列”;,encryption,hash,checksum,encode,Encryption,Hash,Checksum,Encode,我正在开发一个在线活动票务系统,在该系统中,用户将能够自行打印自己的票务,并在活动中显示,在活动中,票务将被扫描(条形码),理想情况下,该人将进入。我的问题是如何创建满足以下要求的“票证代码”: 每个“票证代码”需要彼此有足够的差异(即不按顺序编号) 理想情况下,将根据中央数据库检查票证,以防止重复使用,但它也需要能够离线工作,在这种情况下,系统必须检查“有效”票证代码,并且该票证代码未在该闸门中使用 “票证代码”必须足够小,以便在需要时键入 持票人只需凭票进入即可(无需身份证检查) 数据范

我正在开发一个在线活动票务系统,在该系统中,用户将能够自行打印自己的票务,并在活动中显示,在活动中,票务将被扫描(条形码),理想情况下,该人将进入。我的问题是如何创建满足以下要求的“票证代码”:

  • 每个“票证代码”需要彼此有足够的差异(即不按顺序编号)
  • 理想情况下,将根据中央数据库检查票证,以防止重复使用,但它也需要能够离线工作,在这种情况下,系统必须检查“有效”票证代码,并且该票证代码未在该闸门中使用
  • “票证代码”必须足够小,以便在需要时键入
  • 持票人只需凭票进入即可(无需身份证检查)
数据范围非常小,4天内只有大约20个活动,每个活动大约5000张门票(大约100000个不同的门票代码)

现在我有几个字段没有打印在票证上,用户也不知道,我可以用它们来编码“票证代码”的一部分,所以我可以使用EventId、OrderId、EventDate和一些salt为部分代码创建一个小的“散列”(ideas?),但我仍然坚持使用顺序票证id或GUID(太长了)

那么,关于如何做到这一点有什么想法或建议吗?

我建议您尝试一下。

我可以从两个方面看到:

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

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

    在票证ID后面附加票证ID的哈希和每个事件的salt。您可以将任何加密哈希截断为所需的大小。我想不出有什么特别的原因可以对基本票证ID本身使用随机数


    这允许您限制票证ID的大小,并与票证ID的大小具有明显的比例安全性。

    考虑一个基于Feistel网络的非常简单的方案,以排列票证ID号。(这恰好在PostgreSQL列表中,但实际上与PostgreSQL没有太多关系)描述了一个简单的例子。在每张票据上,您可以打印一个票据ID号(按顺序选择),然后打印一个“票据密码”,这是通过Feistel网络输入ID号的结果。可能的变化包括在密码后附加一个校验位,并将输入到Feistel网络的数据建立在不仅仅是顺序生成的数字(数字+10000*事件ID号,等等)的基础上。

    您可以进行CRC计算

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

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


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

    这里有一个方案,它的优点是允许您从上一个计算下一个票证哈希(以便您可以验证是否缺少一个),但不允许外部人员计算下一个票证哈希:

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

    • HASH
      是将其熵相对均匀地分布在输出字符串上的任何哈希函数
    • 是你一直保守的秘密;每个事件使用不同的事件是一个好主意
    • IV
      是你保守秘密的另一个常量
    • LENGTH是您想要的票证ID的长度(在您的问题中为10,但12不是不可能的,并且为您提供256倍的票证ID)

      • 为什么要重新发明轮子?只需这样做(Python代码,如果需要澄清,请询问我):

        例如:

        事件1

        123号车票

        createticket(1,123)
        # output: 2d7f242597
        
        ticketman先生带着他的验证器过来,输入事件/票号和散列:

        def verifier(eventnum, ticketnum, hash):
            return hash == createticket(eventnum, ticketnum)
        
        verifier(1,123, "2d7f242597")
        # ouput: True
        

        如果计算机关机,则无法验证。或者你是建议门口的计算机从头开始计算车票号码?我看到的问题是,门口的计算机无法验证给定的车票是否有效,因为它没有本地的所有车票。或者我遗漏了什么?我假设任何解决方案都必须有所有生成票据的数据库的本地副本。此解决方案的优点是可以从4元组脱机生成数据库。如果NumberOfTicketsSeld发生变化(b/c有人在节目开始前7分钟在线购买了一张),那么很容易向数据库中添加更多的值。然而,如果没有4元组,这些值很难计算。@jmucchiello你不能让“门口的计算机从头计算到票号”,因为票证可能无效,所以程序永远不会停止。这就是为什么您需要NumberOfTicketsSeld。理想情况下,我可以访问中央数据库,在那里我可以验证票据a)有效,b)以前没有使用过。问题在于我失去了与中央数据库的所有连接,因此我无法更新本地数据库,也无法验证有效/未使用的票号,在这种情况下,为了不阻止人们进入,只需确保票号代码不是伪造的,并且没有在该登机口使用(这些信息可以在本地保存),让这个人进来。也许我没有弄清楚,但是我的完整哈希(ala md5)的问题是我没有用于验证的票证号,因此我无法创建用于验证的哈希。今年五月
        def verifier(eventnum, ticketnum, hash):
            return hash == createticket(eventnum, ticketnum)
        
        verifier(1,123, "2d7f242597")
        # ouput: True