# Java - Fehler in meinem Code...nur wo?



## Bullet1990 (27. März 2010)

Hi Leute, seit gestern sitze ich an einer Programmaufgabe, in der es gilt ein Passwort, das als char-Array gegeben werden soll, auf seine Sicherheit zu testen. Laut Aufgabe soll es: Mindestens 8 Zeichen lang sein, 2 Buchstaben haben, zwei Ziffern haben,  einen Großbuchstaben und einen Kleinbuchstaben enthalten und ein Sonderzeichen.


```
public class Passwort {

	 static int buchstabenanzahl = 0;                                                         //Wert der dann die Anzahl der Buchstaben
	 								                                                  //zählen soll also Groß- und Kleinbuchstaben
	
	public static boolean Sonderzeichen (char[] pw){               //Schaut nach ob Array ein Sonderzeichen enthält
		char[] sonderzeichen = {'!', '"', '§', '$', '%', '&', '(', ')', 
				'=', '?', '`', '´', '\\', '}', ']', '[', '{', '*', '+',
				'~', '\'', '#', '-', '_', '.', ':', ',', ';', '<', '>',
				'|', '°', '^', '@', '€'};                                                       //Char-Array, das alle Sonderzeichen enthält
		String checkstring = new String(pw);                                  //das  Array konvertiere ich nochmal als String um
		boolean zeichen = false;                                                       //setze meinen Ergebniswert auf false
		for (int i=0;i<sonderzeichen.length;i++){                            //hier durchläuft er halt das Array
			if (checkstring.indexOf(sonderzeichen[i])>-1){         //und hier soll er alle Elemente durchsuchen
				                                                                                  //und gucken, ob ein Sonderzeichen enthalten sind.
				zeichen=true;                                      //Wenn also mindestens ein Sonderzeichen drin is soll er mir true liefern
			}                               //mir ist da grad was eingefallen müsste ich eigentlich nochmal abfragen ob der wert da oben 
			                                                                                        //auch wirklich größer -1 ist?
		}return zeichen;}                                           //wenn das Passwort also ein Sonderzeichen enthält soll mir das true liefern
		
	public static boolean Mindestlänge (char[] pw){                                //Hier wird halt gecheckt, ob mein
		boolean langgenug = false;                                                          //Array mindestens 8 Zeichen lang ist
		if (pw.length>=8){
			langgenug = true;}
		return langgenug;}
	
	public static boolean Großbuchstaben(char[] pw){                      //Ähnlich wie bei den Sonderzeichen, soll hier
		char[] großbuchstaben = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',         //nach Großbuchstaben durchsucht werden. 
				'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
				'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'Ä', 'Ü', 'Ö'};
		String checkstring = new String(pw);
		boolean uppercase = false;
		for (int i=0;i<großbuchstaben.length;i++){
			if (checkstring.indexOf(großbuchstaben[i])>-1){
				uppercase=true;
				buchstabenanzahl +=1;                                         // hier rechne ich auf "buchstabenanzahl" eins drauf, da ich ja 
				                                                                                   //mindestens 2 Buchstaben brauche, ich kann ja 
                                                                                                                   //auch einen Groß- und einen Kleinbuchstaben
	}}return uppercase;                                                                        // haben.

	}
	
	public static boolean Kleinbuchstaben(char[] pw){                                      //Hier das gleiche wie oben, nur halt
		char[] kleinbuchstaben = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',                             //mit Kleinbuchstaben
				'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
				't', 'u', 'v', 'w', 'x', 'y', 'z', 'ä', 'ö', 'ü', 'ß'};
		String checkstring = new String(pw);
		boolean lowercase = false;
		for (int i=0;i<kleinbuchstaben.length;i++){
			if (checkstring.indexOf(kleinbuchstaben[i])>-1){
				lowercase=true;
				buchstabenanzahl +=1;
			}}return lowercase;
			}
	
	public static boolean ZweiZiffern(char[] pw){                            //Hier dursucht er das Array ob 
		int anzahl = 0;//Ziffern enthalten sind
		char[] ziffern = {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0'};
		String checkstring = new String(pw);
		boolean zahlen = false;
		for(int i=0;i<ziffern.length;i++){
			if(checkstring.indexOf(ziffern[i])>-1){
				anzahl+=1;                                                                //hier ist es etwas anders falls eine Zahl enthalten ist,
				                                                                                   //zählt er einen int Wert anzahl +1
				if(anzahl>1){                                                            //wenn er also mehr als 2 Ziffern hat erst dann
					zahlen = true;                                                  //soll der Wert true liefern.
				}
			}
		
		}
		return zahlen;
	}
		
	public static boolean ZweiBuchstaben(char[] pw){                //Hier kommt die Variabel buchstabenzahl
		boolean buchstaben = false;                                            //ins Spiel. ich hatte es so gedacht, dass bei Großbuchstaben()
		if (buchstabenanzahl>1){                      //und Kleinbuchstaben(), der Wert von buchstabenanzahl überschrieben wurde,
			buchstaben = true;                       //je nachdem wie viele Buchstaben enthalten sind. Hier soll true zurück gegeben
		}return buchstaben;                                          //werden, wenn die buchstaben anzahl mehr als 1 ist, also mindestens 2.
	}
	
	
	public static void main (String...args){                                               //Hier will ich das ganze nun testen.
		char[] pw = {'A', 'x', 'B', '1', '&', 'a', '8', 'c'};                                         //das ist mein Beispiel char-Array, also mein Passwort
															    //das Passwort ist eigentlich ein perfekt gewähltes, es
                                                                                                                            // erfüllt also die Kriterien
		if(ZweiBuchstaben(pw)==true&&ZweiZiffern(pw)==true&&                       //die ganze Anweisung hier soll mir den Text
                                                                                                                                               //  "Ein gut gewähltes Passwort!"
 	Kleinbuchstaben(pw)==true&&Großbuchstaben(pw)==true&&                 //ausgeben, wenn jeder
                                                                                                                                       // der Methoden oben, true Ergeben und somit alle 
				Mindestlänge(pw)==true&&Sonderzeichen(pw)==true){      //Bedingungen für ein gutes Passwort erfüllt sind
			System.out.println("Ein gut gewähltes Passwort!");
		}else{System.out.println("Das Passwort ist sch***e!");}          //Wenn eine Bedingung nicht zutreffen sollte soll er mir 
                                                                                                                          //ausgeben, dass mein
		                                                                                                         //Passwort e ist
		
	}
	
	}
