Python: List index is out of range - python

I am making some 'password-cracking' software for fun with python. (Not for actual password cracking, for a randomly generated password) However when I run it, it says this:
Traceback (most recent call last):
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Password Cracker.py", line 14, in <module>
if chars[trys] == example[index]:
IndexError: list index out of range
I don't know what the error is here, because this happens as soon as I run the code, and by default, index is set to 0, so how can it be out of range?
Here is my code:
import random
import string
chars = list(string.ascii_lowercase) + list(string.ascii_lowercase.upper())
print(chars)
trys = 0
rounds = 8
index = 0
example = (random.choice(chars) + random.choice(chars) + random.choice(chars) + random.choice(chars) + random.choice(chars) + random.choice(chars) + random.choice(chars) + random.choice(chars))
password = ""
while rounds != 0:
if chars[trys] == example[index]:
password = chars[trys]
rounds -= 1
index +=1
else:
trys += 1
print(password)
What is my mistake?

Increment index and decrements rounds should not be inside if block. This should be irrespective on if or else case.
You can try:
while rounds != 0:
if chars[trys] == example[index]:
password = chars[trys]
else:
trys += 1
rounds -= 1
index +=1
print(password)

Related

Annotating adjacent values in a list

It's supposed to be a roll of dice (random) then adjacent values (runs) are supposed to be in ( ). One challenge is using the current - 1 with the 0 index (think I got that resolved by using range(len(dieRun) -1). But another challenge is using 'current + 1' as it tends to 'out of range' errors.
One thought I have is to maybe build a function to compare the values for adjacents? Then use whatever return I get from that to reference a variable, then use that variable in a formatted Print of the dieRun? But, I don't see how that would be better as then I'd still have to figure out how to place that variable as a "(" or ")" with the print(dieRun) list.
Still a newb.
def main():
from random import randint
counter = 0
inRun = 0
dieRun = []
while counter < 20:
roll = randint(0,6)
dieRun.append(roll)
counter = counter +1
index = 0
counter = 0
value = 0
inRun == False
print(dieRun) # just to see what I'm working with
while counter < len(dieRun):
for i in range(0, len(dieRun)-1):
if dieRun[i] != dieRun[i-1]:
print(")" , end= "")
inRun = False
counter = counter + 1
if dieRun[i] == dieRun[i+1]:
inRun = True
print("(")
counter = counter + 1
print(dieRun[i])
if inRun:
print("(")
if inRun :
print(")", end="")
main()
if you want the output like: 1(3 3) 4 5 (6 6 6) 2 1 3 (2 2) 1 (4 4) 5 6 1 2
from random import randint
dieRun = []
for i in range(20):
roll = randint(0,6)
dieRun.append(roll)
inRun = False
print(dieRun)
for i, n in enumerate(dieRun):
if i < len(dieRun)-1:
if not inRun:
if n == dieRun[i+1]:
print('(', n,' ', end='')
inRun = True
else:
print(n,' ', end='')
else:
if n != dieRun[i+1]:
print(n, ')',' ', end='')
inRun = False
else:
print(n,' ', end='')
else:
if dieRun[i-1] == n:
print(n, ')')
else:
print(n)
just a thought, hope it help.
Just a quick fix, I have commented in the code.
For the inline print, you have provided the solution 'print(")" , end= "")', but I don't know why you didn't make it for every print().
if dieRun[i] != dieRun[i-1]: # will check the first number with last number
dieRun[0] != dieRun[-1]: # [-1] is the last item in the list
if dieRun[i] == dieRun[i+1]: # will index out of length
dieRun[len(..)-1] != dieRun[len(..)]: # [len(..)] wil be out of range
Since the head and tail of the list will always cause problem, I just chopped them off from the for loop, and do it manually.
There must be some cleaner solution:
from random import randint
counter = 0
inRun = 0
dieRun = []
while counter < 20:
roll = randint(0,6)
dieRun.append(roll)
counter = counter +1
index = 0
counter = 0
value = 0
inRun == False
print(dieRun)
# while counter < len(dieRun): # while loop is redundant with the for loop
print('(', dieRun[0],' ', end='') # print the first number manually
for i in range(1, len(dieRun)-1):
if dieRun[i] != dieRun[i-1]:
print(")(" , end= "") # change ")" to ")("
inRun = False
counter = counter + 1
"""
these are redundant, just like if True, don't need elif not True
# if dieRun[i] == dieRun[i+1]:
# inRun == True
# print("(", end='')
# counter = counter + 1
"""
print(dieRun[i],' ', end='')
print(dieRun[-1],')', end='') # print the last number manually

