Passwortgenerator selber schreiben von Grund auf

cola1

Mitglied
Hallo zusammen,

kennt Ihr eine Seite oder ein Projekt auf welcher näher erläutert wird wie man einen eigenen Passwortgenerator schreibt?
Habe den Tipp bekommen, dass mehrere Arrays wohl hilfreich wären (eines zum Start, eines zum Ende und eines für die möglichen Zeichen). Eine Art Parser.

Anschließend müsste sich eine Funktion selbst wieder aufrufen, um zu prüfen ob ein gültiger Eintrag vorhanden ist.
Hierbei kam die Rekursion zur Sprache und ein Beispiel mit A und B.

Also eine Funktion, welche per foreach und den Array-Werte solange prüft ob ein gültiger Wert vorhanden ist.
Dann die vorherigen Schleifen aufrufen um zu schauen, ob an einer anderen Position des Arrays? ein gültiger Wert vohanden ist.
Den Wert jedesmal mit übergeben und zum Schluss eine Zeichnfolge ausgeben.

Weiß leider nicht wo und wie ich anfangen soll. Habt Ihr einen Tipp?
 
Hi

*Ein Array mit gewünschter Länge
*Für jedes Arrayelement eine Zufallszahl zwischen 0 und (inklusive) 61 erzeugen
Für 0-9 die Ziffern '0' bis '9' ins Array, 10-35 sind 26 Stück Kleinbuchstaben, der Rest Großbuchstaben.
*Die einzelnen char´s zu einem String zusammenfügen und Ausgeben.
 
C++:
// Pseudocode

int asciiStart = 33;
int asciiEnd = 125;
int[] ignore = {34, 39, 44, 46, 59, 92, 94, 96};
char[] possibleChars = new char[asciiEnd-asciiStart - ignore.length];
for( int i = asciiStart; i < asciiEnd; i++ ){
  if( !in_array(i, ignore) )
    possibleChars[i-asciiStart] = (char)i;
}
int passwordLength = 10;
String password = "";
for( int i = 0; i < passwordLength; i++ ){
  password += possibleChars[random(0, possibleChars.length)];
}
 
