在python中,如何在循环和范围内生成随机的非重复数字?

在python中,如何在循环和范围内生成随机的非重复数字?,python,for-loop,random,while-loop,range,Python,For Loop,Random,While Loop,Range,嗨,我还是个初学者,有点迷路了。我正在为学校做一个项目,要求我编写不同的小程序来“猜测”给定的密码。这是一个bruteforce程序,我需要它来猜测4个数字密码的所有可能组合,就像旧iPhone上的密码一样。我的问题是,当我使用random.sample时,它会多次生成相同的随机数。我可以使用什么函数,或者我应该更改什么以使给定范围内的随机数不会重复它们自己?我试着做rand.int,但它给了我“TypeError:'int'对象不可编辑” 其他问题: -如何使循环在n==Password4时停

嗨,我还是个初学者,有点迷路了。我正在为学校做一个项目,要求我编写不同的小程序来“猜测”给定的密码。这是一个bruteforce程序,我需要它来猜测4个数字密码的所有可能组合,就像旧iPhone上的密码一样。我的问题是,当我使用random.sample时,它会多次生成相同的随机数。我可以使用什么函数,或者我应该更改什么以使给定范围内的随机数不会重复它们自己?我试着做rand.int,但它给了我“TypeError:'int'对象不可编辑”

其他问题: -如何使循环在n==Password4时停止?即使找到正确的密码,它也会继续。 -在我成功(n==Password4)之前,有没有办法计算失败(n!=Password4)的次数

这是我的代码:

    import random

    Password4 = 1234
    def crack_password():

while True:
    for n in (random.sample(range(1112, 10000), 1)):
        while n == Password4:
            print(n, "is the password")
            break
        if n != Password4:
            print('fail')
            break

    crack_password()
更新:现在使用一个代码,它不会生成随机的非重复性数字,但可以达到我的预期目的。请继续回答最初的问题,非常感谢你们的好意和及时的回答

新代码(计入@roganjosh):


您可能希望在某些规则下检查密码的所有可能值,例如“4位数”或“8个小写字符”。把这些答案作为起点:

  • 用于使用字母表和生成n长度字符串
  • 如果你知道一组不重复的字符
  • 如果您只想格式化左边有零填充的整数(0000,0001,…9999),请参阅如何

如果您真的想以随机顺序尝试所有密码。这更容易通过以下方式实现:

import random
digits = [str(i) for i in range(10)]
s = [''.join([a,b,c,d]) for a in digits for b in digits for c in digits for d in digits]
random.shuffle(s)
real_password = '1234'
i = 0
for code in s:
    if code == real_password:
        print()
        print('The password is: ', code)
        break
    else:
        i += 1
        print(i, ' failures', end='\r')

您有两个
while
循环,因此即使您在找到密码时尝试
中断
,外部(第一个)
while
循环也会重新启动它

如果你想要独特的猜测,那么你必须研究排列。然而,由于可以合理地假设密码本身是随机的,因此随机猜测密码在破解密码时不会比简单地按顺序浏览整个潜在密码列表更有效

试着这样做:

import datetime as dt

Password4 = 5437

def crack_password():
    start = dt.datetime.now()
    for n in range(9999):
        password_guess = '{0:04d}'.format(n)
        if password_guess == str(Password4):
            end = dt.datetime.now()
            print "Password found: {} in {}".format(password_guess, end - start)
            break
guesses = crack_password()

您的代码将始终重复,因为
,而True:
循环这很棘手,因为
int
s不能有前导0。因此,如果密码为0000-0999,则不能将其生成为数字。将密码视为字符串,而不是数字。如果您尝试在某个范围内使用随机密码,而不是按顺序使用,会有什么区别?如果您不知道某些失败的原因,只需逐个从
0000
转到
9999
。顺便说一句,这还计算了作为副产品的故障数。谢谢大家的投入@帕特里克豪:我意识到了我的错误,谢谢:)@AlexH。使用蛮力方法时,难度取决于密码的长度和允许的字符集。密码越长,使用的字符越多,猜测就越困难。这只是因为有更多可能的密码可供尝试。感谢您的帮助。但在实施您的解决方案时仍然存在问题。。。这是新的代码:导入随机密码4=1234位=[str(i)代表范围(10)中的i]s=[''.join([a,b,c,d])代表数字中的a代表数字中的b代表数字中的c代表数字中的d代表数字]random.shuffle(s)代表数字中的代码:而s==Password4:print(s,“是密码”)如果s!=密码4:print('fail')中断,但它所做的只是打印一次'fail',如果我打印,它会给我所有可能的数字,不说哪一个是password@AlexH我更新了我的答案,向你展示了这样一个程序的基本流程。您的问题是在使用不必要的
循环时再次使用了
。我试着在我的IDE上运行你的代码,但没有发生任何事情。我做错了什么(请记住我是最近的初学者)?@AlexH used
是我应该使用的
=
。现在就试试吧谢谢帕特里克:)现在就可以了!您和roganjosh的答案对我都很有用,所以我会将它们标记为正确,并将它们包含在我的更新中(可能会在我需要编写的下一个小程序中使用它们)。如果我在论文中使用你的代码,当然也可以编辑你的代码,你会同意吗?谢谢你的建议!我如何知道在找到密码之前有多少次“失败”(这对我的论文很重要)?或者,是否有一种方法可以测量程序内的时间量/其他变量,以确定找到密码有多困难?@AlexH,因为您按顺序查看密码列表,即0000、0001。。。。然后,如果您发现密码是1234,那么您已经经历了1233次失败:P查找密码没有真正的“困难”。如果随机选择,密码只能在0000到9999之间,那么每次猜测都有可能破解密码,因此在无限次的运行中,每个密码的难度都是相同的(如果使用真正的随机数生成器)。在我的例子中,更高的数字需要更长的时间来破解,因为我们是按顺序进行的。我编辑了我的问题,以消除所有
while
循环,因为它们不需要,并添加了一个timer@AlexH你回答的问题和我回答的是同一个人:)请阅读我的最新评论。数学上的“难度”在这里是无法计算的。@AlexH在现实世界中,人们会更倾向于添加奇数,他们可能会避免在密码中重复数字,例如
1231
,尤其是如果他们相邻,例如
1123
,因为他们感觉不太“随机”。这不是真的,这是人类的心理,超越了这个问题。在心理学之外,它们都同样难以破解。若你们觉得那个是一个
import datetime as dt

Password4 = 5437

def crack_password():
    start = dt.datetime.now()
    for n in range(9999):
        password_guess = '{0:04d}'.format(n)
        if password_guess == str(Password4):
            end = dt.datetime.now()
            print "Password found: {} in {}".format(password_guess, end - start)
            break
guesses = crack_password()