brute force password with words and numbers - python

I am doing this science fair project for school: http://www.sciencebuddies.org/science-fair-projects/project_ideas/CompSci_p046.shtml#summary
The project gives you base program that guesses the passwords that you input into the program and uses a different methods to guess it. Part of the project is to come up with new algorithms to add to the program. One of the methods is using long list of common passwords to match the given password and another is a simple lock-dial simulation of numbers up to 8 digits. I was wondering if there was a way two combine those to so it checks a word in the list plus the number dial behind the word. How to write a simple code to do that?
What I'm really asking for is for someone to help me write a new method that goes through the word list and add a number dial (brute force with numbers) after the word, then check to see if that's the password inputed.
Original program and word list can be downloaded here: http://www.sciencebuddies.org/science-fair-projects/project_ideas/CompSci_p046.shtml#materials
This is the number dial simulation the program uses
def search_method_1(num_digits):
global totalguesses
result = False
a=0
#num_digits = 3 # How many digits to try. 1 = 0 to 9, 2 = 00 to 99, etc.
starttime = time.time()
tests = 0
still_searching = True
print("Using method 1 and searching for "+str(num_digits)+" digit numbers.")
while still_searching and a<(10**num_digits):
ourguess = leading_zeroes(a,num_digits)
tests = tests + 1
totalguesses = totalguesses + 1
if (check_userpass(which_password, ourguess)):
print ("Success! Password "+str(which_password)+" is " + ourguess)
still_searching = False # we can stop now - we found it!
result = True
else:
print ("Darn. " + ourguess + " is NOT the password.")
a=a+1
seconds = time.time()-starttime
report_search_time(tests, seconds)
return result
This is the code that runs through the word list:
def search_method_3(file_name):
global totalguesses
result = False
# Start by reading the list of words into a Python list
f = open(file_name)
words = f.readlines()
f.close
# We need to know how many there are
number_of_words = len(words)
print("Using method 3 with "+str(number_of_words)+" in the list")
## Depending on the file system, there may be extra characters before
## or after the words.
for i in range(0, number_of_words):
words[i] = cleanup(words[i])
# Let's try each one as the password and see what happens
starttime = time.time()
tests = 0
still_searching = True
word1count = 0 # Which word we'll try next
while still_searching:
ourguess_pass = words[word1count]
#print("Guessing: "+ourguess_pass)
# Try it the way it is in the word list
if (check_userpass(which_password, ourguess_pass)):
print ("Success! Password "+str(which_password)+" is " + ourguess_pass)
still_searching = False # we can stop now - we found it!
result = True
#else:
#print ("Darn. " + ourguess_pass + " is NOT the password.")
tests = tests + 1
totalguesses = totalguesses + 1
# Now let's try it with the first letter capitalized
if still_searching:
ourguess_pass = Cap(ourguess_pass)
#print("Guessing: "+ourguess_pass)
if (check_userpass(which_password, ourguess_pass)):
print ("Success! Password "+str(which_password)+" is " + ourguess_pass)
still_searching = False # we can stop now - we found it!
result = True
#else:
#print ("Darn. " + ourguess_pass + " is NOT the password.")
tests = tests + 1
totalguesses = totalguesses + 1
word1count = word1count + 1
if (word1count >= number_of_words):
still_searching = False
seconds = time.time()-starttime
report_search_time(tests, seconds)
return result

I interpret your question to mean that you want to interlace the numeric guesses with the alphabetic guesses.
One problem you are facing is that the logic that keeps time and the logic that checks if the password is correct is mixed in with the logic that generates guesses. You might want to use generators to break out the "guess generation" into separate functions.
from itertools import izip
def numerical_guess():
current_guess = 0
while True:
yield current_guess
current_guess += 1
def dictionary_guess():
for word in {'apple', 'banana', 'orange'}:
yield word
for guess in izip(numerical_guess(), dictionary_guess()):
if guess == password:
print "Got it!"
else:
print "Not it!"
There are some things you will have to think about, such as what if one generator runs out before the other one.
You mention that you don't know enough to understand this level of code, but I don't see anything so complicated with the code. Your posted code only uses the most basic control structures of python so I wonder if this post will even be helpful for you. Maybe you could go through the code line by line and mention any part of the code that is confusing for you.