Okay bin schon etwas weiter. Habe jedoch noch nicht wirklich mit Arrays gearbeitet.
Frage mich wie etwas an die Parser-Klasse übergeben werden KANN und was SOLL.
Verstehe den Sinn der ganzen Beispielaufgabe nicht wirklich :(

Folgender Code ist im Grunde schon das was Ihr gepostet hat, so passt es aber besser auf die Aufgabe (nicht online).

Aufgabe ist es: eine neue Hilfsfunktion, welche zwei Arrays übergeben bekommen soll mit einer bestimmten Länge und diese wieder ausgibt, sodass diese Arrays eine Stelle weniger haben (Speicher sparen).
Dies soll solange aufgerufen werden (Rekursion) bis eines der Arrays (string[] characters) bei der letzen Stelle ([0]) angekommen ist.
Jetzt können die einzelnen Indexe irgendwie irgendwo ausgegeben werden, sodass eine Zeichenfolge daraus entsteht...

C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PasswordGenerator
{
    class Generator
    {
        // Startwert(e) für characters 
        int[] start = new int[] { };
        // Endwert(e) für characters
        int[] end = new int[] { };
        string[] characters = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
                              "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
                              "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };

        // int start und int end legen den Bereich der validen character aus dem Array fest.
        public string[] validCharacters(int start, int end)
        {
            // Nur die Zeichen/Character ausgeben, welche im Bereich von start und end stehen.
            string[] retVal = new string[end - start + 1];
            // Start-Indexwert für retVal in der Schleife festlegen.
            int j = 0;

            // Speichert die character in retVal ab. 
            for (int i = start; i <= end; i++)
            {
                // retVal bekommt immer den Wert aus dem jeweiligen Schleifendurchgang zugewiesen.
                retVal[j] = characters[i];
                // Indexzähler erhöhen, um den nächsten character zu erhalten.
                j++;

                
            }
            return retVal;

            
        }

        public string[] parser(int[] start, int[] end, int characters)
        {
            foreach (string item in validCharacters(start[0], end[0]))
            {
                System.Console.WriteLine(item);
            }
            throw new NotImplementedException();
        }

        public Generator()
        {
        }
    }
}
 
Zuletzt bearbeitet von einem Moderator:
Der Sauberkeit halber sollte "characters" kein string Array sein sondern entweder ein char Array oder ein einzelner string.
Aufgabe ist es: eine neue Hilfsfunktion, welche zwei Arrays übergeben bekommen soll mit einer bestimmten Länge und diese wieder ausgibt, sodass diese Arrays eine Stelle weniger haben (Speicher sparen).
Dies soll solange aufgerufen werden (Rekursion) bis eines der Arrays (string[] characters) bei der letzen Stelle ([0]) angekommen ist.
Jetzt können die einzelnen Indexe irgendwie irgendwo ausgegeben werden, sodass eine Zeichenfolge daraus entsteht...
Ich versteh nur Bahnhof ehrlich gesagt.
Kannst du nicht die tatsächliche Aufgabe posten?
 
Ich versteh nur Bahnhof ehrlich gesagt.
Kannst du nicht die tatsächliche Aufgabe posten?
So gehts mir auch...

Zusätzlich zu der String/char-Sache noch Einiges:
*Warum gibts da eine unvermeidbare NotImplementedEx.?
*Eine Rekursion, um einzelne Arrayelemente durchzugehen? (Äh, Schleife...?)
*Sollen die int[] nicht auch char[] sein? Und warum werden Arrayinhalte als Indizes genommen?
...
Außerdem ist ein PW-Generator in keinster Weise ein Parser.
Ein Parser ist etwas, um Eingaben zu "verstehen".
zB. eine math. Formel mit Klammern, Wurzeln etc.etc., die als String/char-Array vorhanden ist,
math. verstehen, um das Ergebnis ermitteln können. Das wäre ein Parser.
 
Tagchen,

die Aufgabe wurde mündlich vermittelt, daher versuche ich es einfach nochmal :) :
Es geht darum C# näher kennen zu lernen und mit Arrays, Methoden usw. zu arbeiten. Zusätzlich mal die Rekursion kennen zu lernen.

Folgedes Hilfsmuster wurde gegeben:
IMAG0016.jpg

- Bei jeder Abzweigung soll eine foreach-Schleife angewandt werden, um zu prüfen welches Zeichen kommt.
- Wenn es nicht A ist natürlich das nächtst mögliche prüfen.
- dann soll der erste im Array gespeicherte Index per Array.Copy() gelöscht und die restlichen Indexe an ein neues Array übergeben werden.
- immer und immer wieder (Rekursion)
- wenn die Funktion am letzten Zeichen (index[0]) angekommen ist und das Zeichen hat, soll sich die Funktion wieder rückläufig "aufkapseln" und die Werte (die validen character) an ein Array übergeben um so eine Ausgabe eines Passwortes zu erzeugen.

Welche character valide sind soll durch ein int[] start-Array und ein int[] end-Array festgelegt werden.

Im grunde bin ich ziemlich überfordert damit. Habe noch nie mit Arrays gearbeitet.

