Java - Ofuscación de contraseñas

 
Vista:
Imágen de perfil de Javier

Ofuscación de contraseñas

Publicado por Javier (18 intervenciones) el 06/12/2022 09:21:29
Buenos dias a todos.
Tengo una actividad nueva en la que trabajamos con arrays. Me piden "ofuscar" unas contraseñas, es decir , en un array en el que se han guardado contraseñas, cambiar ciertos caracteres por otros.
Encuentro como cambiar caracteres en un string pero no como hacerlo en un array.
Basicamente es esto lo que piden:

Por ejemplo, imagina la contraseña "CASANDRA". Esta expresión podría aparecer fácilmente en una lista de palabras o diccionario de tamaño medio. Si sustituimos la "C" por "((", la "A" por "4", la "S" por "$$" y la "D" por "))", obtendríamos "((4$$4N))R4", que no se parece en nada a la "CASANDRA" original (ni siquiera en el número de caracteres).

CASANDRA -> ((4$$4N))R4
La tabla de ofuscación que vamos a utilizar será la siguiente:

Tabla de ofuscación
Carácter Sustituido por Carácter Sustituido por Carácter Sustituido por
A 4 G 6 P 9
a @ H # S $$
B 8 I | s 2
C (( i 1 T 7
D )) l ! t +
E 3 O 0 V \/
e ? o * Y &

Alguien se le ocurre algo?
Se nos sugiere algo así:

Para cada contraseña, habrá que analizar cada uno de sus caracteres. Lo más sencillo es ir recorriendo cada carácter mediante un bucle.
Si alguno de sus caracteres coincide con los de la tabla de ofuscación, habrá que llevar a cabo la sustitución apropiada y seguir analizando hasta llegar al final. Puedes hacerlo, por ejemplo, con una instrucción switch, con un case para cada carácter "ofuscable".

Muchas gracias
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

Ofuscación de contraseñas

Publicado por Kabuto (1381 intervenciones) el 06/12/2022 11:29:55
Yo representaría esa tabla en una matriz de String de 21x2. Es decir, hay 21 letras que tienen 2 representaciones, "la original" y la "ofuscada"

Así podemos comparar cada letra de la contraseña original con las 21 de la tabla. Si alguna coincide con la "original" (posiciones [x][0]) la sustituimos por la "ofuscada" (posiciones [x][1])

En la tabla, algunas letras se sustituyen por dos caracteres y no por uno solo.
Esto significa que no vamos a poder reemplazar directamente caracteres sobre el String original, porque necesitamos que su longitud pueda aumentar según las letras que ofusquemos.

Así que habrá que construir una nueva cadena, podemos usar la clase String, o mejor aún, la clase StringBuilder.

Todo este proceso lo hacemos con dos bucles anidados.
El primer bucle selecciona una letra de la cadena original.
El segundo bucle recorre la tabla buscando una coincidencia, y si la encuentra, añade al nuevo String la letra ofuscada equivalente.

Si este segundo bucle no encuentra equivalencias, entonces tenemos que agregar la "letra original" al nuevo String. Para poder saber si el segundo bucle encontró equivalencia o no, podemos usar un boolean.

Este podría ser el código:
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
public class Ofuscar {
 
	private final static String[][] TABLA = crearTabla();
 
	public static void main(String[] args) {
		Scanner teclado = new Scanner(System.in);
		System.out.print("Introduce password: ");
		String pass = teclado.nextLine();
		teclado.close();
 
		//Construiremos un nuevo String con las letras originales y las ofuscadas
		StringBuilder passOfuscado = new StringBuilder();
 
		for (int i = 0; i < pass.length(); i++) {
			//Seleccionamos letra original
			String letra = pass.substring(i, i+1);
			//Con un boolean controlamos si la letra sera ofuscada o no
			boolean ofuscada = false;
			//Recorremos la TABLA
			for (int j = 0; j < TABLA.length; j++) {
				if (letra.equals(TABLA[j][0])) {
					//Letra existe en la TABLA, agregamos su equivalente ofuscado
					passOfuscado.append(TABLA[j][1]);
					ofuscada = true; //La letra ha sido ofuscada
					break; //Ya no es necesario seguir recorriendo la TABLA para la letra actual
				}
			}
			//Si la letra NO ha sido ofuscada, debemos agregar la letra original
			if (!ofuscada)
				passOfuscado.append(letra);
		}
 
		//Proceso de ofuscacion terminado
		System.out.println("\nPassword ofuscado: " + passOfuscado.toString());
 
	}
 
	private static String[][] crearTabla() {
		return new String[][] {
			{"A","4"},{"a","@"},{"B","8"},{"C","(("},
			{"D","))"},{"E","3"},{"e","?"},{"G","6"},
			{"H","#"},{"I","|"},{"i","1"},{"J","!"},
			{"O","0"},{"o","*"},{"P","9"},{"S","$$"},
			{"s","2"},{"T","7"},{"t","+"},{"V","\\/"},
			{"Y","&"}
		};
	}
 
}

