Python 5 Ziffern&Buchstaben Pin Brute Force?
Moin,
folgendes:
Ich möchte Bilddateien von einem Webserver herunterladen. Jedes Bild hat seine individuelle URL xxxxx.com/bbbbb
b besteht aus 5 Ziffern oder Buchstaben. Sprich
5 Pins | a - z = 26 und 0 - 9 = 10 (= 36) 36^5
wären dann 60.466.176 mögliche Kombinationen. Nun suche ich nach einer möglichst effektiven Methode, mit einem Python Script das Bild auf jeder der möglichen Kombinationen herunterzuladen. (Natürlich nicht alle, wobei die Gesamtgröße "nur" bei ca. 36GB liegen würde)
Ist da Selenium da die beste Wahl, oder gibt es eine bessere Methode? Und hat jemand von euch effektive Algorithmen parat, um die Kombinationen zu generieren?
1 Antwort
Ich würde versuchen folgendes zu modifizieren:
Ich würde mir eine Liste mit den 5 stelligen Strings anlegen, welche heruntergeladen werden sollen. (könnte man auch in einer file speichern um nicht bei jedem Programmaufruf alles neu erstellen zu müssen)
Dann muss nur in der download_url(kombination) der string Kombination an die URL angehängt werden.
Desweiteren könnte man die Anzahl der laufenden threads beschränken...
Ob das möglichst effizient ist, weiß ich nicht nicht. Aber eine schnelle Lösung wäre es
Ich habe es jetzt mal so gelöst:
import itertools
import string
liste = list(map(str,range(0,10)))+ list(string.ascii_lowercase) #erzeugt Liste mit allen Characters
#print(liste)
combis_map = map("".join,list(itertools.combinations(liste,5))) #liefert alle combinationen als map zurück
combis_list = list(combis_map) #eine Liste
bei mir sind es ungefähr 80ms im Mittel für alle Kombinationen. Geht vielleicht noch schneller. Aber für den ersten Versuch klingt es ganz zufriedenstellend.
doppelt so schnell gehts so hier:
import itertools
import string
text = string.digits+ string.ascii_lowercase
combis_map = map("".join,itertools.combinations(text,5))
combis_list = list(combis_map)
Hatte ein bisschen zu viele list castings drin.
Was mich aber wundert, warum ich nicht über die combis_map iterieren kann... seltsam!
Ohje. Jetzt hab ich's aber einigermaßen:
Man sollte combinations_with_replacement verwenden dann bekommt man auch alle Kombinationen.
Das join macht das Problem mit dem iterator... deshalb jetzt so:
import itertools
import string
text = string.digits + string.ascii_lowercase #erzeugt Liste mit allen Characters
#print(liste)
combis_iter = itertools.combinations_with_replacement(text,5)
#Ein Funktionstest
#for i in range(100):
# print("".join(next(combis_iter)))
#eine Beispiel:
for i in combis_iter:
combi = "".join(i)
#print("".join(i)) wieder Funktionstest
download_pic(url+combi)
#geht auch mit "".join(next(combis_iter))...
Der Iterator ist in ca 650ns gebastelt.
Moin,
vielen Dank für deine Mühe! :) Habe bisher nicht besonders viel Erfahrung mit itertools. Ich habe deinen Algorithmus ein wenig umgebaut und habe folgende Buchstaben "im Topf"
ACHPacefhilorstu
Die zu bauenden Wörter sind zwischen 20 und 25 Zeichen lang. Eine Comboliste mit allen Kombinationen zu erstelle wäre zu viel, da die Datei riesig wäre...
Mir ist aber bekannt, dass jeder Großbuchstabe nur 1x vorkommt und niemals 2 Großbuchstaben hintereinander kommen. Kann ich solche Extra Regeln noch einbauen und wenn ja, wie? ^^
So könnte man eine MENGE Speicher sparen, da die Kombinationen wie z.B
CCCCCCCCCCCCCCCCCCCCCCa
wegfallen ^_^
Ersetze mal
combis_iter = itertools.combinations_with_replacement(text,5)
durch
combis_iter = itertools.combinations(text,5)
Passt das?
Wäre z.B "CaaBa" auch ausgeschlossen? Denn Kleinbuchataben kommen nicht nur 1 Mal vor
Das reine erstezen hat nicht funktioniert... Das Skript beendet sich sofort mit exit code 0, als wäre es abgeschlossen, printed aber nix oder schreibt etwas in mein file
Ja das wäre auch ausgeschlossen.
Wie wäre es wenn du es mit einem langsamen Programm erzeugst, die ganze Liste dann in eine Datei speicherst und sie somit schnell abrufen kannst?
Danke ^^
Hast du eine Idee für einen effizienten Algorithmus, um die Kombinationen zu generieren? 60 Millionen Codes wollte ich ungern per Hand schreiben :p