-1

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"

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)?

This is my 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()

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.

New Code (credit goes to @roganjosh):

    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()
Alex H
  • 69
  • 1
  • 2
  • 7
  • Your code will always repeat because of the `while True:` loop – Patrick Haugh Oct 10 '16 at 18:24
  • This is tricky, because `int`s cannot have leading 0s. So if the password is 0000-0999 you can't generate that as a number. Treat the password like a string, not a number. – Sterling Archer Oct 10 '16 at 18:24
  • What difference would it make if you try random passwords in a range rather than just do it sequentially? If you have no indication of why something failed, just go from `0000` to `9999` one by one. Incidentally, this also calculates the number of failures as a byproduct. – roganjosh Oct 10 '16 at 18:24
  • Thank you everyone for your input. @PatrickHaugh I realized my error, thanks :) – Alex H Oct 10 '16 at 18:51
  • @SterlingArcher Thanks for the input. I get what you're saying, but i'm not sure how to implement it in my code. – Alex H Oct 10 '16 at 18:51
  • @roganjosh Thanks for the input. Going from 0000 - 9999 sequentially would mean that my number of fails = password. I did this at first, however I wanted to know if there was a way I could go through unique combinations within this range randomly, and if this would make it 'easier to crack the password'. Might just stick to the method you suggested though, as I am still very much a beginner, though I do enjoy this learning experience. – Alex H Oct 10 '16 at 18:55
  • 1
    @AlexH. With a brute-force approach, the difficulty is determined by the length of the password, and the set of allowed characters. The longer a password is, and the more different characters it uses, the harder it is to guess. This is simply because there are more possible passwords to try. – ekhumoro Oct 10 '16 at 19:07
  • @ekhumoro thanks for the info :) – Alex H Oct 10 '16 at 19:26

3 Answers3

1

If you really want to try all passwords in random order. this is more easily accomplished by

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')
Patrick Haugh
  • 59,226
  • 13
  • 88
  • 96
  • Thanks for the help. Still having problems with implementing your solution though... Here is the new code: import random Password4 = 1234 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) for code in s: while s == Password4: print(s, "is the password") break if s != Password4: print('fail') break but all it does is print 'fail' once, and if I print(s) it gives me all possible numbres w/o saying which is the password – Alex H Oct 10 '16 at 18:42
  • @AlexH I updated my answer to show you the basic flow of a program like this. Your problem was using an unnecessary `while` loop – Patrick Haugh Oct 10 '16 at 18:49
  • Thanks again. I tried to run you code on my IDE but nothing happened when I did. What am I doing wrong ( please keep in mind I am a very recent beginner)? – Alex H Oct 10 '16 at 19:06
  • @AlexH used `is` when i should have used `==`. Try it now – Patrick Haugh Oct 10 '16 at 19:09
  • Thanks patrick :) it works now ! Both your and roganjosh's answers worked for me so I will be marking them correct and including them in my update(and probably using them for the next small programs I need to write). Would it be alright with you if I used your code in my paper, of course acrediting you as well? – Alex H Oct 10 '16 at 19:20
  • just realized I can't mark both your answers as correct, but since yours includes the more direct answer to the question I will mark yours as correct and include both your and roganjosh's code in the update. Thanks again ! – Alex H Oct 10 '16 at 19:22
  • @AlexH Do not update your question again. This keeps bumping it up on the active thread list. The idea is that you post a question and there are answers below in the current format - they should not be in your question as everyone knows where to look fort hem – roganjosh Oct 10 '16 at 19:23
  • haha thanks for the advice! I'm new to this platform and am just learning to navigate, thanks everyone for being so helpful. – Alex H Oct 10 '16 at 19:25
0

You probably want to check out all possible values for a password under certain rules, e.g "4 digits" or "8 lowercase characters". Consider these answers as starting points:

Community
  • 1
  • 1
orip
  • 73,323
  • 21
  • 116
  • 148
  • thanks for the suggestion. I'm using numbers only (from combination 1111 to 9999). I couldn't figure out how to do this for the large range I'm using but i appreciate your input. – Alex H Oct 10 '16 at 18:48
0

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

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.

Try something like this:

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()
roganjosh
  • 12,594
  • 4
  • 29
  • 46
  • thanks for your suggestion! How do I know how many 'fails' I had before the password was found (this is important to my paper)? Alternatively, is there a way I can measure the amount of time/some other variable within the program to determine how hard it was to find the password? – Alex H Oct 10 '16 at 18:46
  • @AlexH Since you go through the password list sequentially, i.e. 0000, 0001.... then if you find the password to be 1234 you've had 1233 failures :P There is no real "difficulty" to find the password. If you pick at random and the password can only be between 0000 and 9999 then every guess is equally likely to crack it, so over an infinite number of runs, every password is identical in difficulty (if you use a true random number generator). In my case, higher numbers take longer to crack because we go sequentially. – roganjosh Oct 10 '16 at 18:51
  • I have edited my question to get rid of all `while` loops since they are not needed, and added a timer – roganjosh Oct 10 '16 at 18:52
  • @AlexH you're replying to the same person in comments on the question as my answer :) Please read my latest comment. Mathematically "difficulty" is incalculable here. – roganjosh Oct 10 '16 at 18:56
  • @AlexH In the real world, people will be more inclined to add odd numbers and they are likely to avoid repeated digits in their password e.g. `1231` and especially if they are adjacent e.g. `1123` as they _feel_ less "random". It's not true, it's human psychology and beyond this question. Outside of psychology, they're all equally difficult to crack. If you feel that one of the answers presented solves your problem, please consider [marking it correct](http://meta.stackexchange.com/questions/147531/how-mark-my-question-as-answered-on-stackoverflow) to close the question. – roganjosh Oct 10 '16 at 19:03
  • Thanks for this josh! The code worked and I think I will be using this for my math paper. Would this be alright with you (of course I would accredit you for it)? – Alex H Oct 10 '16 at 19:09
  • I'm brand new to stackoverflow, so please let me know how to mark your answer as 'correct'. If anyone has other solutions to the original questions please still let me know, I'd love to learn more. Thanks so much for your help and have a wonderful day! EDIT: Figured it out, thanks to you all for bearing with me :') – Alex H Oct 10 '16 at 19:10
  • @AlexH You are more than welcome to use it (everything on SO is openly available as far as I know). My link explains - click the grey arrow at the top of the answer on the left to turn it green. You're free to accept whichever answer you feel best solved the problem. I'm curious what your paper is and at what level of academia? – roganjosh Oct 10 '16 at 19:12
  • Thank you very much, once again, for your help with the code and helping me navigate this site. I'm in the International Baccalaureate (IB) program, and we are required to write Internal Assesments (IAs) for every class. I am in 12th grade in high school, and this program will be a part of my Math Standard Level IA, and will connect to the unit 'probability' that we are currently doing. – Alex H Oct 10 '16 at 19:28
  • @AlexH You are welcome. You would do well then to take note of my comments as I assume that's the overall purpose of your investigation. Now it's your turn to collect the data and either prove/disprove my assertions as well as the wider picture. – roganjosh Oct 10 '16 at 19:30