```

Mein Problem ist, dass mein Code gemein zu mir ist und mir sagt, dass mein Code "sch***e" ist. 
Wobei das Passwort eigentlich ein gut gewähltes ist, und die Kriterien erfüllt. Das muss bedeuten ich hab irgendwo einen Fehler drin, da oben. Ich finde ihn aber nicht...Kann mir einer von euch da weiterhelfen? Hab ich da irgendwo einen Denkfehler drin?

Danke schonmal im Voraus.

MfG
Bullet


----------



## Kai008 (27. März 2010)

Ich habe mir den Rückgabewert jeder Methode ausgegeben, die, die false zurückgibt expandet und hatte auf einem Blick dem Fehler.
Versuchs mal.

btw. Groß/Klein/Zahlen ist egal, wenn ein Sonderzeichen verlangt wird. Jemand der auf Sonderzeichen testet wird sicher alle anderen einbeziehen, da er ja nicht weiß welche Zeichen darin vorkommen.


----------



## Bullet1990 (27. März 2010)

also ich hab mir den rückgabe wert von ZweiBuchstaben() geben lassen und der war false, liegts daran? das heißt der Wert für buchstabenanzahl wird nich wie gewollt überschrieben.
Und zu den Sonderzeichen etc. So war das in der Aufgabenstellung gefordert, dewegen mache ich das so.

Gute Passwörter sollten so aufgebaut sein, dass nicht leicht durch massives Ausprobieren aufgrund von Wörterbüchern und Zahlenfolgen erraten werden können.

Ein gutes Passwort sollte zum Beispiel mindestens

    * acht Zeichen,
    * zwei Buchstaben,
    * zwei Ziffern,
    * ein Gross- und ein Kleinbuchstabe,
    * ein Sonderzeichen enthalten und
    * mindestens eine Ziffer oder Sonderzeichen, soll sich innerhalb des Passwortes befinden.

"AxB1&a8c" erfüllt zum Beispiel diese Kriterien, "1passw0rt" aber nicht (kein Sonderzeichen und kein Grossbuchstabe).

Implementieren Sie eine Java-Klasse "PasswortChecker" mit einer Java-Methode, die überprüft, ob ein Passwort obige Kriterien erfüllt oder nicht. Das Passwort soll dabei als char-Feld gegeben sein.

Ein Sonderzeichen soll einfach ein Zeichen sein, dass keine Ziffer und kein Unicode-Buchstabe ist. Verwenden Sie die Klasse Character, um einzelne Zeichen zu überprüfen. 

Das war die Aufgabenstellung ich denke schon, dass ich für jedes einzelne ne Methode schreiben sollte.


----------



## Kai008 (27. März 2010)

Ja, buchstabenanzahl ist bei dem Methodenaufruf immer 0, weil ja vorher nix reingeschrieben wird.
Hab ich schon verstanden, wollte ich nur erwähnen. Gibt wohl kaum jemanden, der noch nie versucht hat nen kleinen MD5 zu bruten. ^^


----------



## Bullet1990 (27. März 2010)

OK hab mir jetzt die Lösung angesehen und die is viel einfacher , als ich es gemacht hatte und zwar:

http://www.home.hs-karlsruhe.de/~pa.../aufgaben/felder/PasswortChecker.html#line.12

Ich denk mir die Aufgabenstellungen immer komplizierter als sie sind


----------



## Kai008 (27. März 2010)

Das kommt noch.
Schreibe es aber auf jedem Fall selbst, sonst wirst du später kaum noch mitkommen (denke ich, hatte nie ne Ausbildung im eigendlichen Sinn).


```
public class Passwort
{
	private static char[] UPPER_LETTER = {
		'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',
	};
	private static char[] LOWER_LETTER = {
		'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'
	};
	private static char[] NUMERIC = {
		'1', '2', '3', '4', '5', '6', '7', '8', '9', '0'
	};