Si lo probamos, veremos en pantalla que funciona:
1
2
3
Introduce password: CASANDRA
 
Password ofuscado: ((4$$4N))R4

ATENCION.
Yo he hecho un ejemplo para una sola cadena String
Se supone que tienes que hacerlo para un array de varias cadenas.
Intenta adaptar este código que he puesto para poder hacerlo con un array.

Lo ideal sería crear un método que reciba una cadena y la retorne ofuscada.
O sea, el proceso de los dos bucles, hay que trasladarlo a un método en lugar de que esté en el main.

De esta forma, en el main puedes invocar a dicho método tantas veces como necesites para ofuscar las cadenas del array



También se podría hacer con un switch como propone el enunciado y puede que así fuese más fácil de hacer y entender.

Pero sería menos óptimo. Supongamos que esto fuese un programa destinado al "mundo real".
Si con el tiempo la "tabla de ofuscación" necesitáramos cambiarla para agregar más letras o cambiar los caracteres por otros, entonces habría que reescribir el switch y recompilar todo el programa.
Y así cada vez que quisiéramos actualizar esa tabla.

En cambio, haciéndolo con la matriz, no sería necesario modificar el programa.
Solo habría que hacer que el método crearTabla(), en lugar de crear la tabla con datos "hardcoded" como he hecho en este ejemplo, pudiera tomarlos de un archivo de texto.
De esta forma, para cambiar la tabla solo habría que ir actualizando ese archivo txt, sin necesidad de modificar ni recompilar el resto del código.

Exactamente el mismo programa podría venderse a distintas empresas y ya cada una elaboraría su propia "tabla de ofuscación" a su gusto.

En fin, espero que se haya entendido el código.
Pregunta lo que sea.
Intenta adaptarlo al array, si no te sale, dilo y te ayudamos.
Saludos.
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
Imágen de perfil de Javier

Ofuscación de contraseñas

Publicado por Javier (18 intervenciones) el 07/12/2022 22:58:57
Hola Kabuto, buenas noches y muchas gracias como siempre por tomarte las molestias.
Mas o menos había entendido lo que habías hecho, pero no se si la profesora que tengo es muy "buena" o me toma por tonto, pero me dice que en la tarea se nos "insinua" que lo hagamos de la siguiente manera si queremos tenerla bien:

Declarar el array de entrada, relleno con las contraseñas que van a ser ofuscadas.
Declarar el array de resultados, de tamaño indefinido, con su contenido sin rellenar.
Reservar espacio para el array de resultados, que será del mismo tamaño que el array de entrada. No debes utilizar un literal para indicar su tamaño, sino que debes calcular el tamaño del array de entrada para que si este cambiara de tamaño no hubiera que modificar nada más.
Recorrer cada uno de los elementos del array de contraseñas.
Para cada contraseña, habrá que analizar cada uno de sus caracteres. Lo más sencillo es ir recorriendo cada carácter mediante un bucle.
Si alguno de sus caracteres coincide con los de la tabla de ofuscación, habrá que llevar a cabo la sustitución apropiada y seguir analizando hasta llegar al final. Debes hacerlo con una instrucción switch, con un case para cada carácter "ofuscable".
Una vez finalizado el análisis y transformación de la contraseña original a la contraseña ofuscada, almacenar esa contraseña ofuscada en el array de resultados o de salida.
Una vez transformadas todas las contraseñas y almacenadas en el array de resultados, recorrer cada uno de esos elementos y mostrarlos por pantalla. Cada resultado debe colocarse en una línea diferente y numerada, comenzando por 1, con el siguiente formato: Contraseña Original -> Contraseña ofuscada, tal y como se muestra en los ejemplos.

OFUSCACIÓN DE CONTRASEÑAS
-------------------------

RESULTADO
---------
1.- Paella -> 9@?!!@
2.- Vampiro -> \/@mp1r*
3.- CASANDRA -> ((4$$4N))R4
4.- DOdo -> ))0d*
5.- GABOSVE -> 6480$$\/3
6.- HIPOlito -> #|90!1+*
7.- AEGYPTOS -> 436&970$$
8.- ISISisis -> |$$|$$1212


No se si es que ella no sabe hacerlo de otra manera.
De todas maneras, lo dicho, muchisimas gracias
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

Ofuscación de contraseñas

Publicado por Kabuto (1381 intervenciones) el 08/12/2022 17:36:04
OK, pues hagámoslo "bien" je je.

Posiblemente la intención del ejercicio sea practicar con switch, aunque no sea lo más óptimo.