Related

Coding Hangman in Python

I'm having trouble with this hangman coding. When I run the code, it asks the question "Type in a letter a - z", but when I type in a letter, instead of it putting a letter, it just ask the same question from the beginning without letting me know if the letter is correct or not.
import random
possibleAnswers = ["page","computer","cookie","phishing","motherboard","freeware","bus","unix","document","hypertext","node","digital","worm","macro","binary","podcast","paste","virus","toolbar","browser"]
random.shuffle(possibleAnswers)
answers = list(possibleAnswers[1])
display = []
display.extend(answers)
for i in range(len(display)):
display[i] = "_"
print ' '.join(display)
print "\n\n\n\n"
count = 0
while count < len(answers):
guess = raw_input("Type in a letter a - z: ")
guess = guess.upper()
for i in range(len(answers)):
if answers[i] == guess:
display[i] = guess
count += 1
print ' '.join(display)
print "\n\n\n"
It does tell you, after a fashion. The problem is that your entire word list is lower-case, but you specifically change all of your input guesses to upper-case. Those cannot match, so there's never a "correct" guess. Change the word list to capitals, or change your conversion from upper to lower.

How to let user end program and shift list

Im trying to make an encryption program
def intro():
msg = input("Enter the message you wish to encrypt: ")
return msg
def shift(msg):
alpha = ['a', 'b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']
rotate = int(input("The level of the encryption?: "))
text = ""
for ch in msg:
if ch == " " or ch == ".":
pass
elif msg == "$":
print("nah")
else:
index = alpha.index(ch)
newindex = index + rotate
new= alpha[newindex]
text += new
return text
def start():
msg = intro()
text = shift(msg)
print("Your encryptions is: " + text)
start()
I can't figure out a way to loop the list without getting an index out of range error. For example, if you put "z" it will shift to an "a". I also need for my program to loop till user inputs to end it. I just started coding in python a few months ago so any help will be appreciated!beginner
All you need to do is add this line
newindex %= len(alpha)
Detailed Change (with context)
index = alpha.index(ch)
newindex = index + rotate
new= alpha[newindex]
text += new
to
index = alpha.index(ch)
newindex = index + rotate
newindex %= len(alpha) # <--- this is the new line
new= alpha[newindex]
text += new
This will automatically make the new index loop so it never goes past the end!
Working example
>> Enter the message you wish to encrypt: 'xyz'
>> The level of the encryption?: 2
>> Your encryptions is: zab
Since your code is running fine, I can tell you about some techniques you can work on to get the functionality you want.
To get an array that loops around, you can use a mod system. For example 8 mod 3 = 2 and it would be coded remainder = 8 % 3. If you had a mod size 26, i.e. the alphabet, you could take the remainder of the total number and use it as an index in your alphabet list. This would cycle around when the total number is greater than 26 and begin again at a.
To get the program to end on user input, you can use a variety of methods such as keyboard interrupts, recognizing certain commands such as ctrl-c or whole words. Here is a start from a previous stackoverflow question. How to kill a while loop with a keystroke?
use the modulus operator to wrap the index around when it's outside the list length:
newindex = (index + rotate) % len(alpha)
To repeat, use a while True: loop, and use break to end it.
def start():
while True:
msg = intro()
if msg == '':
break
text = shift(msg)
print("Your encryptions is: " + text)
This will end when the user inputs an empty line.

How to replace "-" with a space?