Python brute force password guesser

I am doing a task in class about a password guesser. I stumbled into a lot of problems trying to solve this task, my first approach was to use for loops (code below), but I realized that the amount of 'for loops' is equal to the length of the string.
a_z = 'abcdefghijklmnopqrstuvwxyz'
pasw = 'dog'
tests = 0
guess = ''
azlen = len(a_z)
for i in range(azlen):
for j in range(azlen):
for k in range(azlen):
guess = a_z[i] + a_z[j] + a_z[k]
tests += 1
if guess == pasw:
print('Got "{}" after {} tests'.format(guess, str(tests)))
break
input()
The program above is very concrete. It only works if there are exactly 3 characters entered. I read that you could use a package called intertools, however, I really want to find another way of doing this. I thought about using recursion but don't even know where to start.
import string
import itertools
for possible_password in itertools.permutations(string.ascii_letters, 3):
print(possible_password)
If you don't want to use itertools you can certainly do this with recursion, which will work with passwords of any (reasonable) length—it's not wired to three characters. Basically, each recursive call will attempt to append a new character from your alphabet to your running value of guess. The base case is when the guess attains the same length as value you're seeking, in which case you check for a match. If a match is found, return an indication that you have succeeded (I used return True) so you can short circuit any further searching. Otherwise, return a failure indication (return False). The use of a global counter makes it a bit uglier, but produces the same results you reported.
ALPHABET = 'abcdefghijklmnopqrstuvwxyz'
def brute_force_guesser(passwd, guess = ''):
global _bfg_counter
if len(guess) == 0:
_bfg_counter = 0
if len(guess) == len(passwd):
_bfg_counter += 1
if guess == passwd:
print('Got "{}" after {} tests'.format(guess, str(_bfg_counter)))
return True
return False
else:
for c in ALPHABET:
if brute_force_guesser(passwd, guess + c):
return True
return False
brute_force_guesser('dog') # => Got "dog" after 2399 tests
brute_force_guesser('doggy') # => Got "doggy" after 1621229 tests
One way to avoid the global counter is by using multiple return values:
ALPHABET = 'abcdefghijklmnopqrstuvwxyz'
def brute_force_guesser(target, guess = '', counter = 0):
if len(guess) == len(target):
counter += 1
if guess == target:
print('Got "{}" after {} tests'.format(guess, str(counter)))
return True, counter
return False, counter
else:
for c in ALPHABET:
target_found, counter = brute_force_guesser(target, guess + c, counter)
if target_found:
return True, counter
return False, counter
brute_force_guesser('dog') # => Got "dog" after 2399 tests
brute_force_guesser('doggy') # => Got "doggy" after 1621229 tests
Here is my full answer, sorry if it's not neat, I'm still new to coding in general. The credit goes to #JohnColeman for the great idea of using bases.
import math
global guess
pasw = str(input('Input password: '))
chars = 'abcdefghijklmnopqrstuvwxyz' #only limeted myself to lowercase for simplllicity.
base = len(chars)+1
def cracker(pasw):
guess = ''
tests = 1
c = 0
m = 0
while True:
y = tests
while True:
c = y % base
m = math.floor((y - c) / base)
y = m
guess = chars[(c - 1)] + guess
print(guess)
if m == 0:
break
if guess == pasw:
print('Got "{}" after {} tests'.format(guess, str(tests)))
break
else:
tests += 1
guess = ''
cracker(pasw)
input()
import itertools
import string
def guess_password(real):
chars = string.ascii_lowercase + string.digits
attempts = 0
for password_length in range(1, 20):
for guess in itertools.product(chars, repeat=password_length):
attempts += 1
guess = ''.join(guess)
if guess == real:
return 'the password is {}, found in {} guesses.'.format(guess, attempts)
print(guess, attempts)
print(guess_password('abc'))

