Password-Generator

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
blinx
User
Beiträge: 8
Registriert: Montag 10. Juli 2006, 19:30

Hi @ all!
Nun habe ich vor einen PW Gen zu programmieren. Dieser soll per Browser funktionieren, ähnlich wie der hier:

http://www.us-webmasters.com/Random-Password-Generator/

Kann ich das hier als Vorlage nehmen?
http://www.python-forum.de/topic-1812.html

DANKE

Gruß
Benny
Benutzeravatar
Masaru
User
Beiträge: 425
Registriert: Mittwoch 4. August 2004, 22:17

Ich würde mir eher gehörig Gedanken um die WebServer und Template-Engine machen, als um das bisschen Character-Gewürfel für die Passwörter ;).

Ich kann sowohl:
- Django
wie auch:
- Skakelets
empfehlen.

Was den Passwort-Generator an sich angeht ... joa ... der Thread http://www.python-forum.de/topic-1812.html kann dir als Vorlage dienen, obwohl es auch ein wenig einfacher wohl für einen ersten Wurf geht.

Das Ziel des Threads ziehlt doch etwas mehr auf die Brute Force Idee als auf einfaches Randomizen hin ab.

Ich denke mit random (Python Standard Module) sollte es für den Anfang verständlicher gehen.

Bsp:

Code: Alles auswählen

>>> import random
>>> import string
>>> 
>>> charmap = string.letters + string.digits + '*/\\!?'
>>> charmap
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789*/\\!?'
>>> 
>>> def gen_pass(len_pass):
... 	assert isinstance(len_pass, int)
... 	new_pass = ''
... 	for x in range(0, len_pass):
... 		new_pass += random.choice(charmap)
... 	return new_pass
... 
>>> gen_pass(2)
'Ug'
>>> gen_pass(5)
'R5ZJN'
>>> gen_pass(8)
'K9gY1dlu'
>>> 
Wenn man in einem Wurf eine Anzahl von Passwörter natürlich haben möchte, diei eindeutig sind, so muss man dies noch Plausbilitätstechnisch implementieren (liste, set, dict ... wie's immer auch einem passt :D).

>>Masaru<<
7crystal7
User
Beiträge: 46
Registriert: Freitag 26. Mai 2006, 18:50

auch danke von mir, ist eine tolle Lösung.

Was ich nicht ganz verstehe, für was machst Du das

assert isinstance?

Danke
Babsi
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Aus dem Pocoo Quellcode eine Funktion um leicht zu merkende Passwörter zu erstellen: http://trac.pocoo.org/browser/pocoo/tru ... ext.py#L61
TUFKAB – the user formerly known as blackbird
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Oder ein Ausschnitt aus dem Shorty-Quellcode, der zufällige URLs generiert:

Code: Alles auswählen

import string

def gen_short(length=8, chars=string.letters + string.digits):
    """Generator for random, short sequences.
    Modified from a password generator in the Python Cookbook
    http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/59873"""
    return ''.join(random.choice(chars) for i in range(length))
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Ich steuere den Kern meines kleinen Mnemonic Password Generator bei:

Code: Alles auswählen

import random


# Some consonants were left out for clarity or better pronunciation.
CHARSET = ('bdfghklmnprstvwz', 'aeiou') # consonants, vowels


def generateMnemonicPassword(letters=8, digits=4, uppercase=False):
    """Generate a random mnemonic password."""
    chars = ''.join([random.choice(CHARSET[i % 2]) for i in range(letters)])
    if uppercase:
        chars = chars.upper()
    chars += ''.join([str(random.randrange(0, 9)) for i in range(digits)])
    return chars


if __name__ == '__main__':
    print 'Generating sample passwords with alternating case:'
    for i in range(10):
        print generateMnemonicPassword(uppercase=i%2)

Übrigens mag sich mancher denken: "Warum benutzt der nicht nur einmal am Ende join() und fügt nicht erst alle Zeichen einer Liste hinzu?"
Grund: Den Tests mit dem timeit-Modul nach war dies die schnellste Lösung mit wenig Code. Vielleicht sieht das auf aktuellen Python-Versionen aber anders aus.
Benutzeravatar
Masaru
User
Beiträge: 425
Registriert: Mittwoch 4. August 2004, 22:17

Mit asserts kannst du einfach eine Art "Absicherung" auf eine Erwartung einbauen. Falls die Erwartung nicht eintritt, so wird ein AssertionError geraised.

Ganz einfach wäre z.B.

Code: Alles auswählen

assert x<0
... was im Falle dass eben x nicht kleiner als 0 ist, der besagte AssertioError geworfen wird.

In meinem Codesnippet sichere ich hingegen ab, isinstance() (meint: der erste Parameter dieser Methode entspricht dem Typ, deklariert durch den zweiten Parameter) von len_pass träfe zu, es handele sich um einen Integer.

Wenn als len_pass kein Integer ist, dann bricht das ganze an der Stelle ab ;) ... dient dem Zwecke, dass nicht einfach mit dem Wert weiter umgegangen wird, Methoden angewendet werden, etc. als wäre es ein Integer (z.B. eine Division auf einen String wäre nicht ganz so sinnvoll).
Man hätte es natürlich auch noch anders lösen können, aber gerade im Protoyping-Prozess sind Assertions sehr nützlich.