I'm making a hangman program, and I want it to be able to include phrases; however, when I input a phrase to be guessed, the output only dashes. For instance, when I put in "how are you"(input to be guessed), the output is "-----------". What i want the out put to be is "--- --- ---", as it makes it easier for the player to know that it is a phrase. I've tried a 'for' loop and 'if' statement to now avail, and would appreciate some help. Thanks!
*At the moment I'm trying replace. Also, if this is badly worded, let me know and I'll try rewriting it.
right = ""
guess=""
attempts = 6
tries = 0
space = " "
print("Hangman: guess letters until you can guess the word or phrase.")
print("In this game you get six tries.")
right_str = str(input("\nEnter your word: "))
right_str = right_str.lower()
#displays the proper amount of unknown spaces
right = right * len(right_str)
if space in right_str:
right_str.find(space, i)
print(i)
you could try this:
guess=""
attempts = 6
tries = 0
space = " "
print("Hangman: guess letters until you can guess the word or phrase.")
print("In this game you get six tries.")
right_str = str(input("\nEnter your word: "))
right_str = right_str.lower()
output = ""
for c in right_str:
if c != " ":
output += "-"
else:
output += " "
print output

String Index Out Of Range (Python) I have made bounds too

import time
password=input("What's your password?")
ans = ""
password=password.lower()
alpha = "abcdefghijklmnopqrstuvwxyz"
n = 0
a=0
starttime=time.time()
while ans !=password:
print(a)
for i in range(len(password)):
letter=alpha[n]
ans+=letter
if ans[a] != password[a]:
print(ans)
ans = ans.replace(ans[a],"")
n+=1
break
else:
a+=1
print(ans)
n=0
break
print("Password Found!")
endtime=time.time()
time=endtime-starttime
print("It took " + str(time) + " seconds!")
This is my code, sorry if i'm not posting it right (first time here). But let's digress, It seems i get an error of string index out of range
Traceback (most recent call last):
File "C:\Users\admin\Documents\Letter word cracker.py", line 15, in <module>
if ans[a] != password[a]:
IndexError: string index out of range
I was wondering how to fix this, because its been eating at my brain for days. Any help would be appreciated, thanks!
Ok, I don't know why you are trying to do this, what you are trying to do, the error is here due to this line
ans = ans.replace(ans[a],"") ---> X
what replace will do, is replace all the occurrences of a particular character from the array, while you only need to remove the last.
For example :-
If ans = "naa",
now replace will replace both 'a' while based on your logic you only want to remove the last element. because you have already matched till "na" and now in process of matching the third element.
You could probably do :-
ans = ans[:-1]
But again, this is a very very bad way to do this, because strings are immutable so you are basically creating and destroying strings every iteration.
One advice I would give is using list of characters instead of a string, it would not give a significant boost to the runtime for your program, for whatever reason you are using this.
EDIT:-
Also the for loop is unnecessary, as it is always breaking after first iteration. thanks #TigerHawk
import time
password=input("What's your password?")
ans = []
password=password.lower()
alpha = "abcdefghijklmnopqrstuvwxyz"
n = 0
a=0
starttime=time.time()
while "".join(ans) !=password:
letter=alpha[n]
ans.append(letter)
if ans[a] != password[a]:
ans.pop()
n+=1
else:
a+=1
n=0
print("Password Found!")
endtime=time.time()
time=endtime-starttime
This is a little better and more condensed version. From what I understand, you want to brute force a character string to compare it to a password.
import time
password=input("What's your password?")
password=password.lower()
alpha = "abcdefghijklmnopqrstuvwxyz"
starttime=time.time()
for letter in range(len(password)):
for index in range(len(alpha)):
if alpha[index] == password[letter]:
print "Letter",letter,"Found."
next
print "Password Found!"
endtime=time.time()
time=endtime-starttime
print "It took",time,"seconds!"
There are a few issues per the previous post, but the IndexError is happening because you are comparing each element of each list, and when one list runs out, it raises the IndexError exception. Wrap that part of the code in an if() that checks to see whether there are any more elements left over.
This will not fix the entire program, and in fact, you'll likely need a better way to do this comparison... I'm just explaining why the IndexError is happening.
if (ans[a] and password[a]):
if ans[a] != password[a]:
print(ans)
ans = ans.replace(ans[a],"")
n+=1
break
You should really go through your logic to understand why it isn't working, but there are many improvements you can make to your code. I have implemented a working version with a few improvements below.
from time import time
import string
#this will only work for a-z no whitespace, caps, numbers, etc.
pwd = raw_input("What is your password? ")
pwd = pwd.lower()
#create list of password for easier iterability
password = list(pwd)
#alphabet will have a-z lowercase
alphabet = list(string.ascii_lowercase)
#empty list to start
guess = []
#start timer
start = time()
#outer loop through password
for char in password:
#inner loop through alphabet
for letter in alphabet:
if letter == char:
guess.append(letter)
break
#print correct guess as string
end = time()
print "It took " + str(end - start) + " seconds to solve this password."
#verify correctness
print "".join(guess)
print pwd

