Java - Validar contraseñas de un archivo .txt

 
Vista:
sin imagen de perfil
Val: 25
Ha aumentado su posición en 1146 puestos en Java (en relación al último mes)
Gráfica de Java

Validar contraseñas de un archivo .txt

Publicado por ander (15 intervenciones) el 14/07/2021 07:45:26
Como puedo validar contraseñas de un archivo .txt bajo estos parámetros:

-que contenga mínimo una mayúscula
-que contenga mínimo una minúscula
-que contenga mínimo un número
-y que contenga mínimo un carácter especial : "@,#,-,*,_"

después de leer el archivo como puedo hacerle para que me cree dos nuevos archivos uno que guarde las contraseñas que cumplen con los parámetros y otro archivo .txt que me guarde las contraseñas que no cumplen con los parámetros
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
Imágen de perfil de Kabuto
Val: 3.428
Oro
Ha mantenido su posición en Java (en relación al último mes)
Gráfica de Java

Validar contraseñas de un archivo .txt

Publicado por Kabuto (1044 intervenciones) el 14/07/2021 12:30:27
Primero pensemos en validar una contraseña, dejando de lado lo de trabajar con archivos txt.

Se puede hacer una clase con un método que se encargue específicamente de recibir un String y devolver verdadero/falso si cumple los 4 parámetros que lo valida como contraseña.

A su vez, cada parámetro, se puede comprobar con métodos específicos. Uno que se encargue de comprobar si hay al menos una mayúscula, otro para la minúscula, otro para buscar números, etc...

Si todos estos métodos retornan verdadero, es que la contraseña es válida.

¿Y como comprobar, por ejemplo, si un String contiene una mayúsucula?
Una forma rápida es recorrer cada carácter del String y obtener su código ASCII.
Si su código es un entero entre 65 y 90, que son los códigos ASCII de las mayúsculas (ver tabla ASCII) es que se ha encontrado al menos una mayúscula y el método puede retornar TRUE.
También comprobamos el código 165, que es la Ñ mayúscula.

1
2
3
4
5
6
7
8
9
private static boolean tieneMayuscula(String password) {
		for (int i = 0; i < password.length(); i++) {
			int codigo = password.codePointAt(i);
			if ((codigo >= 65 && codigo <= 90) || codigo == 165) //De A hasta Z o Ñ
				return true;
		}
		//Bucle for no ha encontrado mayúsculas
		return false;
	}

Para la minúscula, mismo proceso, pero con los códigos correspondientes a las minúsculas.
1
2
3
4
5
6
7
8
9
private static boolean tieneMinuscula(String password) {
		for (int i = 0; i < password.length(); i++) {
			int codigo = password.codePointAt(i);
			if ((codigo >= 97 && codigo <= 122) || codigo == 164) //De a hasta z o ñ
				return true;
		}
		//Bucle for no ha encontrado minúsculas
		return false;
	}

Para números, lo mismo:
1
2
3
4
5
6
7
8
9
private static boolean tieneNumero(String password) {
		for (int i = 0; i < password.length(); i++) {
			int codigo = password.codePointAt(i);
			if (codigo >= 48 && codigo <= 57) //De 1 hasta 9
				return true;
		}
		//Bucle for no ha encontrado números
		return false;
	}

Para los caracteres especiales, en este caso, los códigos de estos caracteres no son consecutivos y no nos va a servir comparar con mayor y menor que.
Habrá que usar un switch y entonces, nos da igual comprobar el código ASCII, o comprobar directamente los caracteres que buscamos:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private static boolean tieneEspecial(String password) {
		for (int i = 0; i < password.length(); i++) {
			char caracter = password.charAt(i);
			switch(caracter) {
			case '@':
			case '#':
			case '-':
			case '*':
			case '_':
				return true;
			}
		}
		//Bucle for no ha encontrado especiales
		return false;
	}

Vale, tenemos cuatro métodos para los cuatro parámetros que ha de cumplir una contraseña.

Pues ahora usamos un método que reciba la contraseña a comprobar, se la pase a estos cuatro métodos y compruebe si TODOS retornan TRUE, en cuyo caso la contraseña es correcta.
Si alguno retorna FALSE, es que no se cumplen todos los parámetros y por tanto la contraseña no es válida.

