title: Multithreading in zip password cracker
body: <p>I am learning how to crack zip files using dictionary attacks. This is the code:</p>
  
  <pre><code>import zipfile
  from threading import Thread
  
  def extractFile(zFile, password):
      try:
          zFile.extractall(pwd=password)
          print '[+] Found password ' + password + '\n'
      except:
          pass
  
  def main():
      zFile = zipfile.ZipFile('evil.zip')
      passFile = open('dictionary.txt')
      for line in passFile.readlines():
          password = line.strip('\n')
          extractFile(zFile, password)
  
  if __name__ == '__main__':
      main()
  </code></pre>
  
  <p>I use threading on it</p>
  
  <pre><code>import zipfile
  from threading import Thread
  
  def extractFile(zFile, password):
      try:
          zFile.extractall(pwd=password)
          print '[+] Found password ' + password + '\n'
      except:
          pass
  
  def main():
      zFile = zipfile.ZipFile('evil.zip')
      passFile = open('dictionary.txt')
      for line in passFile.readlines():
          password = line.strip('\n')
          t = Thread(target=extractFile, args=(zFile, password))
          t.start()
  
  if __name__ == '__main__':
      main()
  </code></pre>
  
  <p>However, when I time the two programmes, it takes 90 seconds to complete the first but nearly 300 seconds to complete the second. The dictionary contains 459026 entries. I am baffled as to why this happens. I also tried limiting the threads to 10,20,so on. But still the loop performs faster at each instance. Can anybody explain why this is so?? Also is there any chance to improve the program at all.</p>
  
  <p><strong>EDIT</strong>
  I tried slicing as suggested by Ray as follows:</p>
  
  <pre><code>import zipfile
  from threading import Thread
  
  def chunks(l, n):
      """Yield successive n-sized chunks from l."""
      for i in xrange(0, len(l), n):
          yield l[i:i+n]
  
  def extractFile(zFile, passwords):
      for password in passwords:
          try:
              zFile.extractall(pwd=password)
              print '[+] Found password ' + password + '\n'
              sys.exit(0)
          except:
              continue
  
  def main():
      zFile = zipfile.ZipFile('evil.zip')
      with open('dictionary.txt', 'rb') as pass_file:
          passwords = [i.strip() for i in pass_file]
      passes = list(chunks(passwords, 10))
      for pas in passes:
          t = Thread(target=extractFile, args=(zFile, pas))
          t.start()
  
  if __name__ == '__main__':
      main()
  </code></pre>
  
  <p>Still takes 3-4 mins</p>