Kennworterzeugung anpassen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Marek06
User
Beiträge: 13
Registriert: Dienstag 17. April 2012, 08:51

Okay, ich schaue mir die Grundlagen dazu nochmal an. :)
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@Marek06: Zum utilGeneral: Die von Dir angeführten Funktionen sehen so aus, als ob sie sehr einfach durch irgendetwas aus der Standardbibliothek zu ersetzen wären. Warum also eine unnötige und komplizierte Abhängigkeit schaffen???
Kannst Du mir den Sinn der »for«-Schleife erklären? Du würfelst die Reihenfolge, wann s, t, u und v definiert werden.
Dadurch baust Du Dir neben der Wiederholung fast identischem Codes zusätzlich noch eine »if«-Kaskade ein, die nichtmal eine ist, weil Du statt »elif« tatsächlich jedesmal »if« nimmst. Übrigens, Klammern um Bedingungen wo sie nicht gebraucht werden, solltest Du löschen.
Dein Ziel sollte es sein mit nur einem[/b| »random.choice« auszukommen, weil die Zeichenmengen mit ihrer Häufigkeit in einer Liste gespeichert wird, die dann von einer for-Schleife abgearbeitet wird.
Das Vorhandensein von »flag«, »param« und »config« erschließt sich mir in einer Funktion zum Erzeugen eines Passworts nicht.
BlackJack

@Marek06: Das ziemlicher Unsinn was da gemacht wird. Wozu soll `x` und die Schleife gut sein? Das hätte man sich komplett sparen können. `zahl`, `x`, und die Schleife haben keinen Einfluss auf das Ergebnis.

`param` wird nirgends benutzt.

Was soll `chars_up_lo` bedeuten? Wenn ich richtig geraten habe passt der Name nicht zum Wert. `zahl` passt ebenfalls nicht, denn das ist keine Zahl. `zahl_ind` ist zumindest fragwürdig. Die Namen `a` und `y` gehen ja mal gar nicht.

`config` ändern *und* den Wert zurück geben ist irgendwie redundant, die Funktion zum generieren eines Passwortes sollte auch wirklich nur das tun: Ein Passwort generieren.

Deinen Quelltext kann man auf das hier eindampfen:

Code: Alles auswählen

    if flag:
        password_characters = [
            ''.join(random.choice(chars) for _ in range(length))
            for chars, length in [
                (string.uppercase, 1),
                (string.digits, 2),
                (string.lowercase, 3),
                (string.punctuation, 1),
            ]
        ]
        random.shuffle(password_characters)
        return (
            random.choice(string.lowercase + string.uppercase + string.digits)
            + ''.join(password_characters)
        )
Allerdings ist das Passwort nicht so gut wie es sein könnte, denn die einzelnen „Klassen” von Zeichen werden als komplette Gruppe ”gemischt”. Sinvoller wäre es am Ende alle Zeichen zu mischen, damit nicht immer alle Ziffern, alle Grossbuchstaben, usw. zusammen stehen.
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

@Marek06:
Überhaupt wären die Passwörter stärker, wenn Du keine Bedingungen an das Zeichenvorkommen stellst sondern einfach den Zeichenvorrat und die Länge hinreichend groß wählst. Z.B. führte bei der Enigma die Festlegung für das Steckerbrett - dass kein Zeichen auf sich selbst verweisen darf - zu einer Reduktion des Suchraumes um mehrere 10er Potenzen.
Ist der Zeichenvorrat groß, sind triviale Passwörter eh unwahrscheinlich, wenn Du sie (gut randomisiert) generierst.
Marek06
User
Beiträge: 13
Registriert: Dienstag 17. April 2012, 08:51

Nochmals danke für die Tipps (wäre ich sonst nicht so schnell drauf gekommen) :D :D :D

Das Passwort hat bestimmte Voraussetzungen die erfüllt sein müssen (z. B. nicht länger als 8 Zeichen, ... s.o)

Ich habe den Vorschlag aufgenommen und habe es entsprechend angepasst (bestimmt könnte es immer noch besser sein, aber es funktioniert - 8) - mit Grundlagen wäre das bestimmt besser gegangen). Zum Durchmischen der Buchstaben habe ich jetzt den String in eine Liste übertragen und dann erneut ein shuffle drauf gemacht, womit dann auch nicht die ganzen Blöcke getauscht werden.

Code: Alles auswählen

if flag:
        number=[1, 2, 3, 1]
        random.shuffle(number) 
       	password_characters = [
            ''.join(random.choice(chars) for _ in range(length))
            for chars, length in [
                (string.uppercase, number[0]),
                (string.digits, number[1]),
                (string.lowercase, number[2]),
                (string.punctuation, number[3]),
            ]
        ]
        password_characters_tmp=''.join(password_characters)
        password_characters=[]
        for c in password_characters_tmp: password_characters.append(c)
        random.shuffle(password_characters)

        return (
            random.choice(string.lowercase + string.uppercase + string.digits) + ''.join(password_characters)
        )
    return ''
