Seite 1 von 1

Password-Generator

Verfasst: Donnerstag 24. August 2006, 20:04
von blinx
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

Verfasst: Donnerstag 24. August 2006, 23:23
von Masaru
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<<

Verfasst: Dienstag 10. Oktober 2006, 11:04
von 7crystal7
auch danke von mir, ist eine tolle Lösung.

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

assert isinstance?

Danke
Babsi

Verfasst: Dienstag 10. Oktober 2006, 11:55
von mitsuhiko
Aus dem Pocoo Quellcode eine Funktion um leicht zu merkende Passwörter zu erstellen: http://trac.pocoo.org/browser/pocoo/tru ... ext.py#L61

Verfasst: Dienstag 10. Oktober 2006, 16:10
von Leonidas
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))

Verfasst: Dienstag 10. Oktober 2006, 16:49
von Y0Gi
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.

Verfasst: Mittwoch 11. Oktober 2006, 21:56
von Masaru
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<<

Verfasst: Mittwoch 11. Oktober 2006, 22:39
von 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.

Verfasst: Mittwoch 11. Oktober 2006, 23:49
von Y0Gi
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.

Verfasst: Donnerstag 12. Oktober 2006, 13:25
von Leonidas
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.

Verfasst: Donnerstag 12. Oktober 2006, 14:41
von Masaru
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 ;).

Verfasst: Donnerstag 12. Oktober 2006, 15:03
von Leonidas
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.

Verfasst: Donnerstag 12. Oktober 2006, 15:22
von Masaru
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<<

Verfasst: Donnerstag 12. Oktober 2006, 16:57
von Y0Gi
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.