Folgender Code entstand bisher in Zusammenarbeit:
C:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PasswordGenerator
{
    class Generator
    {
        // characters: Angabe aller für den Generator verfügbaren/validen Zeichen.
        string[] characters = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
                              "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
                              "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };

        /* validCharacters:
         * start und end legen den Bereich der validen character aus dem Array fest.
         */
        public string[] validCharacters(int start, int end)
        {
            // Nur die Zeichen/Character ausgeben, welche im Bereich von start und end stehen.
            string[] retVal = new string[end - start + 1];
            // Start-Indexwert für retVal in der Schleife festlegen.
            int j = 0;

            // Speichert die character in retVal ab. 
            for (int i = start; i <= end; i++)
            {
                // retVal bekommt immer den Wert aus dem jeweiligen Schleifendurchgang zugewiesen.
                retVal[j] = characters[i];
                // Indexzähler erhöhen, um den nächsten Index zu füllen.
                j++;
            }
            return retVal;
        }

        // Kommentar fehlt...
        public string[] Parser(int[] start, int[] end, int characters)
        {
            foreach (string item in validCharacters(start[0], end[0]))
            {
                System.Console.WriteLine(item);
            }
            throw new NotImplementedException();
        }

        /* Copy<T>: Hilfsfunktion um pro rekursivem Schleifendurchlauf den ersten Index des
         * input-Arrays zu "entfernen" und die restlichen Indexe in das retVal-Array zu übergeben.
         * 
         * Generic T: Bei Funktionsaufruf per Copy<T>(x) wird zur Compiler-Zeit der Generic durch den
         * gewählten (x = String/Int/...) ersetzt.
         */
        public T[] Copy<T>(T[] input)
        {
            T[] retVal = new T[0];

            /* Array.Copy(Array mit den Daten,
             *              ab welchem Index kopiert wird,
             *              Empfangs-Array,
             *              ab welchem Index gespeichert wird,
             *              Anzahl der zu kopierende Indexe);
             */
            // TODO: GetUpperBound(); ?
            Array.Copy(input, 1, retVal, 0, input.Length - 1);

            return retVal;
        }

        public Generator()
        {
        }
    }
}
 
Mir ist immer noch nicht klar, was jetzt eigentlich das Ziel der Aufgabe ist. Einen Passwortgenerator zu schreiben, der mindestens an einer Stelle im Code eine rekursive Funktion verwendet?

Das Hilfsmuster hilft mir gar nicht. Was soll auf welche Eigenschaft hin überprüft werden? Was sind A und B?

Zu deinem Code: was soll die Parser-Methode machen?
 
Neue Erkenntnis.
Es geht nicht darum ein Passwort zu generieren, sondern ein Passwort zu hacken!
Die Rekursion durch die Parser-Methode soll alle möglichen Zeichen per validCharacters() prüfen, per Copy() den ersten Index aufgrund des begrenzten Speichers löschen und beim letzten Zeichen der Rekursion die gespeicherten Werte ausgeben.

Das kommt davon, wenn sich Person X eine Aufgabe ausdenkt und Person Y die Aufgabe per stille Post übermittelt. Entschuldigung.

Parser soll sich selbst solange aufrufen, bis der character-Index nurnoch 1 beträgt. Ab diesem Punkt gehen wir die Rekursion zurück und geben jeweils die Werte aus. Vielleicht schaffe ich es heute. Finde es auch eine harte Übungsaufgabe...

Kann nicht wirklich weiter schreiben, weil ich den Ablauf nicht verstehen und nicht weiß an welche Stelle was wann übergeben wird :O

Die Range von den Arrays start und end bzw. 4 bis 8 dient dazu die Aufgaben auf mehrere Threads aufzuteilen. Das wird wohl die nächste Aufgabe.


Neuster Code:

Generator.cs
C:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PasswordGenerator
{
    class Generator
    {
        // characters: Angabe aller für den Generator verfügbaren/validen Zeichen.
        string[] characters = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
                              "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
                              "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };

        /* 
         * validCharacters:
         * start und end legen den Bereich der validen character aus dem Array fest.
         */
        public string[] validCharacters(int start, int end)
        {
            // Nur die Zeichen/Character ausgeben, welche im Bereich von start und end stehen.
            string[] retVal = new string[end - start + 1];
            // Start-Indexwert für retVal in der Schleife festlegen.
            int j = 0;

            // Speichert die character in retVal ab. 
            for (int i = start; i <= end; i++)
            {
                // retVal bekommt immer den Wert aus dem jeweiligen Schleifendurchgang zugewiesen.
                retVal[j] = characters[i];
                // Indexzähler erhöhen, um den nächsten Index zu füllen.
                j++;
            }
            return retVal;
        }

        #region Parser 1
        /* 
         * Parser 1:
         * Läuft solange durch bis nurnoch 1 Index in characters vorhanden ist.
         * Dann wird das Ergebnis aus Parser 2 verarbeitet und dank Rekursion
         * das nächste Ergebnis (rückwirkend) vorne angehängt. Z.B.:
         * Durchlauf 1 = a
         * Durchlauf 2 = B
         * Ergebnis    = Ba
         */
        public string[] Parser1(int[] start, int[] end, int characters)  
        {
            // Array deklarieren, Funktion Copy aufrufen und den Wert übergeben.
            int[] start2 = Copy<int>(start);
            int[] end2 = Copy<int>(end);

            if(characters == 1)
            {
                foreach (string item in validCharacters(start[0], end[0]))
                {
                    // in dieser Schleife neu aufrufen

                    Console.Write(item);
                }
                throw new NotImplementedException();
            }
            throw new NotImplementedException();
        }
        #endregion

        #region Parser 2
        /* 
         * Parser:
         * Gibt die Chars einer Liste für Parser1 aus.
         */
        public string[] Parser2(int[] start, int[] end, int characters)
        {
            // Array deklarieren, Funktion Copy aufrufen und den Wert übergeben.
            int[] start2 = Copy<int>(start);
            int[] end2 = Copy<int>(end);

            if (characters == 1)
            {
                foreach (string item in validCharacters(start[0], end[0]))
                {
                    // in dieser Schleife neu aufrufen

                    Console.Write(item);
                }
                throw new NotImplementedException();
            }
            throw new NotImplementedException();
        }
        #endregion

        /* 
         * Copy<T>:
         * Hilfsfunktion um pro rekursivem Schleifendurchlauf den ersten Index des
         * input-Arrays zu "entfernen" und die restlichen Indexe in das retVal-Array zu übergeben.
         * 
         * Generic T:
         * Bei Funktionsaufruf per Copy<T>(x) wird zur Compiler-Zeit der Generic durch den
         * gewählten (x = String/Int/...) ersetzt.
         */
        public T[] Copy<T>(T[] input)
        {
            T[] retVal = new T[0];

            /* Array.Copy(Array mit den Daten,
             *              ab welchem Index kopiert wird,
             *              Empfangs-Array,
             *              ab welchem Index gespeichert wird,
             *              Anzahl der zu kopierende Indexe);
             */
            // TODO: GetUpperBound(); ?
            Array.Copy(input, 1, retVal, 0, input.Length - 1);

            return retVal;
        }

        public Generator()
        {
        }
    }
}

Progam.cs
C:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PasswordGenerator
{
    class Program
    {
        static void Main(string[] args)
        {
            Generator instanceGenerator = new Generator();
            int[] start = new int[] { 4, 5 };
            int[] end = new int[] { 8, 9 };
            string[] result = instanceGenerator.Parser1(start, end, 2);
            Console.WriteLine(result);
            Console.ReadLine();
        }
    }
}
 
Zuletzt bearbeitet:
Aaaha.

Ich verstehe, dein Programm soll einfach alle Passwortmöglichkeiten durchprobieren,
bis es das Richtige erwischt.

*Das ist noch immer kein Parser. Also bitte, nenn das nicht Parser.

*Woran das Ganze zurzeit nur scheitern kann:
Irgendwo muss auch das richtige Passwort herkommen, damit man vergleichen kann.
Wo ist es?

*Noch ein Konzeptproblem: Du hast vergessen, dass Passwörter verschieden lang sein können.
Zum Durchprobieren zuerst alle 1-Zeichen-PWs nehmen.
Wenn da nichts dabei war, alle 2-Zeichen-PWs. Usw.

*Lass die Thread vorerst mal, bis sonst alles funktioniert.
Du verwirrst dich und uns sonst nur noch mehr :)

*Und die Sache mit dem Copy ist totaler Unsinn.
So, wie du es beschreibst/ich es verstanden habe (der Code ist anders)
veringerst du den Speicherverbrauch nicht, sondern treibst ihn zur Summe 1...n
Für ein 10-Zeichen-PW brauchst du dann nicht 10 chars, sondern 55.
Ganz toll :sarkastisch:

*Nimm doch endlich die Exceptions raus.
Falls der Code nicht komplett von dir ist: Besser löschen,
sonst verstehst du da in absehbarer Zeit nicht viel.

PS: Ach ja, die Punkte von oben sind mir noch immer nicht klar.
 
Zurück