BlackJack

@Marek06: Das ist immer noch furchtbar kompliziert und ich verstehe auch immer noch nicht was das mit `number` werden soll. Ich habe so das Gefühl das erfüllt zwar die tatsächlichen Anforderungen, schränkt aber deutlich zu stark ein. Was sind denn die Einschränkungen? Sinn machen würde 8 Zeichen und dabei mindestens ein Zeichen aus den Gruppen Kleinbuchstaben, Grossbuchstaben, Ziffern, Sonderzeichen (Interpunktion). Da gäbe es aber deutlich mehr Möglichkeiten als Dein Code erzeugt, der wäre dann also unnötig einschränkend. Und wie gesagt: Zu kompliziert.

Edit:

Code: Alles auswählen

def generate_password(length=8):
    groups = [
        string.lowercase, string.uppercase, string.digits, string.punctuation
    ]
    result = [random.choice(g) for g in groups]
    all_characters = ''.join(groups)
    result.extend(
        random.choice(all_characters) for _ in range(length - len(result))
    )
    random.shuffle(result)
    return ''.join(result)[:length]
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Warum erzeugst Du erst Listen von Strings, dann einen String um dann wieder daraus eine Liste zu machen (es gibt übrigens »list« dafür)?

Wenn man alles zusammenfasst, kommt ungefähr das raus:

Code: Alles auswählen

import string
import random

def generate_password(length):
    sets = [string.uppercase, string.lowercase, string.digits, string.punctuation]
    sets2 = [''.join(sets[:-1])]+random.sample(sets + [''.join(sets)]*(length-len(sets)-1), length-1)
    return ''.join(map(random.choice, sets2))
Marek06
User
Beiträge: 13
Registriert: Dienstag 17. April 2012, 08:51

Folgende Konventionen sind gefordert:

1. Das 1 Zeichen darf nur Großbuchstabe, Kleinbuchstabe, Zahl sein
2. Genau 8 Zeichen
3. Insgesamt muss im Kennwort 1 Kleinbuchstabe, Großbuchstabe, Zahl, Zeichen vorhanden sein

Mit dem Attribut 'number' wollte ich sicher, dass ich z.B nicht festlege - immer 3 Großbuchstabe oder 3 Kleinbuchstaben oder 3 Zahlen - sondern das jedesmal variable erzeugt wird. Und mit der 2 Liste wollte ich sicher gehen, dass alle 7 Zeichen und nicht die Blöcke gemischt werden (außer das 1 Zeichen).

Die anderen Lösungen sehen auf jeden Fall kürzer und besser aus. :) :)
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Marek06 hat geschrieben:Mit dem Attribut 'number' wollte ich sicher, dass ich z.B nicht festlege - immer 3 Großbuchstabe oder 3 Kleinbuchstaben oder 3 Zahlen - sondern das jedesmal variable erzeugt wird. Und mit der 2 Liste wollte ich sicher gehen, dass alle 7 Zeichen und nicht die Blöcke gemischt werden (außer das 1 Zeichen).
Die Intention hinter deinem Gedanken ist schon klar, du hast dir bei deiner Umsetzung nur nicht genügend Gedanken über die Folgen gemacht. Durch deinen Ansatz gehen nämlich unglaublich viele Kombinationen verloren, welche sonst möglich wären. Und damit werden deine Kennwörter viel leichter vorhersagbar.

Vielleicht einfach an einem Beispiel. Angenommen du hast zwei Mengen von Zeichen: die Menge N mit n verschiedenen Zeichen und die Menge M mit m verschiedenen Zeichen. Das Kennwort soll mindestens 5 Zeichen lang sein und mindestens eine Zeichen aus M und aus N enthalten. Wählt man die Verteilung bei dir, so könnte man einfach sagen: gut 3 Zeichen für n und zwei Zeichen für m oder umgekehrt. Damit hast du dann n³+m² + n²+m³ mögliche Kombinationen dabei vergisst du aber, dass noch n+m⁴, und n⁴+m möglich sind. Das sieht jetzt auf den ersten Blick nicht nach viel aus, aber in diesem Fall würdest du einfach mal einen riesigen Batzen an Möglichkeiten wegwerfen. Bereits bei relativ kleinen n und m werden n⁴ und m⁴ deutlich größer als n³+m² + n²+m³ und dominieren vollständig. D.h., du verlierst die überwiegenden Anteil an Kombinationen. Wenn jemand die Verteilung der Anzahlen kennt, dann ist es ein Leichtes die Kennwörter zu raten.
Das Leben ist wie ein Tennisball.
Antworten