Passwort-Generator

Code-Stücke können hier veröffentlicht werden.
Üpsilon
User
Beiträge: 222
Registriert: Samstag 15. September 2012, 19:23

Kennt Ihr das? Man will sich irgendwo registrieren und einem fällt kein gutes Passwort ein. :?: :?: :?:
Da hilft das hier: :!: :!: :!: :arrow:

Code: Alles auswählen

#!/usr/bin/python
# -*- coding:utf-8 -*-
# Passwort-Generator
# Programmiert von Üpsilon
# Oktober 2012, Mainz, OT Hartenberg-Münchfeld

from random import choice
zahlen = ("1", "2", "3", "4", "5", "6", "7", "8", "9", "0")
grossb = ("Q", "W", "E", "R", "T", "Z", "U", "I", "O", "P", "Ü", "A", "S", "D", "F", "G", "H", "J", "K", "L", "Ö", "Ä", "Y", "X", "C", "V", "B", "N", "M")
kleinb = ("q", "w", "e", "r", "t", "z", "u", "i", "o", "p", "ü", "a", "s", "d", "f", "g", "h", "j", "k", "l", "ö", "ä", "y", "x", "c", "v", "b", "n", "m")
sonderz = ("^", "!", "\"", "§", "$", "%", "&", "/", "(", ")", "=", "?", "ß", "\\", "+", "*", "<", ">", "|", "'", "#", ",", ";", ":", "-", "_", "{", "}", "[", "]", "~")

wort = ""
zusammensetzung = (zahlen, grossb, kleinb, sonderz, grossb, kleinb, zahlen, grossb, kleinb, sonderz, grossb, kleinb, zahlen, grossb, kleinb, sonderz, grossb, kleinb)
for teil in zusammensetzung:
    zeichen = choice(teil)
    wort += zeichen