Podemos escribir un código que tenga dos métodos, uno para ofuscar mediante switch y otro para ofuscar mediante la matriz. Aunque luego solo uses el del switch, pero así conservas los dos ejemplos para futuras referencias.


Aquí te dejo un programa con ambos métodos y declarando arrays de entrada y salida.

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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
public class Ofuscar {
 
	public static void main(String[] args) {
 
		//Array entrada
		String[] entrada = new String[] {
				"CASANDRA", "Felipe", "Juanito",
				"Oscarin", "Jose Ramon", "JAVIER",
				"javier", "Tato"
		};
		//Array salida
		String[] salida = new String[entrada.length];
 
		//Iniciamos ofuscacion
		for (int i = 0; i < entrada.length; i++)
			salida[i] = ofuscarCadenaConSwitch(entrada[i]);
			//salida[i] = ofuscarCadenaConMatriz(entrada[i]);
 
		//Resultados
		System.out.println("OFUSCACION DE CONTRASEÑAS");
		System.out.println("---------- -- -----------");
		System.out.println("\nRESULTADO");
		System.out.println("---------");
 
		for (int i = 0; i < entrada.length; i++)
			System.out.printf("%d.- %-10s -> %-10s\n", i+1, entrada[i], salida[i]);
 
		System.out.println("\n\t\tFIN DE PROGRAMA");
	}
 
	//Método para ofuscar cadenas mediante un switch
	public static String ofuscarCadenaConSwitch(String cadena) {
 
		//Construiremos un nuevo String con las letras originales y las ofuscadas
		StringBuilder passOfuscado = new StringBuilder();
 
		for (int i = 0; i < cadena.length(); i++) {
			//Seleccionamos letra original
			String letra = cadena.substring(i, i+1);
			//Analizamos letra con Switch
			switch(letra) {
			case "A":
				passOfuscado.append("4");
				break;
			case "a":
				passOfuscado.append("@");
				break;
			case "B":
				passOfuscado.append("8");
				break;
			case "C":
				passOfuscado.append("((");
				break;
			case "D":
				passOfuscado.append("))");
				break;
			case "E":
				passOfuscado.append("3");
				break;
			case "e":
				passOfuscado.append("?");
				break;
			case "G":
				passOfuscado.append("6");
				break;
			case "H":
				passOfuscado.append("#");
				break;
			case "I":
				passOfuscado.append("|");
				break;
			case "i":
				passOfuscado.append("1");
				break;
			case "J":
				passOfuscado.append("!");
				break;
			case "O":
				passOfuscado.append("0");
				break;
			case "o":
				passOfuscado.append("*");
				break;
			case "P":
				passOfuscado.append("9");
				break;
			case "S":
				passOfuscado.append("$$");
				break;
			case "s":
				passOfuscado.append("2");
				break;
			case "T":
				passOfuscado.append("7");
				break;
			case "t":
				passOfuscado.append("+");
				break;
			case "V":
				passOfuscado.append("\\/");
				break;
			case "Y":
				passOfuscado.append("&");
				break;
			default: //No es una letra ofuscable
				passOfuscado.append(letra);
			}
		}
		//Retornamos cadena ofuscada
		return passOfuscado.toString();
	}
 
	//Método para ofuscar cadenas mediante una matriz
	public static String ofuscarCadenaConMatriz(String cadena) {
 
		final String[][] TABLA = new String[][] {
			{"A","4"},{"a","@"},{"B","8"},{"C","(("},
			{"D","))"},{"E","3"},{"e","?"},{"G","6"},
			{"H","#"},{"I","|"},{"i","1"},{"J","!"},
			{"O","0"},{"o","*"},{"P","9"},{"S","$$"},
			{"s","2"},{"T","7"},{"t","+"},{"V","\\/"},
			{"Y","&"}
		};
 
		//Construiremos un nuevo String con las letras originales y las ofuscadas
		StringBuilder passOfuscado = new StringBuilder();
 
		for (int i = 0; i < cadena.length(); i++) {
			//Seleccionamos letra original
			String letra = cadena.substring(i, i+1);
			//Con un boolean controlamos si la letra sera ofuscada o no
			boolean ofuscada = false;
			//Recorremos la TABLA
			for (int j = 0; j < TABLA.length; j++) {
				if (letra.equals(TABLA[j][0])) {
					//Letra existe en la TABLA, agregamos su equivalente ofuscado
					passOfuscado.append(TABLA[j][1]);
					ofuscada = true; //La letra ha sido ofuscada
					break; //Ya no es necesario seguir recorriendo la TABLA para la letra actual
				}
			}
			//Si la letra NO ha sido ofuscada, debemos agregar la letra original
			if (!ofuscada)
				passOfuscado.append(letra);
		}
 
		//Retornamos cadena ofuscada
		return passOfuscado.toString();
	}
 
}
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