"List index out of range" error in python 3 file

I have a homemade text encryption script which outputs a "List index out of range" error when I input "Hey dude, how are you doing?" as a text to encrypt and "KFC" as an encryption key.
I get this more precisely:
Traceback (most recent call last):
File "/Users/BCPianist/Google Drive/Project-Cryptonite/NCrypt.py", line 75, in <module>
main(userIn, a)
File "/Users/BCPianist/Google Drive/Project-Cryptonite/NCrypt.py", line 47, in main
currentscrtrank += 1 + scrtlst[scrtrankcounter]
IndexError: list index out of range
I have two files used in this script (the main script and a function library). I just can't figure where this error is coming from...
Here is my main script:
import random
from cryptolib import *
# !/usr/bin/env python
# -*- coding: UTF-8 -*-
# enable debugging
print("Content-Type: text/plain;charset=utf-8") # Definit le code d'ecriture
print() # Insere une ligne d'espacement.
def main(userin, numberedsecretkey): # Fonction principale (le gros de l'encryption)
"""
This is my main.
>>> main("Allo", "Hey")
10842839726
"""
comments = True # Definit si les commentaires lors de l'impression sont actif ou non (False les desactive)
total = convdecimal(userin) # Time to deal with the encryption key:
scrtkeytotal = convdecimal(numberedsecretkey)
# converting numbered message to list
msglst = [int(elem) for elem in str(total)]
if comments == True:
printdebug("The initial numbered message is:%s " % msglst)
# converting numbered key to list
scrtlst = [int(thingy) for thingy in str(scrtkeytotal)]
if not comments != True:
printdebug("The initial encryption key is:%s" % scrtlst)
# Attempting Encryption
scrtrankcounter = 0
currentscrtrank = scrtlst[scrtrankcounter]
while currentscrtrank < len(msglst):
randomgen = random.randint(0, 9)
msglst.insert(currentscrtrank, randomgen)
if comments:
printdebug(str(randomgen) + " was inserted at rank: " + str(
scrtrankcounter) + ", therefore, at index position: " + str(currentscrtrank) + ".")
printdebug("List now appears as: " + str(msglst))
scrtrankcounter += 1
if scrtrankcounter > len(scrtlst):
scrtrankcounter = 0
currentscrtrank += 1 + scrtlst[scrtrankcounter]
return listtoint(msglst)
def convdecimal(userin):
rank = len(userin)
total = 0
for character in userin:
rank -= 1 # decreasing the letter rank by one
letter = ord(character)
if letter < 32:
pass
elif letter == 27:
pass
else:
rankmult = 255 ** rank # Making a multiplier
lettervalue = letter * rankmult # Multiplying the letter by this multiplier
total += lettervalue # Adding the letter's value to the total
return total
if __name__ == "__main__":
userIn = input("Enter the word/Sentence you want to encrypt:")
a = input("Enter a password with which you would like to encrypt your message:")
print(userIn)
main(userIn, a)
And here is my function library file:
import os
DEBUG = True
def printdebug(log: object) -> object:
if DEBUG:
print(log)
def loading(sec=10):
start = 1
input("Press Enter to continue")
printdebug("loading...")
while start <= sec:
printdebug("...")
start += 1
def codepause():
os.system("Pause")
input("press enter to continue")
def listtoint(msglst):
# Conversion from list to int
"""
>>> listtoint([1,2,3,4,5,6,7,8,9,0])
1234567890
"""
ncryptedkey = 0
base = 10
for d in msglst:
ncryptedkey = base * ncryptedkey + d
# printDebugJob:
printdebug("The encrypted message is:" + str(ncryptedkey))
return ncryptedkey
def convdecimal(userin):
rank = len(userin)
total = 0
for character in userin:
rank -= 1 # decreasing the letter rank by one
letter = ord(character)
if letter < 32:
pass
elif letter == 27:
pass
else:
rankmult = 255 ** rank # Making a multiplier
lettervalue = letter * rankmult # Multiplying the letter by this multiplier
total += lettervalue # Adding the letter's value to the total
def letterprint(nb):
nb = chr(nb)
print(nb, end='')
Thanks Already!
I've not tested this, but it looks like you need to swap the greater than sign for greater than or equals, as it's probably going 1 index too high.
if scrtrankcounter >= len(scrtlst):
scrtrankcounter = 0
currentscrtrank += 1 + scrtlst[scrtrankcounter]
For example, if scrtlst has a length of 5, the highest index is 4, so it'll give an error if you try scrtlst[5].

Binary Search to search a list

I have a code which first sorts the emails into alphabetical order and then attempts to use binary search to search a user inputted email from a list. However, I have been stuck on how to do this for so long and haven't found any solutions on the error I get and how to fix it. Here is my code
def BubbleSort(logindata):
NoSwaps = 1
N = len(logindata)
logindata = list(logindata)
while NoSwaps == 1:
Count = 1
NoSwaps = 0
for Count in range(N-1):
if logindata[Count] > logindata[Count+1]:
temp = logindata[Count]
logindata[Count] = logindata[Count+1]
logindata[Count+1]=temp
NoSwaps=1
return tuple(logindata)
def BinarySearch(logindata,ItemSought):
First=0
Last=len(logindata)-1
ItemFound = False
SearchFailed = False
while ItemFound == False or SearchFailed == False:
Midpoint = (First + Last) // 2
if logindata[Midpoint] == ItemSought:
ItemFound = True
print("Item Found")
break
elif logindata[Midpoint] > ItemSought:
Last = Midpoint - 1
else:
First = Midpoint + 1
if __name__ == "__main__":
logindata=["tom#gmail.com","Password1"],["harry#gmail.com","Password2"],["jake#gmail.com","Password3"]
logindata=BubbleSort(logindata)
print(logindata)
ItemSought=input("Enter username")
BinarySearch(logindata,ItemSought)
The error I currently get is :
elif logindata[Midpoint] > ItemSought:
TypeError: unorderable types: list() > str()
You're comparing a username/password pair (e.g. ["tom#gmail.com","Password1"]) with a username (e.g. "tom#gmail.com").
You need to extract the username from logindata[Midpoint] before comparing it to ItemSought.

String index not working? - Python

I'm Making a sort of cipher that requires a string to be read backwards and i get an indexing error even though the index I reference is well within range:
M = str(input("Input Message: "))
M = M.upper()
L = len(M)
A = ["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"]
def DECRYPT():
global L
global M
global A
if L%2 != 0:
POS = False
else:
POS = True
i = L-1
NM = ""
while 1:
if M[i] != " ":
INDEX = A.index(M[i])
if POS == True:
INDEX += (i + 1)
else:
INDEX -= (i)
INDEX %= 26
NM = NM+A[INDEX]
i += 1
if POS == True:
POS = False
else:
POS = True
print("\n"+NM)
def ENCRYPT():
global L
global A
global M
POS = True
M = M[::-1]
i = 0
NM = ""
while 1:
if i == L:
break
if M[i] != " ":
INDEX = A.index(M[i])
if POS == True:
INDEX += (i + 1)
else:
INDEX -= (i + 1)
INDEX %= 26
NM = NM+A[INDEX]
i += 1
if POS == True:
POS = False
else:
POS = True
print("\n"+NM)
while 1:
C = int(input("\nWhat do you want to do:\n1) Encrypt Something\n2)Decrypt Something\n\n"))
if C == 1:
ENCRYPT()
if C == 2:
DECRYPT()
where i is a placeholder value. I run it and get this:
Input Message: ABC
What do you want to do:
1) Encrypt Something
2)Decrypt Something
2
Traceback (most recent call last):
File "C:\Users\Danny\Google Drive\SHIFT.py", line 67, in <module>
DECRYPT()
File "C:\Users\Danny\Google Drive\SHIFT.py", line 19, in DECRYPT
if M[i] != " ":
IndexError: string index out of range
I have tried changing value of i to no avail.
There are multiple problems with your code: as fernand0 noted, your index runs the wrong way; your inversion of POS happens at different levels in the code, the encryptor does it on every character, the decryptor does it on every letter -- they should work the same; five of your six global declarations aren't needed; you don't deal with word breaks correctly so the decryption won't match the original; once you encrypt, there's no way to decrypt in the same session as the local NM doesn't feedback into the global M.
Below is my rework of your code addressing the above problems and some style issues. The key phrase here is 'simplify'. I've kept your odd uppercase variable names but expanded them from single characters to what they represent:
MESSAGE = input("Input Message: ").upper()
ALPHABET = list("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
ALPHABET_LENGTH = len(ALPHABET)
def DECRYPT(MESSAGE):
LENGTH = len(MESSAGE)
IS_NEGATIVE = True
NEW_MESSAGE = ""
for I in range(LENGTH):
if MESSAGE[I] in ALPHABET:
INDEX = ALPHABET.index(MESSAGE[I])
if IS_NEGATIVE:
INDEX -= (I + 1)
else:
INDEX += (I + 1)
INDEX %= ALPHABET_LENGTH
NEW_MESSAGE += ALPHABET[INDEX]
IS_NEGATIVE = not IS_NEGATIVE
else:
NEW_MESSAGE += MESSAGE[I]
return NEW_MESSAGE[::-1]
def ENCRYPT(MESSAGE):
MESSAGE = MESSAGE[::-1]
LENGTH = len(MESSAGE)
IS_POSITIVE = True
NEW_MESSAGE = ""
for I in range(LENGTH):
if MESSAGE[I] in ALPHABET:
INDEX = ALPHABET.index(MESSAGE[I])
if IS_POSITIVE:
INDEX += (I + 1)
else:
INDEX -= (I + 1)
INDEX %= ALPHABET_LENGTH
NEW_MESSAGE += ALPHABET[INDEX]
IS_POSITIVE = not IS_POSITIVE
else:
NEW_MESSAGE += MESSAGE[I]
return NEW_MESSAGE
while True:
print("\nWhat do you want to do:")
print("1) Encrypt Message")
print("2) Decrypt Message")
CHOICE = int(input("\n"))
if CHOICE == 1:
MESSAGE = ENCRYPT(MESSAGE)
if CHOICE == 2:
MESSAGE = DECRYPT(MESSAGE)
print("\n" + MESSAGE)
TEST
> python3 file.py
Input Message: An opportunity to teach is an opportunity to learn
What do you want to do:
1) Encrypt Message
2) Decrypt Message
1
OPDAQ HB OEWAGIBFXIU JD RI JZEZZ GC NFVBFJAGWJT KC
What do you want to do:
1) Encrypt Message
2) Decrypt Message
2
AN OPPORTUNITY TO TEACH IS AN OPPORTUNITY TO LEARN
What do you want to do:
1) Encrypt Message
2) Decrypt Message
You are starting i at the end of the string and then, you are increasing it. I think the line i += 1 should be i -= 1

Categories

Resources