# [Tutor] Suggestions for more efficient and optimized coding technique,

Michael Langford michael.langford at rowdylabs.com
Thu Jan 8 21:20:12 CET 2009

```I understand that each response is unique Robert and no caching is
required to solve the problem at hand. However in a real program, the
chance you're brute forcing just one password is small (usually you
would brute force many); additionally, the question posted
specifically asked that the trials be cached, which is why I suggest
you do so, not out of any real need for just testing on the "loner"
testcase.

Additionally, the reason the aaaaa->zzzzz method is suggested is that
it a much faster algorithm to test every available combination than
the random method. The random method may never find the data.

I've created a frame work for you to play around with on this problem.
It shows how long different methods take in a more realistic scenario.
Try some other methods if you want, as well play around with password
length, the aaaaa->zzzzz method, etc. I've shorted then password
length to 3 to make it run faster  as well. Enough procrastination,
back to google app engine stuff.

--Michael

#!/usr/bin/env python
import string
import random

# test code to simulate a computer system under
#    attack, no need to understand now
class Computer(object):
def __init__(self):

"""returns true if the password was correct"""

# end test code

def rand_string(length = 3):
"""generates a random string of the given length"""
return ''.join(random.sample(string.ascii_lowercase,length))

passcache = list()

"""repeatedly tries passwords on the given computer"""
tries = 0
while True:
tries += 1
print( 'Password found in ' + str(tries) + ' tries.')
return

"""repeatedly tries passwords on the given computer"""
return

tries = 0
while True:
tries += 1
s = rand_string()
passcache.append(s)
print( 'Password found in ' + str(tries) + ' tries.')
return

def hack():
"""hacks a computer via a brute force method"""
my_computer = Computer()

def hack_cached():
"""hacks a computer via a brute force method with cached results"""
my_computer = Computer()

def mean(ls):
"""finds the mean of a list of numbers"""
return sum(ls)/len(ls)

def test_case(funcname, repeats):
"""
timeit is a python library for timing code. No need to
understand how this works, just that its repeating the
command given the number times specified by repeats. It's
returning a list of the execution times of each of the trials
"""
import timeit
timer = timeit.Timer("%s()"%funcname,"from __main__ import %s"%funcname)
return timer.repeat(number=repeats)

if __name__ == '__main__':

times_to_repeat = 100

uc_results = test_case("hack",times_to_repeat)
c_results = test_case("hack_cached", times_to_repeat)

print( "Cached mean time: "  + repr(mean(c_results)) )
print( "Cached min. time: "  + repr(min(c_results)) )
print( "Uncached mean time: "  + repr(mean(uc_results)) )
print( "Uncached min. time: "  + repr(min(uc_results)) )

On Thu, Jan 8, 2009 at 1:31 PM, Robert Berman <bermanrl at cfl.rr.com> wrote:
> Michael,
>
> Thank you for your code and your commentary. The code tells me this is
> really an ongoing learning process; almost as convoluted as linguistics and
> certainly every bit as interesting.
>
> Your concept of brute force in this example is intriguing. It is as if I
> have five cogs spinning, 'a' the slowest and 'e' flying as fast as its
> spokes can engage, and every click of every wheel produces a viable but
> possibly wrong response. However, each response is unique and in the nth
> iteration where password is found, all previous iterations are unique so
> there is certainly no need to carry the previous responses in either a list
> or a dictionary. They do not duplicate since they cannot repeat. Other than
> to include extraneous code, why include repetitive checking at all?
>
> In spite of that, your code and your remarks are most appreciated.
>
> Robert
>
> Michael Langford wrote:
>
> Here is your algorithm made more pythonic. Notice the use of default
> parameters, doc strings, not abbreviated variable names,  unix C style
> capitolization (very subjective, but often the one found in python
> libs), the avoidance of control variables when possible, the use of
> functions main that aren't __main__.
>
> #!/usr/bin/env python
> import string
> import random
>
> def rand_string(length = 5):
>   """returns a random string of numbers"""
>   return ''.join(random.sample(string.ascii_lowercase,length))
>
>   """randomly tries 5 letter long passwords until the user finds the
> correct one"""
>   tries = 0
>   while True:
>        tries += 1
>        if rand_string()  == match:
>            print 'Password found in ' + str(tries) + ' tries.'
>            return
>
> if __name__ == '__main__':
>
>
> Note: I do not think you're doing the problem the way the author
> intended. As it wants you to try all combinations, and it's about
> brute force, not finding it quickly, you most likely should start at
> "aaaaa" and move to "zzzzz", and cache the results in a list like they
> ask you too. At the very least, you should be saving these
> combinations you are generating randomly in a list (as it asks you to)
> and not testing the password if the generated string was already in
> the list (as in a real application, that is the time consuming or
> dangerous operation).
>
>              --Michael
>
> PS: If you wish to assure direct replies reach me
>
> On Thu, Jan 8, 2009 at 10:49 AM, Robert Berman <bermanrl at cfl.rr.com> wrote:
>
>
> Hi,
>
> One of the challenges on the challenge you web page appropriately titled
> 'Brute force' reads as follows:
>
> "The password you have to guess is 'loner' . Try all combinations of
> lowercase letters until you guess it.  Try not to loop much for example,
> save all used combinations in an array so you don't repeat."
>
> My code is as follows:
>
> #!/usr/bin/env python
>
> import random
>
> def GetString():
>   alphabet='abcdefghijklmnopqrstuvwxyz'
>   return ''.join(random.sample(alphabet,5))
> def main():
>   errknt = 0
>   control = True
>   while control is True:
>           errknt +=1
>       else:
>           print 'Password found in ',errknt,' tries.'
>           control = False
>
>          if __name__ == '__main__': main()
> efficiency  and optimization of code.
>
> Since the challenge revolves around the use of randomized retrieval, I'm not
> too sure how to optimize the process. The authors concept of using arrays
> seem a bit superfluous as I think it takes longer to add an item to a
> dictionary and retrieve an item from a dictionary than it does to do an if
> compare of two 5 character strings. So, I left that code out of the program
> entirely. If that was wrong, or there is a better way to avoid duplication,
> please point me in the right direction.
>
> I think, perhaps, I could make it a tad more efficient if I changed
> 'alphabet' from a string to a list as I remember reading  that lists are
> significantly faster to manipulate than are strings. Is that true and is it
> a viable change.
>
> I realize my code looks like modified C++ structured code. I am trying to
> become more Python concise but I think that is  a matter of writing more and
> more python code.
>
> All suggestions, ideas, critiques are most welcome.
>
> Thank you,
>
> Robert
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> http://mail.python.org/mailman/listinfo/tutor
>
>
>
>

--
Michael Langford
Phone: 404-386-0495
Web: http://www.RowdyLabs.com
```