我不想制作1000个密码并将其提供给用户。 密码包含6位数字 - 它们看起来像随机的6位数字。
当用户到达时,除了此密码之外没有任何信息,我想验证它。
我可以通过数据库查找此密码,但我想将此操作的难度从O(N)降低到O(1),其中N是密码的数量。
是否有任何方法可以通过简单的检查方式生成1000个“随机可能”密码?
UPD:现在我正在考虑加密。例如(Python)key = 'top_secret'
N = 1000
passwords = [encrypt(i, key) for i in range(N)]
def check(s):
try:
return int(decrypt(s, key))<1000
except ValueError:
return False
但我想这是一个更好的解决方案
UPD2:例如,3位数和6位数。它们可能是64位和128位
答案 0 :(得分:0)
使用密码作为键创建哈希。在Perl中的示例中,哈希提供恒定时间查找(O(1))。
这可能是这样的:
my %pass;
foreach ( 1 .. 1000 ) {
# generate_next_pass() is your algorithm
# of getting new password.
my $p = generate_next_pass();
$pass{$p} = 1;
}
然后O(1)检查密码是否在哈希中:
# $user_input is a password to be validated.
if ( exists $pass{$user_input} ) {
# password correct
} else {
# password incorrect
}
答案 1 :(得分:0)
如果密码只是 位,您可以将它们用作列表索引:
# Create a list of all possible passwords
pwds = [False for n in xrange(10**6)]
# Make 1000 valid passwords
for j in xrange(1000):
i = random.randint(0, 10**6)
print 'password is {:06d}'.format(i)
pwds[i] = True
查找它们应该是O(1):
testpw = '103076'
if pwds[int(testpw)]:
print 'Password is OK'
else:
print 'Invalid password!'
请注意,六位数密码不是很安全。他们很容易被猜到。
更好的方法是让用户选择密码。然后存储该密码短语的SHA512哈希值作为词典的密钥,例如,用户的数据作为值。当用户给出密码时,将其哈希并查看该密钥是否在dict中。
答案 2 :(得分:0)
不是100%肯定,但您可以生成uuid4并将其存储为身份验证 - &gt;用户名查找,例如:
import uuid
userpass = {uuid.uuid4().hex:'user{:05}'.format(idx) for idx in xrange(1, 1001)}
an_item = next(iter(userpass)) # one we know is in there
for check in (an_item, 'bob'): # 'bob' we know won't be...
print check, 'belongs to', userpass.get(check, '*nobody*')
# 8411d50aa7ec42d8a6b4736284d1837b belongs to user00381
# bob belongs to *nobody*
答案 3 :(得分:0)
由于密码很短,您可能需要使用位图。您需要1000000位= 125000字节〜= 122kB,即相当少的内存。
因此,创建一个bitmap并初始化它(完全取消设置)。生成密码并在位图中设置适当的位。用户尝试登录时检查位图。
您在这里要做的是非常不安全。
您写道,用户仅使用其密码登录,因此,无论您选择哪种数据结构来保存密码,登录系统只需要尝试猜测一个密码。由于1000存在于[0; 1000000范围内[首次尝试输入密码的概率为0,001,这是非常高值)。基本上,正如您所描述的那样,您的系统不会要求输入密码 - 它要求输入用户名。
在某些情况下,6位数的密码可能没问题,但从不使用密码作为用户名+密码。