Este método, es tan sencillo como esto:
1
2
3
4
5
public static boolean esValida(String password) {
		//Solo si se cumplen los 4 parámetros se retornará TRUE
		return tieneMayuscula(password) && tieneMinuscula(password)
				&& tieneNumero(password) && tieneEspecial(password);
	}

Todos estos métodos los vamos a tener juntos en una clase, que podemos llamar ValidaPassword (o como tu quieras)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
public class ValidaPassword {
 
	public static boolean esValida(String password) {
		//Solo si se cumplen los 4 parámetros se retornará TRUE
		return tieneMayuscula(password) && tieneMinuscula(password)
				&& tieneNumero(password) && tieneEspecial(password);
	}
 
	private static boolean tieneMayuscula(String password) {
		for (int i = 0; i < password.length(); i++) {
			int codigo = password.codePointAt(i);
			if ((codigo >= 65 && codigo <= 90) || codigo == 165) //De A hasta Z o Ñ
				return true;
		}
		//Bucle for no ha encontrado mayúsculas
		return false;
	}
 
	private static boolean tieneMinuscula(String password) {
		for (int i = 0; i < password.length(); i++) {
			int codigo = password.codePointAt(i);
			if ((codigo >= 97 && codigo <= 122) || codigo == 164) //De a hasta z o ñ
				return true;
		}
		//Bucle for no ha encontrado minúsculas
		return false;
	}
 
	private static boolean tieneNumero(String password) {
		for (int i = 0; i < password.length(); i++) {
			int codigo = password.codePointAt(i);
			if (codigo >= 48 && codigo <= 57) //De 1 hasta 9
				return true;
		}
		//Bucle for no ha encontrado números
		return false;
	}
 
	private static boolean tieneEspecial(String password) {
		for (int i = 0; i < password.length(); i++) {
			char caracter = password.charAt(i);
			switch(caracter) {
			case '@':
			case '#':
			case '-':
			case '*':
			case '_':
				return true;
			}
		}
		//Bucle for no ha encontrado especiales
		return false;
	}
}

Fíjate que todos los métodos los he declarado como static. Esto es porque esta clase no va a representar ningún tipo de entidad (una Persona, un Perro, un Coche, un Hotel....) y por tanto no vamos a necesitar crear distintos objetos únicos a partir de esta clase.

Solo necesitamos que cumpla ciertas tareas, como validar una contraseña, así que podemos declarar sus métodos como static y así llamarlos cuando queramos sin tener que instanciar un objeto.

Podemos hacer una prueba a ver si funciona con este sencillo main.

1
2
3
4
5
6
7
8
9
10
11
12
public class Prueba {
 
	public static void main(String[] args) {
 
		String pass = "h4P*la";
 
		System.out.print("La contraseña... " + pass + " ...es: ");
		System.out.println(ValidaPassword.esValida(pass)?"VALIDA":"INVALIDA");
 
	}
 
}

Y en pantalla veremos que distingue bien las contraseñas válidas de las que no:
1
La contraseña... h4P*la ...es: VALIDA
1
La contraseña... h4Pla ...es: INVALIDA



Bueno, pues ahora ya somos capaces de determinar si una contraseña es válida o no.
Comprueba que entiendes todo lo que hemos hecho, si no es así, pregunta lo que sea.


Lo siguiente será hacer que obtenga las contraseñas de un archivo de texto.
Haz tu un intento, a ver qué consigues. No importa si no lo completas o te equivocas, lo que importa es intentarlo.

Habría que hacer que la clase ValidaPassword tuviera un nuevo método donde reciba un String con la ruta del archivo de texto que ha de comprobar.
Que lea el archivo y que pase cada contraseña obtenida por el método que las valida.
Para simplificar, si quieres de momento no hagas lo de escribir las validas e inválidas en distintos archivos.
Haz solo que muestre en pantalla cada contraseña que tenga el archivo de texto y diga si es válida o no.

El archivo de texto, cada contraseña debería ocupar una línea separada, para que sea más sencillo.
Algo como esto:

1
2
3
4
5
6
7
8
9
12345
12abc45
Hol4#
h4ck-mE
ab23c_O
password
cOntr4s3ñ4
miPassword_
Java14*#
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar

Validar contraseñas de un archivo .txt

Publicado por Tom (1714 intervenciones) el 14/07/2021 15:29:15
Ya que usas codePointAt() que devuelve un Unicode code point no se debería comparar con los valores numéricos de los caracteres ASCII (funcionará, a veces sí, a veces no, y dependerá de la codificación ppor defecto que tengas en tu terminal -consola-).

Yo usaría en su lugar los método pensados para trabajar con Unicode, por ejemplo:

https://docs.oracle.com/javase/8/docs/api/java/lang/Character.html#getType-int-
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar
sin imagen de perfil
Val: 25
Ha aumentado su posición en 1146 puestos en Java (en relación al último mes)
Gráfica de Java

Validar contraseñas de un archivo .txt

Publicado por ander (15 intervenciones) el 16/07/2021 01:28:31
como puedo hacerle para leerle desde un archivo .txt
adjunto el link del archivo

https://drive.google.com/file/d/1NxCg9Hs7WwPJvCoMhIGaXv7GEJAK68dX/view?usp=sharing

y como puedo hacerle para que me genere dos archivos txt uno con contraseñas que cumplen los parametros y otro con contraseñas que no cumplen
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Kabuto
Val: 3.428
Oro
Ha mantenido su posición en Java (en relación al último mes)
Gráfica de Java

Validar contraseñas de un archivo .txt

Publicado por Kabuto (1044 intervenciones) el 16/07/2021 11:38:33
Insisto, haz un intento. No te vamos a hacer el ejercicio completo, porque eso no es ayudarte.

Si te han pedido que hagas este ejercicio, es que previamente te han explicado y/o proporcionado el temario necesario para poder hacerlo.

Puedes leer archivos de texto con las clases BufferedReader o incluso con la clase Scanner.
Revisa tu temario o busca ejemplos por Internet (la mejor opción) y escribe un código que lea el archivo de texto con las contraseñas y las muestre en pantalla.
Solo eso, a partir de ahí, se puede ir modificando el código para hacer el resto de cosas que pide el ejercicio.

Pero tienes que intentar hacerlo tú.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar
sin imagen de perfil
Val: 25
Ha aumentado su posición en 1146 puestos en Java (en relación al último mes)
Gráfica de Java

Validar contraseñas de un archivo .txt

Publicado por ander (15 intervenciones) el 16/07/2021 22:11:23
le hice este código en el metodo main que lee el archivo linea por linea pero al guardar en el archivo .txt solo se guarda la primera contraseña
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public static void main(String[] args) throws IOException {
    Scanner lee = new Scanner(new File("C:\\Users\\Nickand\\Desktop\\Pass.txt"));
    String linea = lector.nextLine();
 
    while (lee.hasNextLine()) {
        linea = lector.nextLine();
    System.out.print("La contraseña... " + linea + " ...es: ");
    System.out.println(PasswordScanner.esValida(linea)?"VALIDA":"INVALIDA");
 
    }
    lee.close();
      FileOutputStream n = null;
    try {
        n = new FileOutputStream("C:\\Users\\Nickand\\Desktop\\Valida.txt");
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
 
    ObjectOutputStream out= new ObjectOutputStream(n);
    out.writeObject(linea);
    out.close();
}
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 25
Ha aumentado su posición en 1146 puestos en Java (en relación al último mes)
Gráfica de Java

Validar contraseñas de un archivo .txt

Publicado por andre (15 intervenciones) el 16/07/2021 23:31:47
le corregí el método main ya guarda las contraseñas pero como puedo guardar en archivos separados la contraseña valida en un archivo e invalida en otro archivo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static void main(String[] args) throws IOException {
			Scanner lector = new Scanner(new File("C:\\Users\\us\\Desktop\\Pass.txt"));
			String linea = lector.nextLine();
			FileWriter fichero=new FileWriter("C:\\Users\\us\\Desktop\\Pass11.txt");
			while (lector.hasNextLine()) {
				fichero.write("La contraseña... " + linea + " ...es: ");
				fichero.write(PasswordScanner.esValida(linea)?"VALIDA\n":"INVALIDA\n");
				linea = lector.nextLine();
 
			}
			fichero.close();
			System.out.println("Escanenado contraseña");
	}
 
}
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Kabuto
Val: 3.428
Oro
Ha mantenido su posición en Java (en relación al último mes)
Gráfica de Java

