序列密钥生成与验证

0 投票
2 回答
7254 浏览
提问于 2025-04-16 15:10

我正在尝试写一个串行代码生成器和验证器,但我不知道怎么做一个正确的检查。

这是我的生成器代码:

# Serial generator

# Create sequences from which random.choice can choose
Sequence_A = 'ABCDEF'
Sequence_B = 'UVWQYZ'
Sequence_C = 'NOPQRS'
Sequence_D = 'MARTIN'

import random

# Generate a series of random numbers and Letters to later concatenate into a pass code
First = str(random.randint(1,5))
Second = str(random.choice(Sequence_A))
Third = str(random.randint(6,9))
Fourth = str(random.choice(Sequence_B))
Fifth = str(random.randint(0,2))
Sixth = str(random.choice(Sequence_C))
Seventh = str(random.randint(7,8))
Eighth = str(random.choice(Sequence_D))
Ninth = str(random.randint(3,5))


serial = First+Second+Third+Fourth+Fifth+Sixth+Seventh+Eighth+Ninth

print serial

我想做一个通用的检查,这样我的验证代码就能接受任何由这个生成的密钥。

我本来想创建这样的检查:

serial_check = raw_input("Please enter your serial code: ")

# create a control object for while loop
control = True

# Break up user input into list that can be analyzed individually
serial_list = list(serial_check)    

while control:
    if serial_list[0] == range(1,5):
        pass
    elif serial_list[0] != range(1,5):
        control = False

    if serial_list[1] == random.choice('ABCDEF'):
        pass
    elif serial_list[1] != random.choice('ABCDEF'):
        control = False
# and so on until the final, where, if valid, I would print that the key is valid.

if control == False:
      print "Invalid Serial Code"

我知道第二种检查根本行不通,但它只是个占位符,因为我完全不知道该怎么检查。

不过我以为检查数字的方法可以用,但结果也不行。

2 个回答

0

关于你的Python代码,我猜当你写这个的时候:

if serial_list[0] == range(1,5):

你可能是想写这个:

if 1 <= serial_list[0] <= 5:

还有当你写这个的时候:

if serial_list[1] == random.choice('ABCDEF'):

你可能是想写这个:

if serial_list[1] in 'ABCDEF':

你的代码还有其他一些问题,但我相信随着你学习Python,你会逐渐改进的。

从更高的角度来看,你似乎是在尝试构建一个软件激活码生成器或验证器。你需要知道,仅仅生成一串伪随机字符,然后检查每个字符是否在范围内,这是一种非常弱的验证方式。如果你想防止伪造,我建议你了解一下HMAC(如果你在安全的服务器上进行验证)或者公钥加密(如果你在用户的电脑上进行验证),并把这些知识融入到你的设计中。Python有一些库可以帮助你实现这两种方法。

1

表达式 `range(1, 5)` 会生成一个从 1 到 4 的数字列表。所以在你的第一个测试中,你是在问你的序列号的第一个字符是否等于这个列表:

"1" == [1, 2, 3, 4]

可能不是……

你其实想知道的是某个数字是否在这个范围内(也就是从 1 到 5,我猜,不是从 1 到 4)。

另外一个问题是,序列号的第一个字符是字符串,而不是整数,所以你需要把第一个字符转换成整数。但如果它不是数字,这样做会出错。所以你得先检查一下,确保它是数字:

if serial_list[0].isdigit() and int(serial_list[0]) in range(1, 6):

别担心,如果它不是数字,Python 甚至不会去执行 and 后面的部分。这种情况叫做短路。

不过,我不建议你这样做。相反,直接检查一下它是否至少是 "1" 并且不超过 "5",像这样:

if "1" <= serial_list <= "5":

你可以用同样的方法检查每一个测试,只需要改变你要检查的内容。

而且,你不需要把序列号转换成列表。serial_check 是一个字符串,通过索引访问字符串是完全可以的。

最后,你的代码中有一个模式:

if thing == other:
   pass
elif thing != other:
   (do something)

首先,因为你测试的条件是逻辑上的相反,所以你不需要 elif thing != other —— 你可以直接用 else,这就意味着“任何没有被 if 条件匹配的情况。”

if thing == other:
   pass
else:
   (do something)

但是如果你在条件满足时只是 pass,那为什么一开始不直接测试相反的条件呢?你显然知道怎么写,因为你之前放在了 elif 中。直接放在 if 里就行了!

if thing != other:
    (do something)

是的,你的每个 if 语句都可以轻松减半。在我给你的检查字符范围的例子中,最简单的方法可能是使用 not

if not ("1" <= serial_list <= "5"):

撰写回答