Python - Finding all non alpha-numeric characters in a string

I'm designing a system that allows users to input a string, and the strength of the string to be determined by the amount of non alphanumeric characters. Points should be awarded like so: +1 for every non-alnum character to a maximum of 3 non-alnum characters.
def non_alnum_2(total,pwd):
count = 0
lid = 3
number = 0
if pwd[count].isalnum():
if True:
print "Nope"
if False:
print "Good job"
count = count + 1
number += 1
if number > lid:
number = lid
return number
total = 0
number = 0
pwd = raw_input("What is your password? ")
non_alnum_2(total, pwd)
print total
total += number
I've only just started coding, so I'm sorry if this seems like a very junior question.
You can simply try:
bonus = min(sum(not c.isalnum() for c in pwd), 3)
If you want to count the number of non-alpha strings you could say
def strength(string):
'''Computes and returns the strength of the string'''
count = 0
# check each character in the string
for char in string:
# increment by 1 if it's non-alphanumeric
if not char.isalpha():
count += 1
# Take whichever is smaller
return min(3, count)
print (strength("test123"))
There are multiple problems with this code.
First, if True: is always true, so the "Nope" will always happen, and if False: is never true, so none of that stuff will ever happen. I think you wanted this:
if pwd[count].isalnum():
print "Nope"
else:
print "Good job"
count = count + 1
number += 1
Also, I think you want to increment count always, not just if it's a symbol, so:
if pwd[count].isalnum():
print "Nope"
else:
print "Good job"
number += 1
count = count + 1
Meanwhile, you need some kind of loop if you want this to happen over and over. For example:
while count < len(pwd):
if pwd[count].isalnum():
# etc.
However, you really don't need to maintain count yourself and keep doing pwd[count]; you can use a for loop for this:
for ch in pwd:
if ch.isalnum():
# etc.
Meanwhile, while you do return a value from the end of the function, you don't do anything with that returned value when you call the function. What you need is:
number = non_alnum_2(total, pwd)
Also, there's no reason to pass total to non_alnum_2 here. In fact, it doesn't do anything useful at all.
So, putting it all together:
def non_alnum_2(pwd):
lid = 3
number = 0
for ch in pwd:
if ch.isalnum():
print "Nope"
else:
print "Good job"
number += 1
if number > lid:
number = lid
return number
pwd = raw_input("What is your password? ")
number = non_alnum_2(pwd)
print number
def non_alnum(s):
temp=[]
for i in s:
if i.isalnum():
continue
else:
temp.append(i)
if temp==[]:
print("The string doesn't contain any non_alphanumeric chars")
else:
print("The string contains non_alphanumeric chars: ",temp)
str1="ABCDEFabcdef123450"
str2="ABCDEF;abcdef'1234!50"
str3="*&%#!}{"
non_alnum(str1)
non_alnum(str2)
non_alnum(str3)

Categories