	private static final char[] SYMBOLIC = {
		'!', '"', '§', '$', '%', '&', '(', ')', '=', '?', '`', '´', '\\', '}', ']', '[', '{', '*', '+', '~', '\'',
		'#', '-', '_', '.', ':', ',', ';', '<', '>', '|', '°', '^', '@', '€', 'Ä', 'Ü', 'Ö',  'ä', 'ö', 'ü', 'ß'
	};
	 		
	public static void main (String[] args) {
		char[] pw = {'A', 'x', 'B', '1', '&', 'a', '8', 'c'};
		String password = String.valueOf(pw);
		
		if(containTwoLetters(password) && containToNumerics(password) && containALowerLetter(password) &&
				containAUpperAlpha(password) && lenghtEnough(password) && containASymbolic(password)) {
			System.out.println("Ein gut gewähltes Passwort!");
		}
		else {
			System.out.println("Nicht so gutes Passwort!"); //Keine Beleidigungen in Programmen.
		}
	}
	private static boolean containTwoLetters(String password) {
		boolean result = false;
		if(UPPER_LETTER.length != LOWER_LETTER.length)
			throw new IllegalArgumentException();
		for(byte b = 0, letterCounter = 0; b < UPPER_LETTER.length && !result; b++)
		{
			char upperLetter = UPPER_LETTER[b];
			char lowerLetter = LOWER_LETTER[b];
			
			if(password.indexOf(upperLetter) != -1 || password.indexOf(lowerLetter) != -1)
				letterCounter++;
			if(letterCounter >= 2)
				result = true;
		}
		return(result);
	}
	private static boolean containToNumerics(String password) {
		boolean result = false;
		for(byte b = 0, numbersFound = 0; b < NUMERIC.length && !result; b++){
			if(password.indexOf(NUMERIC[b]) != -1){
				numbersFound++;
				
				if(numbersFound == 2) {
					result = true;
				}
			}
		}
		return(result);
	}
	private static boolean containALowerLetter(String password) {
		boolean result = false;
		
		for(byte b = 0; b < LOWER_LETTER.length && !result; b++){
			if (password.indexOf(LOWER_LETTER[b]) != -1) {
				result = true;
			}
		}
		return(result);
	}
	private static boolean containAUpperAlpha(String password) {
		boolean result = false;
		for(int i = 0; i < UPPER_LETTER.length && !result; i++) {
			if(password.indexOf(UPPER_LETTER[i]) != -1) {
				result = true;
			}
		}
		return(result);
	}
	private static boolean lenghtEnough(String password) {
		return(password.length() >= 8);
	}
	private static boolean containASymbolic(String password) {
		boolean result = false;
		for(int i = 0; i < SYMBOLIC.length && !result; i++) {
			if(password.indexOf(SYMBOLIC[i]) != -1) {
				result = true;
			}
		}
		return(result);
	}
}
```

Da kriegt man wenigstens keinen Augenkrampf mehr.
Hier noch ein paar Tips:


Beginne Methoden mit einen Kleinbuchstaben und schreibe sie CamelCase.
Lass die Methodennamen wenigstens entfernt beschreiben was sie machen
Beende Schleifen, die ihre Aufgabe erfüllt haben.
Wandle nicht oft sinnlos zwischen char[] und String um.
Mach Leerzeichen.
Halte dich entfernt an irgend eine Form von Formatierung.
Behandle jedes Programm wie ein Neugebohrenes, denn nur so kann es zu etwas nützlichen/guten heranwachsen.
Und das wichtigste von allem: Schreibe die Kommentare direkt nach der Zeile oder lasse sie ganz, die sinnlosen Leerzeichen nerfen beim Navigieren mehr als alles andere.


----------



## Bullet1990 (27. März 2010)

OK, ich danke dir und ich werde versuchen mich an die Tips zu halten.


----------