Validar contraseñas de un archivo .txt

Publicado por Kabuto (1044 intervenciones) el 17/07/2021 00:45:02
OK, vamos mejor.

Para crear archivos separados, creo que lo mejor es crear primero dos ArrayList, uno con las contraseñas válidas y otro con las inválidas.

Es decir, primero leemos archivo, si una contraseñas es válida la metemos en un ArrayList, si no lo es, la metemos en el otro.
Aquí ya no es necesario añadir el texto de si es válida o no, solo debemos guardar la contraseña en un List o en el otro.

Luego, tras finalizar la lectura, escribimos el contenido de esos ArrayList en diferentes archivos.
Para ahorrar código, podemos hacer un método que se encargue únicamente de recibir un ArrayList, una ruta de archivo, y escribir ahí las contraseñas de ese ArrayList.

Te dejo un ejemplo, continuando con la clase ValidaPassword que puse al principio.
Le añado dos métodos:
Uno se llama validarArchivo() que recibe la ruta de un archivo, lo lee y crea dos ArrayList separados.
Luego llama dos veces al método escribirArchivo(), para escribir el contenido de esos dos ArrayList en distintos archivos.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
public static void validarArchivo(String ruta) {
 
		ArrayList<String> validas = new ArrayList<String>();
		ArrayList<String> inValidas = new ArrayList<String>();
 
		try {
			BufferedReader lector = new BufferedReader(new FileReader(ruta));
			//Leemos primera contraseña
			String password = lector.readLine();
			while (password != null) {
				/*
				 * Comprobamos la validez de la contraseña y
				 * la guardamos en el ArrayList correspondiente.
				 */
				if (esValida(password))
					validas.add(password);
				else
					inValidas.add(password);
				//Leemos la siguiente contraseña y se repite el bucle
				password = lector.readLine();
			}
			lector.close();
			/*
			 * Finalizado el bucle WHILE, ya tenemos las contraseñas
			 * válidas separadas de las inválidas en dos listas.
			 * Ahora podemos crear dos archivos de texto con ellas.
			 */
			escribirArchivo(validas, "d:/validas.txt");
			System.out.println("Creado archivo de contraseñas validas: d:/validas.txt");
			escribirArchivo(inValidas, "d:/invalidas.txt");
			System.out.println("Creado archivo de contraseñas invalidas: d:/invalidas.txt");
		} catch (FileNotFoundException e) {
			System.out.println("No existe archivo:\n" + ruta);
		} catch (IOException e) {
			System.out.println("Error de acceso a:\n" + ruta);
		}
	}
 
	private static void escribirArchivo(ArrayList<String> lista, String ruta) {
		try {
			BufferedWriter escritor = new BufferedWriter(new FileWriter(ruta));
			for (String password: lista) {
				escritor.write(password);
				escritor.newLine();
			}
			escritor.close();
		} catch (IOException e) {
			System.out.println("Error de acceso a:\n" + ruta);
		}
	}
}


Luego en la clase main de prueba, tan solo necesito invocar a este nuevo método y pasarle la ruta del archivo


1
2
3
4
5
6
7
8
9
public class Prueba {
 
	public static void main(String[] args) {
 
		ValidaPassword.validarArchivo("d:/Pass.txt");
 
	}
 
}


Si todo ha ido bien, pues en pantalla me informa de donde puedo encontrar los dos nuevos archivos creados:
1
2
Creado archivo de contraseñas validas: d:/validas.txt
Creado archivo de contraseñas invalidas: d:/invalidas.txt


Así que el "truco" para facilitar la tarea es primero clasificar las contraseñas coleccionándolas en ArrayList separados, y ya luego escribir en disco el contenido de esos ArrayList
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar