How to generate random non-recurring numbers in a loop and within a range in python?
<blockquote>
  <p>Hi, I'm still a beginner and a bit lost. I'm working on a project for school that requires me to write different small programs that will 'guess' the given password. This is a bruteforce program, and I need it to guess every possible combination of 4 number passwords like those on the old iPhones. My problem is that when I use random.sample it generates the same random numbers multiple times. What function can I use, or what should I change so that the random numbers within the given range don't repeat themselves? I tried doing rand.int but it gave me "TypeError: 'int' object is not iterable"</p>
  
  <p>Additional questions: 
  - How do I get my loop to stop once n == Password4 ? It simply continues, even after the correct password is found.
  - Is there a way I can count the number of fails(n != Password4) before my success (n == Password4)?</p>
</blockquote>

<p>This is my code:</p>

<pre><code>    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()
</code></pre>

<p>Update: Using a code now that does not generate random non-recurring numbers but works for the purposes I intended. Please still feel free to answer the original questions, and thank you all so much for your kindness and prompt responses.</p>

<p>New Code (credit goes to @roganjosh):</p>

<pre><code>    import datetime as dt

    Password4 = 9999

    def crack_password():
        start = dt.datetime.now()
        for n in range(10000):
            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()
</code></pre>

<p>You have two <code>while</code> loops, so even though you attempt to <code>break</code> when you find the password, the outer (first) <code>while</code> loop just starts it off all over again.</p>

<p>If you want unique guesses then you would have to look into permutations. However, since it's reasonable to assume that the password itself would be random, then random guesses of that password would be no more efficient at cracking the password than simply going through the whole list of potential passwords sequentially.</p>

<p>Try something like this:</p>

<pre><code>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()
</code></pre>

python for-loop random while-loop range