
How to generate a verification code/number?我正在开发一个应用程序,其中用户必须拨打电话并用手机的键盘输入验证码。 我希望能够检测到他们键入的数字是否正确。电话系统无法访问有效号码列表,但会根据算法(例如信用卡号)验证号码。 以下是一些要求:
鉴于这些要求,您将如何生成这样的数字? 编辑: @Haaked:该代码必须为数字,因为用户使用其手机进行了键入。 @matt b:第一步,代码显示在网页上,第二步是调用并键入代码。我不知道用户的电话号码。 后续:我发现了几种算法来检查数字的有效性(请参阅此有趣的Google Code项目:checkDigits)。 经过研究,我认为我将采用ISO 7064 Mod 97,10公式。由于它用于验证IBAN(国际银行帐号),因此看起来非常可靠。 公式很简单: 测试:
显然,该算法捕获了大多数错误。 另一个有趣的选择是Verhoeff算法。它只有一个验证码,并且更难以实现(与上面的简单公式相比)。 对于1M组合,您需要6位数字。为了确保没有任何意外有效的代码,我建议使用9位数字,并且有1/1000的机会使用随机代码。我还建议使用另一个数字(共10个数字)执行完整性检查。就分发方式而言,随机就足够了,校验位将确保单个错误不会导致正确的代码。 编辑:显然我没有完全阅读您的请求。使用信用卡号,您可以对其进行哈希处理(MD5或SHA1或类似的名称)。然后,您在适当的位置截断(例如9个字符)并将其转换为10。然后添加校验位,这或多或少会适合您的目的。 您想对代码进行分段。它的一部分应该是其余代码的16位CRC。 如果您只需要一个验证号,则只需使用一个序列号(假设您有一个生成点)。这样,您就知道不会重复。 然后,为该序列添加该序列号的CRC-16前缀和一些私钥。您可以将任何东西用作私钥,只要您将其保持私密即可。使它变大,至少要有一个GUID,但这可以是古腾堡项目给《战争与和平》写的文字。只是需要保持秘密和不断。拥有私钥会阻止人们伪造密钥,但是使用16位CR使其更容易破解。 要进行验证,您只需将数字分为两部分,然后对序列号和私钥进行CRC-16校验。 如果要进一步遮掩顺序部分,则将CRC分为两部分。将3位数字放在序列的前面,再将2位放在序列的后面(零填充,因此CRC的长度是一致的)。 此方法还允许您从较小的键开始。前10个键将是6位数字。 一定只是数字吗?您可以创建一个介于1到1M之间的随机数(尽管我建议更高),然后Base32对其进行编码。您需要做的下一件事是对值(使用秘密盐值)进行哈希处理,然后base32对哈希进行编码。然后将两个字符串附加在一起,也许用短划线隔开。 这样,您可以通过算法验证传入的代码。您只需使用代码的左侧,使用您的秘密盐对其进行哈希处理,然后将该值与代码的右侧进行比较即可。 您已链接到支票号码项目,并且使用"编码"功能似乎是一个不错的解决方案。它说:
因此,听起来您可以将编码函数传递给数据库密钥(例如5位数字),并且可以得到一个满足您要求的数字。 听起来您有一个不言而喻的要求,即必须通过算法快速确定该代码有效。这将排除您仅分发一个时区号码列表的可能性。 过去人们有几种方法可以做到这一点。 还有很多其他选项,但是这些选项很常见且易于实现。 -亚当 假设您已经知道如何检测用户按下了哪个键,那么应该可以轻松地做到这一点。在安全领域中,存在"一次性"密码的概念。有时将其称为"一次性密码"。通常,这些值仅限于(易于键入的)ASCII值。因此,[a-zA-z0-9]和一堆易于键入的符号。如逗号,句号,半冒号和括号。不过,就您而言,您可能希望将范围限制为[0-9],并可能包括*和#。 我无法解释如何充分生成(或工作)这些一次性代码的所有技术细节。它背后有一些中级数学,我会亲自屠夫而无需先对其进行复习。可以说您使用一种算法来生成一次密码流。无论您之前知道的代码多么简单,后面的代码都应该是不可能的!就您而言,您只需将列表中的每个密码用作用户的随机代码。 除了直接自己解释实现的细节外,我还将带您转到9页的文章,您可以自己自己阅读该文章:https://www.grc.com/ppp.htm 创建验证码时,您可以访问呼叫者的电话号码吗? 如果是这样,我将使用呼叫者的电话号码并通过某种哈希函数运行它,以便您可以确保在步骤1中提供给呼叫者的验证码与他们在步骤2中输入的验证码相同(以确保他们没有使用朋友的验证码,或者只是做出了非常幸运的猜测)。 关于哈希,我不确定是否可以采用10位数字并得出小于10位的哈希结果(我想您必须承受一定的冲突),但是我认为这将有助于确保用户就是他们所说的。 当然,如果步骤1中使用的电话号码不同于他们在步骤2中呼叫的电话号码,则此方法将无效。
好吧,如果您希望它具有至少一百万个组合,那么您至少需要六位数字。够短吗? |