datei = open("passwort.txt", "a")
thema = raw_input("Gib ein, wofür du das Passwort brauchst: ")
datei.write(thema + ": "
datei.write(wort + "\n")
datei.close()
Wie gefällt euch das? Hat jemand Vorschläge für Verbesserungen??? Vielen Dank für Antworten! :D :mrgreen: :lol:
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

das string-modul hat diese Konstanten bereits definiert (ausgenommen Sonderzeichen): http://docs.python.org/library/string.h ... -constants.

Des Weiteren, könntest das Generieren des Passworts in eine Funktion packen, und das Schreiben in eine Zweite, somit wird dein Skript flexibler.
the more they change the more they stay the same
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hinzu kommz dann noch, dass die Zeichen bei dir nicht gleichverteilt sind. Die Wahrscheinlichkeit einer "1" ist bei dir größer als die Wahrscheinlichkeit eines "A"s.

Dann kommt noch hinzu, dass Zeichen bereits Sequenzen sind, der Umweg über Tupel ist unnötig. Auch solltest du das Wort nicht mittels += zusammensetzen, sondern die Buchstaben in eine Liste packen und später mit "".join zusammenfügen. Ein Blick auf das with-Statement, in diesem Fall zum Öffnen und automatischem Schließen von Datien, ist es ebenfalls wert.
Das Leben ist wie ein Tennisball.
Üpsilon
User
Beiträge: 222
Registriert: Samstag 15. September 2012, 19:23

Danke!!!

Code: Alles auswählen

#!/usr/bin/python
# -*- coding:utf-8 -*-
# Passwort-Generator
# Oder ein Programm, was das Schreiben in Dateien, random.choice() und die string-Konstanten demonstriert
# Programmiert von Üpsilon
# Oktober 2012, Mainz, OT Hartenberg-Münchfeld

import string
from random import choice
def erstelle_passwort():
    alle_zeichen= ["^", "!", "\"", "§", "$", "%", "&", "/", "(", ")", "=", "?", "ß", "\\", "+", "*", "<", ">", "|", "'", "#", ",",";",   ":",  "-", "_", "{", "}", "[", "]", "~"]
    for i in string.letters: alle_zeichen.append(i)
    for i in string.digits: alle_zeichen.append(i)

    wort_buchstaben = []
    for i in range(20):
        zeichen = choice(alle_zeichen)
        wort_buchstaben.append(zeichen)
    wort = "".join(wort_buchstaben
    return wort

wort = erstelle_passwort()
datei = open("passwort.txt", "a")
thema = raw_input("Gib ein, wofür du das Passwort brauchst: ")
datei.write(thema + ": "
datei.write(wort + "\n")
datei.close()
Das mit dem with muss ich mir mal angucken, wie das geht. :K
MfG Y :mrgreen:
PS: Die angebotene Summe ist beachtlich.
Benutzeravatar
/me
User
Beiträge: 3554
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Üpsilon hat geschrieben:

Code: Alles auswählen

    for i in string.letters: alle_zeichen.append(i)
    for i in string.digits: alle_zeichen.append(i)
Das geht einfacher und schöner.

Code: Alles auswählen

alle_zeichen.extend(string.ascii_letters)
alle_zeichen.extend(string.digits)
Üpsilon hat geschrieben:

Code: Alles auswählen

    wort_buchstaben = []
    for i in range(20):
        zeichen = choice(alle_zeichen)
        wort_buchstaben.append(zeichen)
    wort = "".join(wort_buchstaben
Das kann man mit einem Generator-Ausdruck einfacher gestalten.

Code: Alles auswählen

wort = ''.join(random.choice(alle_zeichen) for i in xrange(20))
Ich habe hier bewusst random.choice verwendet statt choice in den Namensraum zu importieren, da ich es schöner finde wenn ich beim Lesen direkt weiß wo etwas herkommt. Du kannst das natürlich halten wie du möchtest.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Eine Anmerkung noch zum Arbeiten mit File-Objekten: Dateien solltest Du immer mittels ``with`` öffnen, da damit sicher gestellt ist, dass die Datei in jedem Falle geschlossen wird (also auch im Falle einer Exception):

Code: Alles auswählen

with open(...) as handler:
    # handler ist hier das File-Objekt
Du kannst Dir damit auch das explizite Aufrufen von ``close`` sparen.

Zudem würde ich die Zugriffe eher "kurz" halten und die Datei erst dann öffnen und schreiben, wenn de "Arbeit" getan ist, sprich, die Benutzereingaben getätigt und das Passwort erstellt sind.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Üpsilon
User
Beiträge: 222
Registriert: Samstag 15. September 2012, 19:23

Donnerwetter, hier lernt man ja 'ne Menge! :idea: Ist es so okay :arrow:

Code: Alles auswählen

#!/usr/bin/python
# -*- coding:utf-8 -*-
# Passwort-Generator
# Programmiert von Üpsilon mit der Hilfe von vielen Anderen
# Oktober 2012, Mainz, OT Hartenberg-Münchfeld

import string, random
def erstelle_passwort():
    alle_zeichen= ["^", "!", "\"", "§", "$", "%", "&", "/", "(", ")", "=", "?", "ß", "\\", "+", "*", "<", ">", "|", "'", "#", ",",";",   ":",  "-", "_", "{", "}", "[", "]", "~"]
    alle_zeichen.extend(string.ascii_letters) 
    alle_zeichen.extend(string.digits)

    wort_buchstaben = []
    wort = "''.join(random.choice(alle_zeichen) for i in xrange(20))
    return wort

wort = erstelle_passwort()
thema = raw_input("Gib ein, wofür du das Passwort brauchst: ")
text = thema + ": " + wort + "\n"
with open("passwort.txt","a") as pw_datei:
    pw_datei.write(text)
Ist ja total kurz geworden, Vielen Dank! :D
PS: Die angebotene Summe ist beachtlich.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Naja, da kann man schon noch etwas verbessern:

- ``wort_buchstaben = []`` ist überflüssig

- Das Zusammensetzen der Zeichen würde ich per ``str.join``-Methode lösen. Mal so als Denkanstoß:

Code: Alles auswählen

char_base = "".join((string.digits, ".-+"))
- Ich würde die Zeichenmenge auch auf Modulebene definieren, da sie augenscheinlich immer als Basis für das Generieren herhält. Wozu das also immer wieder in der Funktion zusammenbauen? (Wenn man diese konfigurierbar machen möchte, dann würde ich die Erstellung der Menge sowieso vom Code für das Generieren entkoppeln und separat verfügbar machen)

- Muss es denn so ein selbstgebasteltes Textformat sein? Wieso nicht einfach JSON (mittels des ``json``-Moduls oder eben auch CSV mittels des ``csv``-Moduls nutzen? Zudem könnte man sich dann das anhängen sparen und die Datei immer als ganze auslesen und somit die bisherigen Daten verfügbar machen. Ja selbst das INI-Format mittels ``configparser`` könnte man sich hier vorstellen...

- Selbst wenn Du so weiter machen willst, solltest Du Strings nicht per ``+`` zusammen setzen. Das liest sich doch unschöner, als:

Code: Alles auswählen

text = "%s: %s" % (thema, wort)
# oder auch
text = "{}: {}".format(thema, wort)
Überhaupt müsstest Du das nicht temporär an ``text`` binden, da Du damit eh nichts anderes machst, als das String-Objekt in die Datei zu schreiben. Das Zusammenbauen kannst Du auch *direkt* im ``write`` erledigen.

- Als letztes: Kapsele Deinen "Client"-Code in folgendem Snippet:

Code: Alles auswählen

def main():
    wort = erstelle_passwort()
    # usw.

if __name__ == "__main__":
    main()
Damit hast Du keinen ausführbaren Code auf Modulebene stehen und Du kannst das ganze auch leicht als Modul für andere Programme nutzen. Selbst wenn Du das (noch) nicht vor hast, würde ich mir das einfach immer angewöhnen. Du kannst Dir für den allgemeinen Aufbau eines Python-Moduls ja ein Template für Deinen Editor bauen bzw. eines nutzen - die meisten guten Editoren bieten dafür ja Unterstützung an. Damit musst Du das nicht alles immer per Hand tippen ;-) (Dazu gehört auch der Kopf, mit dem Shebang und das Encoding-Cookie)

- Ach doch noch etwas:

Code: Alles auswählen

# Passwort-Generator
# Programmiert von Üpsilon mit der Hilfe von vielen Anderen
# Oktober 2012, Mainz, OT Hartenberg-Münchfeld
Das gehört eher in einen DocString, als in einen Kommentar. Z.B. so:

Code: Alles auswählen

"""
Passwort-Generator

Programmiert von Üpsilon mit der Hilfe von vielen Anderen
Oktober 2012, Mainz, OT Hartenberg-Münchfeld    
"""
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Statt dem:

Code: Alles auswählen

alle_zeichen= ["^", "!", "\"", "§", "$", "%", "&", "/", "(", ")", "=", "?", "ß", "\\", "+", "*", "<", ">", "|", "'", "#", ",",";",   ":",  "-", "_", "{", "}", "[", "]", "~"]
Besser das:

Code: Alles auswählen

alle_zeichen = r""""^!"§$%&/()=?ß\+*<>|'#,;:-_{}[]~"""
Dadurch dass es ein Multi-Line-String ist brauchst du ein Double-Quote nicht escapen, dadurch dass es ein Raw-String ist brauchst du \ nicht escapen, dadurch dass es ein String statt einer Liste von Strings ist brauchst du auch nicht so viele Strings tippen und es funktioniert genauso.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
BlackJack

An alle die die Sonderzeichen nicht als Liste sondern literale Zeichenkette schreiben wollen: Ihr denkt schon daran dass das nur bei 8-Bit-Kodierungen des Quelltextes oder Unicode-Zeichenketten geht‽ Wenn das zum Beispiel Python 2.x mit `utf-8` als Kodierung ist, dann kommt bei ``random.choice('äöüß')`` niemals etwas sinnvolles bei heraus. Bei ``random.choice(['ä', 'ö', 'ü', 'ß'])`` dagegen schon.
Üpsilon
User
Beiträge: 222
Registriert: Samstag 15. September 2012, 19:23

Bin gerade etwas in eile, aber trotzdem danke für alles an alle. :lol:

Code: Alles auswählen

#!/usr/bin/python
# -*- coding:utf-8 -*-
"""Passwort-Generator
Programmiert von Üpsilon mit der Hilfe von vielen Anderen
Oktober 2012, Mainz, OT Hartenberg-Münchfeld
"""

import string, random
alle_zeichen= ["^", "!", "\"", "§", "$", "%", "&", "/", "(", ")", "=", "?", "ß", "\\", "+", "*", "<", ">", "|", "'", "#", ",",";",   ":",  "-", "_", "{", "}", "[", "]", "~"]
alle_zeichen.extend(string.ascii_letters)
alle_zeichen.extend(string.digits)

def erstelle_passwort():
    wort = ''.join(random.choice(alle_zeichen) for i in range(20))
    return wort

def main():
    wort = erstelle_passwort()
    thema = input("Gib ein, wofür du das Passwort brauchst: ")
    text = "%s: %s\n" %(thema, wort)
    with open("passwort.txt","a") as pw_datei:
        pw_datei.write(text)

main()
PS: Die angebotene Summe ist beachtlich.
Benutzeravatar
/me
User
Beiträge: 3554
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

BlackJack hat geschrieben:Wenn das zum Beispiel Python 2.x mit `utf-8` als Kodierung ist, dann kommt bei ``random.choice('äöüß')`` niemals etwas sinnvolles bei heraus.
Wer verwendet denn ein aktuelles Python 2 ohne

Code: Alles auswählen

from __future__ import unicode_literals
? :D
nomnom
User
Beiträge: 487
Registriert: Mittwoch 19. Mai 2010, 16:25

Möchte nur mal kurz anmerken: Es gibt auch das Programm pwgen, mit dem man ebenfalls Passwörter generieren kann, das aber ein paar mehr Optionen hat und (nach Wunsch) Passwörter generiert, die man sich leichter merken kann, weil man sie aussprechen kann. Vielleicht kannst du dich ja auch daran mal versuchen?

P.S.: https://xkcd.com/936/
Üpsilon
User
Beiträge: 222
Registriert: Samstag 15. September 2012, 19:23

nomnom hat geschrieben:Möchte nur mal kurz anmerken: Es gibt auch das Programm pwgen, mit dem man ebenfalls Passwörter generieren kann, [...] Vielleicht kannst du dich ja auch daran mal versuchen?
@nomnom: Jajaja, kann sein, nett von dir, danke. Aber ich hab mein Programm zum Üben geschrieben :mrgreen: :D :lol:
Vielleicht guck ich's mir mal an.
PS: Die angebotene Summe ist beachtlich.
BlackJack

Man kann sich auch ein Passwort von einer Suchmaschine geben lassen: http://duckduckgo.com/?q=password+42 :-)
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Aber dann weiß doch DDG was man für ein Passwort verwendet hat! :p
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Ich finde den Encoding-Hinweis von BlackJack durchaus wichtig und würde es noch weiter ausdehnen - spätestens wenn das Passwort gespeichert, gehasht oder de-crypt()-et werden soll, ist die Frage nach der eigentlichen Bytefolge wichtig. Will man dann auch noch mit einem anderen Tool als aus Python heraus das Passwort nutzen, können exotische Sonderzeichen aus dem Unicoderaum zum Spielverderber werden. Abhilfe schafft da nur die genaue Festlegung des Encodings vor der Verarbeitung des Passwortes. (Und unter Windows sind die Python Unicode-Literale intern nach wie vor UTF16 kodiert, während die meisten unixoiden Systeme inzwischen auf UTF32 setzen, ganz abgesehen von der BE/LE-Problematik)
Üpsilon
User
Beiträge: 222
Registriert: Samstag 15. September 2012, 19:23

Üpsilon hat geschrieben: [...] Aber ich hab mein Programm zum Üben geschrieben :mrgreen: :D :lol: [...]
@Blackjack: Ich wiederhole: Ich habe mein Programm zum ÜBEN geschrieben
und nur hochgeladen, weil ich was lernen wollte. (Das ist auch passiert.)
Aber jetzt wissen wenigstens alle, wo man Passwörter herkriegt
Edit: Von DuckDuckGo, aus pwgen oder von WolframAlpha (nach password suchen).
Oder aus komischen primitiven Python-Programmen.
PS: Die angebotene Summe ist beachtlich.
rolgal_reloaded
User
Beiträge: 312
Registriert: Dienstag 24. Oktober 2006, 19:31

Üpsilon hat geschrieben:Bin gerade etwas in eile, aber trotzdem danke für alles an alle. :lol:

Code: Alles auswählen

#!/usr/bin/python
# -*- coding:utf-8 -*-
"""Passwort-Generator
Programmiert von Üpsilon mit der Hilfe von vielen Anderen
Oktober 2012, Mainz, OT Hartenberg-Münchfeld
"""

import string, random
alle_zeichen= ["^", "!", "\"", "§", "$", "%", "&", "/", "(", ")", "=", "?", "ß", "\\", "+", "*", "<", ">", "|", "'", "#", ",",";",   ":",  "-", "_", "{", "}", "[", "]", "~"]
alle_zeichen.extend(string.ascii_letters)
alle_zeichen.extend(string.digits)

def erstelle_passwort():
    wort = ''.join(random.choice(alle_zeichen) for i in range(20))
    return wort

def main():
    wort = erstelle_passwort()
    thema = input("Gib ein, wofür du das Passwort brauchst: ")
    text = "%s: %s\n" %(thema, wort)
    with open("passwort.txt","a") as pw_datei:
        pw_datei.write(text)

main()

Ich habe mich neben diesem Code auch mit einigen anderen in der Rubrik Codesnippets beschäftigt. An dem Thread hat mir ganz gut gefallen, dass er didaktisch verwertbar ist, was hier sonst leider selten der Fall ist. Man kann schön die Schritte, die Verbesserungen nachvollziehen bzw. thematiseren.
Dennoch gibt es hier doch noch einen Fehler, oder nicht?

Code: Alles auswählen

thema = input("Gib ein, wofür du das Passwort brauchst: ")
Ist vielleicht etwas vorrangiger als div. Encodingüberlegungen :?:

LG, rolgal_reloaded
Antworten