In einer fertigen Lösung könnte man hingegen allgemein eine eigene Exception werfen (mit einem Fehlercode und optional eine variablen Anzahl von Paramtern), die dann von einer übgeordneten Instanz gecatched und auf eine Message Text Liste gemapped ... die vollständige Fehlermeldung (eventuell gar MultiLanguage supported) werfen. Wenn Dich in die Richtung etwas mehr interessiert, dann einfach fragen.

Gruß,
>>Masaru<<
BlackJack

Wobei diese Absicherung in meinen Augen "unpythonisch" ist. Wenn Du eine Zeichenkette übergibst, dann wird schon früh genug eine Ausnahme ausgelöst.

Andererseits würde Dein Code auch prima mit 5.0 oder 7L funktionieren, wenn Du das nicht so "gewaltsam" abwürgen würdest. Das läuft dem "duck typing" zuwider.
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Ich sehe das ähnlich. Python hat kein static typing und wenn man die Typen nicht direkt in der Funktionssignatur angeben kann, dann sollte man da nicht auch noch mit Assertions versuchen, das nachzubilden - es bläht alles deutlich auf. Gerade wenn eine Funktion etwa eine Ganzzahl erwartet und als erstes z.B. eine range erzeugt wird, wird sich direkt über den falschen Typ beschwert. Wer nicht in die Doku guckt, kann in den Source gucken - aber der Funktionsname selbst sollte natürlich schon gut genug sein, an zweiter Instanz muss der Docstring den Rest verdeutlichen. Und wenn die Parameter gut benannt sind, hilft help() auch schon weiter.

Ansonsten kann man glaube ich mit einem Schalter auch Bytecode erzeugen, der die Assertions nicht mehr enthält.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Y0Gi hat geschrieben:Ansonsten kann man glaube ich mit einem Schalter auch Bytecode erzeugen, der die Assertions nicht mehr enthält.
Wenn man Python mit -O oder -OO startet, werden Assertions nicht mehr ausgewertet, __debug__ wird dabei auch auf False gestellt.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
Masaru
User
Beiträge: 425
Registriert: Mittwoch 4. August 2004, 22:17

Vielleicht ist eine assert wirklich nicht die optimalste Lösung ... dafür aber pragmatisch :D.

Und wie erwähnt: deaktivierbar (für den finalen Wurf)

Im Falle einer WebAnwendung mit Benutzerinteraktion würde blinx aber wohl nicht um eine Typ-Prüfung, bzw. -Konvertierung (mit ExceptionHandling) herrum kommen ... möglich (und ratsam) auch ohne Assertions ;).
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Masaru hat geschrieben:Im Falle einer WebAnwendung mit Benutzerinteraktion würde blinx aber wohl nicht um eine Typ-Prüfung, bzw. -Konvertierung (mit ExceptionHandling) herrum kommen ... möglich (und ratsam) auch ohne Assertions ;).
FormEncode? Wieder eine Ian Bicking-Produktion, die von TurboGears verwendet wird.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
Masaru
User
Beiträge: 425
Registriert: Mittwoch 4. August 2004, 22:17

Falls möglich ... eine pragmatische Sache. Falls nicht könnte man z.B.:

Code: Alles auswählen

# ---------- Anwendungs-Code ------------...
def methode(x):
    try:
        x_int = int(x)
    except ValueError:
        raise MeineFehlerklasse(error_code, x)
...

#-------------- WebFramework/Template/owe -----------
try:
   methode(user_input)
except MeineFehlerKlasse:
   error_message = # Error_code und Paramter mit MultiLanguage Quelle auswerten

# 'error_message' mittels Template ausgeben
Abe sein wir doch mal ganz ehrlich, wie auch immer, Typ-Prüfungen und eventuell Eingabefehler-Notifikationen im Falle von Benutzerinteraktionen sollten immer erfolgen: so oder so.

Gruß,
>>Masaru<<
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Direkt vom Benutzer: ja.
Innerhalb der Anwendung: nein. Die API sollte klar definieren, was für Typen erwartet werden und dann muss man sich einfach dran halten und gut.
Antworten