Eingabe überprüfen



  • Hallo,

    Ich will ein Programm schreiben welches die Eingabe auf Mindestanforderung überprüft, sprich die Eingabe soll:
    -mindestens 8 Zeichen lang sein
    -Zeichen von 'a' bis 'z', 'A' bis 'Z' und Sonderzeichen wie '!' und '?' enthalten
    - Groß und Kleinbuchstaben enthalten.

    Bitte um Lösungsansätze. Vielen Dank im voraus.

    Schönen Abend



  • Dieser Thread wurde von Moderator/in Arcoth aus dem Forum C++ (alle ISO-Standards) in das Forum Rund um die Programmierung verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • if(end-begin<8) return false;
    if(!find_if(begin,end,islower)) return false;
    if(!find_if(begin,end,isupper)) return false;
    if(!find_if(begin,end,isgraph)) return false;
    return true;
    

  • Mod

    Ich hasse Leute, die mir Vorgaben über Passwörter machen.



  • Danke für die antworten. Jedoch sieht das schon ziemlich professionell aus.
    Ich würde das gerne in dem Programmierstil wie unten aufgeführt.
    Ebenfalls ohne einen String.

    Ich habe die einzelnen Forderungen in Funktionen unterteilt, jedoch habe ich mein Problem mit der Umsetzung.

    void GrosKlein()
    {
    }
    
    void Zeichen()
    {
    }
    void Laenge()
    {
    	char Passwort[8] = {};
    	char a = '\0';
    
    	for (int i = 0; i < 8; i++)
    	{
    		if ( ) //<- Wie stelle ich am besten die Bedingung auf?
    		{
    
    			cout << " Passwortanforderung nicht erfuellt! " << endl;
    
    		}
    		else
    		{
    				cout << "Passwort korrekt" << endl;
    
    		}
    	}
    }
    

    Wie kriege ich das am besten programmiert?



  • hä. Was willstn du jetzt? Den als Hausi gestellten Frame damit ausfüllen?


  • Mod

    hardware schrieb:

    hä. Was willstn du jetzt? Den als Hausi gestellten Frame damit ausfüllen?

    Was denn sonst?

    Wobei die Antwort hier einfach ist: Da das Passwort höchstens 7 Zeichen hat, ist die Antwort automatisch immer false. Problem gelöst.



  • Wäre für Lösungsansätze dankbar



  • SeppJ schrieb:

    Ich hasse Leute, die mir Vorgaben über Passwörter machen.

    Geht mir auch so.

    Also mindestens

    bool hasLower=false;
    bool hasUpper=false;
    bool hasDigit=false;
    bool hasGraph7=false;//!"#$%&'()*+,-./:;<=>?@[]^_`{|}~
    bool hasOther=false;//mal nur äöüÄÖÜß //supi gegen rainbowtables
    for(auto ch:password){
    	if(islower(ch)) 
    		hasLower=true;
    	else if(isupper(ch)) 
    		hasUpper=true;
    	else if(isdigit(ch)) 
    		hasDigit=true;
    	else if(isgraph(ch) and (0<=ch && ch<=127))
    		hasGraph7=true;
    	else 
    		hasOther=true;
    }
    double bitsPerChar=0;
    if(hasUpper) bitsPerChar+=log2(26);
    if(hasLower) bitsPerChar+=log2(26);
    if(hasDigit) bitsPerChar+=log2(10);
    if(hasGraph7) bitsPerChar+=log2(32);
    if(hasOther) bitsPerChar+=log2(5);
    return password.size()*bitsPerChar>=47;
    

    So, nu kann ich weiter meine 16-stelligen kleinbuchstabigen Passwörter benutzen. Mit 75Bits bin ich ja sowas von über den Mindestanforderungen…

    Schade, daß Admins sich nie mit Rechnern auskennen.



  • Creed schrieb:

    Danke für die antworten. Jedoch sieht das schon ziemlich professionell aus.

    Du willst SeppJ und mich ärgern, weil diese Passwortmindestanforderungen aus den 80-er Jahren professionell aussehen? 👎

    Creed schrieb:

    Ich würde das gerne in dem Programmierstil wie unten aufgeführt.

    Stil und Plan nicht erkennbar.

    Creed schrieb:

    Wie kriege ich das am besten programmiert?

    Wie immer.
    Buch macht kluch, zum Bleistift Der C++-Programmierer | ISBN: 3446443460



  • Ich habe mein Programm überarbeitet. Mein Problem liegt nun darin das ich nicht aus der while Schleife in der main raus komme.
    Es wird jedesmal " Passwort erfullt die Bedingung" nicht ausgegeben.

    /*
    Name: Passwortprüfer
    Beschreibung: Erstelle ein Programm, welches ein eingegebenes Passwort auf folgende Mindestanforderungen prüft:
    • Länge >= 8 Zeichen
    • Erlaubte Zeichen: 'a' bis 'z', 'A' bis 'Z', '!', '?', '#', '<', '>', '/', '%', '(', ')', '[', ']'
    • enthält Groß- und Kleinbuchstaben sowie Sonderzeichen
    */
    #include<iostream>
    using namespace std;
    
    bool Eingabe(char* Passwort);
    bool GrosKlein(char*Passwort);
    bool Laenge(char*Passwort);
    
    int main()
    {
    	const int Anzahl = 8;
    	char Passwort[Anzahl] = {};
    
    	cout << "Bitte geben Sie ihr Passwort ein: " << endl;
    
    	while (Eingabe(Passwort) == false)
    	{
    		cout << "Passwort lautet " << Passwort << endl;
    		cout << "Passwortanforderung nicht erfuellt! Bitte Eingabe wiederholen! " << endl;
    	}
    	cout << " Passwortanforderung erfuellt! " << endl;
    
    	system("pause");
    	return 0;
    }
    bool Eingabe(char*Passwort)
    {
    	if (Laenge(Passwort) == true && GrosKlein(Passwort) == true)
    	{
    		cout << "Eingabe ist in ordnung" << endl;
    		return true;
    	}
    	else
    	{
    
    		return false;
    	}
    }
    bool Laenge(char *Passwort)
    {
    	bool kurz = false;
    	cin >> Passwort;
    	int counter = 0;
    	for (int i = 0; i < 8; i++)
    	{
    		if (Passwort[i] == 0)
    		{
    			kurz = true;
    			counter++;
    		}
    	}
    	if (counter == 0)
    	{
    		kurz = false;
    	}
    
    	if (kurz == false)
    	{
    		cout << "Laenge ist in ordnung" << endl;
    		return true;
    	}
    	else
    	{
    		cout << "Passwort ist zu kurz" << endl;
    		return false;
    	}
    }
    
    //• enthält Groß - und Kleinbuchstaben sowie Sonderzeichen
    bool GrosKlein(char*Passwort)
    {
    	bool counterKleinzeichen = false;
    	bool counterGroszeichen = false;
    	bool counterSonderzeichen = false;
    	bool zahl;
    	int counter = 0;
    	for (int i = 0; i < 8; i++)
    	{
    		if (Passwort[i] >= 'a' && Passwort[i] <= 'z')
    		{
    			counterKleinzeichen = true;
    			cout << "counterKleinzeichen == true" << endl;
    
    		}
    		if (Passwort[i] >= 'A' && Passwort[i] <= 'Z')
    		{
    			counterGroszeichen = true;
    			cout << "counterGroszeichen == true" << endl;
    		}
    		if (Passwort[i] == '!' || Passwort[i] == '?' || Passwort[i] == '#' || Passwort[i] == '<' ||
    			Passwort[i] == '>' || Passwort[i] == '/' || Passwort[i] == '%' || Passwort[i] == '(' ||
    			Passwort[i] == ')' || Passwort[i] == '[' || Passwort[i] == ']')
    		{
    			counterSonderzeichen = true;
    			cout << "counterSonderzeichen == true" << endl;
    		}
    		if (Passwort[i] >= '0' && Passwort[i] < '9'){
    			zahl = true;
    			cout << "Zahl eingegeben!!!" << endl;
    		}
    		if (counterKleinzeichen == true && counterGroszeichen == true && counterSonderzeichen == true && zahl == false)
    		{
    			cout << "GroßKlein und Sonderz sind in ordnung" << endl;
    			return true;
    		}
    		else
    		{
    			cout << "Passwort enthält kein Gros-/Klein oder Sonderzeichen! " << endl;
    			return false;
    		}
    	}
    }
    


  • Der Code ist leider ganz grosser Murks.
    Das kannst du auch selbst einfach daran erkennen, wenn du mal versuchst mit ganz normalen deutschen Sätzen zu erklären was die einzelnen Funktionen machen. Am besten indem du sie Statement für Statement durchgehst und dir anguckst was der Code wirklich macht. NICHT indem du einfach sagst was du willst dass er macht.



  • Creed schrieb:

    Es wird jedesmal " Passwort erfullt die Bedingung" nicht ausgegeben.

    /*
    • Länge >= 8 Zeichen
    */
    
    	const int Anzahl = 8;
    	char Passwort[Anzahl] = {};
    
    }
    

    Das kann nicht funktionieren. Du willst ein Paßwort der Länge >= 8, hast aber nur Platz für 7 Zeichen. Warum nimmst du eigentlich nicht std::string?



  • String darf ich leider nicht nutzen.

    Wie sag ich dem Compiler das er mindestens 8 Zeichen haben muss mit einem array ?
    und was genau ist den großer Murks ?
    Wie hätten Sie es denn besser gemacht ?



  • Hi,

    Zeichenketten bestehen in C/C++ immer aus der Zeichenkette und einem angehängten /0 als Endekennung. Du brauchst also mindestens 9 Zeichen Platz für 8 Zeichen.

    Gruß Mümmel



  • Creed schrieb:

    Wie sag ich dem Compiler das er mindestens 8 Zeichen haben muss mit einem array ?

    Dein Array hat schon Platz für 8 Zeichen. Du brauchst aber Platz für 9, weil immer ein sog. Null-Terminator ("/0" - siehe Beitrag von muemmel) angehängt wird. Bloss wenn du ein Array mit 9 Zeichen machst, dann kann der User trotzdem 10 eingeben. Oder 11 oder 10000. Weswegen das Einlesen über cin >> array auch so problematisch ist.

    string wäre optimal, aber wenn du den nicht verwenden darfst, dann kannst du immer noch istream::getline() verwenden:
    http://www.cplusplus.com/reference/istream/istream/getline/
    Dabei kannst du angeben wie viel Platz im Array ist, ala

    char Passwort[9] = {};
        if (!cin.getline(Passwort, 9))
        {
            // TODO: Eingabefehler. Gehört irgendwie behandelt, z.B. Fehlermeldung ausgeben und Programm beenden.
        }
    

    Creed schrieb:

    und was genau ist den großer Murks ?

    Alles, der ganze Code. Funktioniert doch hinten und vorne nicht, du brauchst ihn doch bloss auszuprobieren.
    Beispielsweise die Funktion GrosKlein ... da fehlt ein return nach der Schleife. Falls du dafür von deinem Compiler keine Warning bekommen hast, dann liegt das vermutlich am nächsten Bug:
    Das if

    if (counterKleinzeichen == true && counterGroszeichen == true && counterSonderzeichen == true && zahl == false)
            {
                cout << "GroßKlein und Sonderz sind in ordnung" << endl;
                return true;
            }
            else
            {
                cout << "Passwort enthält kein Gros-/Klein oder Sonderzeichen! " << endl;
                return false;
            }
    

    steht IN der Schleife. Es wird also im ersten Durchlauf ausgeführt. Entweder der if oder halt der else Zweig. In beiden ist ein return enthalten. D.h. die Funktion wird auf jeden Fall im ersten Schleifendurchlauf verlassen. Die Schleife ist also so wie sie jetzt ist für genau nix.

    Creed schrieb:

    Wie hätten Sie es denn besser gemacht ?

    Netter Versuch.



  • @volkard
    worüber muss ich da nachlesen, um das bitsPerChar Zeug zu kapieren? Also ich glaube zu verstehen dass es mit dem Aufwand zu tun hat das Passwort mit verschiedenen Methoden zu knacken, aber so ganz im Detail ists mir nicht klar.


  • Mod

    HarteWare schrieb:

    @volkard
    worüber muss ich da nachlesen, um das bitsPerChar Zeug zu kapieren? Also ich glaube zu verstehen dass es mit dem Aufwand zu tun hat das Passwort mit verschiedenen Methoden zu knacken, aber so ganz im Detail ists mir nicht klar.

    Information. Um X verschiedene Zustände in der Basis Y darzustellen, braucht man log_Y(X) Ziffern. Um also 26 Buchstaben im Zweiersystem darzustellen, braucht man log_2(26)=4.7 binäre Ziffern (binary digit = bit). Man kann daher sagen, dass ein Buchstabe aus einer Menge von 26 eine Information von 4.7 Bit enthält.



  • HarteWare schrieb:

    @volkard
    worüber muss ich da nachlesen, um das bitsPerChar Zeug zu kapieren? Also ich glaube zu verstehen dass es mit dem Aufwand zu tun hat das Passwort mit verschiedenen Methoden zu knacken, aber so ganz im Detail ists mir nicht klar.

    Der Code ist mir so ganz im Detail auch nicht klar. Und die anderen haben weggeschaut, weil er irgendwie richtig aussah. In Wirklichkeit ist er total falsch und den kannste so lange angucken, wie Du willst, er wird Dir widersprücklichen Blödsinn erzählen.

    Die Grundidee ist, daß es für von Passwörtern der Lange 3 mit nur Kleinbuchstaben 17576 Stück == 26*26*26 == pow(26,3) (es gibt 26 Buchstaben im Alphabet). Passwörter mit Klein- und Großbuchstaben und Ziffern der Lange 8, davon gibt es 457163239653376 Stück == pow(62,8).

    Das würde dann folgenden Code ergeben

    double alphabetSize=0;
    if(hasUpper) alphabetSize+=26;
    if(hasLower) alphabetSize+=26;
    if(hasDigit) alphabetSize+=10;
    if(hasGraph7) alphabetSize+=32;
    if(hasOther) alphabetSize+=5;
    return pow(alphabetSize,password.size())>=pow(62,8);
    

    Und dann tun die Profis das immer als Logarithmen darstellen.
    Logarithmengesetze.
    Statt if(x>=26*26*26) kann ich auch lf(log(x)>=log(26)+log(26)+log(26)) schreiben. Bzw statt if(x>=pow(26,3)) auch if(log(x)>=log(26)*3). Aus * in der normalen Werlt wird + in der logarithmischen Welt. Aus pow wird *. Aus 1 wird 0.
    Aber aufgepaßt: Aus 0 wird minus unendlich.
    Aus + wird {geht nicht}.

    Entsprechend ist mein Code vollkommen kaputt. DORT hätte ich die Logarithmen niemals addieren dürfen, weil das eine Multiplikation in der echten Welt darstellt.

    volkard schrieb:

    double bitsPerChar=0;//minus undendlich
    if(hasUpper) bitsPerChar+=log2(26);//geht nicht
    if(hasLower) bitsPerChar+=log2(26);//geht nicht
    if(hasDigit) bitsPerChar+=log2(10);//geht nicht
    if(hasGraph7) bitsPerChar+=log2(32);//geht nicht
    if(hasOther) bitsPerChar+=log2(5);//geht nicht
    return password.size()*bitsPerChar>=47;
    

    Die Logarrithmen haben den Riesenvorteil, daß die Rechnung nicht überläuft und daß man leicht in Worten sagen kann, wie groß die Zahl ungefähr ist.
    3 klein: 17576
    8 groskleinziffer: 457163239653376
    8 groskleingraph7: 2478758911082496
    12 klein: 95428956661682176
    16 klein: 43608742899428874059776
    Die Zahlen sind ja voll doof zu vergleichen, die Wertebereiche liegen zu weit auseinander.

    Ich stecke sie alle in die log-Funktion (zur Basis 10, die gibt aus, wieviele Ziffern eine Zahl hat):
    3 klein: 4.2
    8 groskleinziffer: 14,7
    8 groskleingraph7: 15,3
    12 klein: 17
    16 klein: 22,6
    Das ist doch mal übersichtlich.

    Und nimmt man nicht den log10, der die Anzahl der Dezimalziffern findet, sondern den log2, dann hat man die Anzahl der Bits.



  • volkard schrieb:

    double bitsPerChar=0;//minus undendlich
    

    Ne, das ist log(1)=0. Also kein Problem.


Log in to reply