Generar palabras de la mejor manera.

Iniciado por NetJava, 31 Marzo 2011, 12:18 PM

0 Miembros y 2 Visitantes están viendo este tema.

NetJava

Buenas,

Bueno la verdad es que ya he estado haciendo preguntas más o menos sobre el mismo tema del proyecto que me había planteado, y ahora llego a la conclusión de que tengo que abandonarlo. La idea era crear una tabla con todas las palabras posibles, y poner su SHA1 y su MD5. En su momento ya me enfrente a crear todas las posibilidades de palabras y era imposible por el tiempo. Bueno las ideas que se me ocurrieron y que hice.

1.- Como se creaban muchas palabras "inservibles" hice que el programa cogiera libros en .txt, los filtrase para quitar signos, y después guardaba las palabras obtenidas, todas servibles, aun que ya sabemos que una contraseña es compleja frente a una palabra normal. Y más si tenemos una palabra con acento, o con una letra en mayúscula, pero bueno...

2.- Volví a generar palabras aleatoriamente pero con Thread (bueno para ser más exactos cada función de la aplicación se hacía en Thread diferentes). Bueno la cuestión es que aunq empiece a generar por un lado palabras con 10 caracteres y 32 posibilidades en un hilo, y en otro palabras de 9 caracteres con 32 posibilidades los tiempos siguen siendo demasiado... Así que os pongo un ejemplo.

Bueno el bucle normal (para 6 caracteres en la palabra) seria "for(int a = 0; a < 32; a++)" etc... Lo que pense e hice fue el bucle de para 6 caracteres separarlo en 4 bucles, cada uno en thread diferente. Pero aun así es imposible, por que hablamos de millones...

Código (java) [Seleccionar]

public void GenerarDiccionario6_1(JLabel jlbl_0){
DBManagementx DBM11 = new DBManagementx();
String ContentCarac = "";
String c1 = "";
String c2 = "";
String c3 = "";
String c4 = "";
String c5 = "";
for(int a = 0; a < 10; a++){
c1 = caracteres1[a];
for(int e = 0; e < 15; e++){
c2 = caracteres1[e];
for(int i = 0; i < 32; i++){
c3 = caracteres1[i];
for(int o = 0; o < 32; o++){
c4 = caracteres1[o];
for(int u = 0; u < 32; u++){
c5 = caracteres1[u];
for(int A = 0; A < 32; A++){
ContentCarac = c1 + c2 + c3 + c4 + c5 +caracteres1[A];
DBM11.fillTablex(ContentCarac, jlbl_0);
//JOptionPane.showMessageDialog(null,""+ContentCarac,"Message",JOptionPane.INFORMATION_MESSAGE);
ContentCarac = "";
}
}
}
}
}
}
DBM11 = null;
}


Código (java) [Seleccionar]

public void GenerarDiccionario6_1_1(JLabel jlbl_0){
DBManagementx DBM11 = new DBManagementx();
String ContentCarac = "";
String c1 = "";
String c2 = "";
String c3 = "";
String c4 = "";
String c5 = "";
for(int a = 0; a < 10; a++){
c1 = caracteres1[a];
for(int e = 15; e < 32; e++){
c2 = caracteres1[e];
for(int i = 0; i < 32; i++){
c3 = caracteres1[i];
for(int o = 0; o < 32; o++){
c4 = caracteres1[o];
for(int u = 0; u < 32; u++){
c5 = caracteres1[u];
for(int A = 0; A < 32; A++){
ContentCarac = c1 + c2 + c3 + c4 + c5 +caracteres1[A];
DBM11.fillTablex(ContentCarac, jlbl_0);
//JOptionPane.showMessageDialog(null,""+ContentCarac,"Message",JOptionPane.INFORMATION_MESSAGE);
ContentCarac = "";
}
}
}
}
}
}
DBM11 = null;
}


Bueno pues os cuento un poco más. Esto aun así tarda mucho. Lo que se hace: a través de un hilo se ejecuta el bucle va al método donde se guarda en la BD, pero antes se coteja con lo que ya hay guardado en la BD, para que no se dupliquen palabras.

Se os ocurre algo para hacerlo mejor en cualquier sentido.

Muchas gracias y saludos.  :-\

P.D:
32 * 32 = 1024

32 * 32 * 32 = 32.768

32 * 32 * 32 * 32 = 1.048.576

32 * 32 * 32 * 32 * 32 = 33.554.432

32 * 32 * 32 * 32 * 32 * 32 = 1.073.741.824





NetJava

Bueno algo más. Cuanto hilos puede ejecutar a la vez¿? Pues para mi ordenador para que la aplicación "aguante" unos cuatro hilos aprox, el gadgets de la CPU con el primer hilo 25%, y así sucesivamente. Cuando digo que la aplicación "aguante" es por que cuanto más hilos pongo a rular en paralelo más fallos se producen al insertar en la BD. Aun q hasta 4 hilos es asequible por que se produce un error de 800 inserciones, teniendo en cuanta que con un solo hilo, no se produce ni un solo error. Para dar algo más de inf.

Saludos!!

KuraraGNU

Ufff la verdad es que son muchisimos bucles, normal que tarde tanto, habria que cambiar por completo el planteamiento del ejercicio, manteniendo lo de buscar en el txt ese. No se, quizas usando una matriz de mas de una dimension? Me lo mirare en mi tiempo libre a ver si se me ocurre algo. Exactamente cuantos hilos tienes y que hace cada uno? Es que no me entero lo de los hilos e.e

NetJava

Buenas, pues muchas gracias, te voy a poner más inf.

Lo primero es decir que se crea un objeto thread para cada bucle. Al igual que hay un objeto diferente de conexión con la BD para cada bucle.

Código (java) [Seleccionar]

...
...
...
//este código esta dentro de la clase Thread, en un case dentro del método run()
case 15:algoritx.GenerarDiccionario6_1(this.jlbl_0); break;
case 16:algoritx.GenerarDiccionario6_1_1(this.jlbl_0); break;
case 17:algoritx.GenerarDiccionario6_2(this.jlbl_0); break;
case 18:algoritx.GenerarDiccionario6_2_1(this.jlbl_0); break;
case 19:algoritx.GenerarDiccionario6_3(this.jlbl_0); break;
case 20:algoritx.GenerarDiccionario6_3_1(this.jlbl_0); break;
...
...
...
//algoritx el el objeto de la clase algoritmo donde se encuentran todos los bucles.
public void GenerarDiccionario6_1(JLabel jlbl_0){
DBManagementx DBM11 = new DBManagementx();
String ContentCarac = "";
String c1 = "";
String c2 = "";
String c3 = "";
String c4 = "";
String c5 = "";
for(int a = 0; a < 10; a++){
c1 = caracteres1[a];
for(int e = 0; e < 15; e++){
c2 = caracteres1[e];
for(int i = 0; i < 32; i++){
c3 = caracteres1[i];
for(int o = 0; o < 32; o++){
c4 = caracteres1[o];
for(int u = 0; u < 32; u++){
c5 = caracteres1[u];
for(int A = 0; A < 32; A++){
ContentCarac = c1 + c2 + c3 + c4 + c5 +caracteres1[A];
DBM11.fillTablex(ContentCarac, jlbl_0);
//JOptionPane.showMessageDialog(null,""+ContentCarac,"Message",JOptionPane.INFORMATION_MESSAGE);
ContentCarac = "";
}
}
}
}
}
}
DBM11 = null;
}

public void GenerarDiccionario6_1_1(JLabel jlbl_0){
DBManagementx DBM11 = new DBManagementx();
String ContentCarac = "";
String c1 = "";
String c2 = "";
String c3 = "";
String c4 = "";
String c5 = "";
for(int a = 0; a < 10; a++){
c1 = caracteres1[a];
for(int e = 15; e < 32; e++){
c2 = caracteres1[e];
for(int i = 0; i < 32; i++){
c3 = caracteres1[i];
for(int o = 0; o < 32; o++){
c4 = caracteres1[o];
for(int u = 0; u < 32; u++){
c5 = caracteres1[u];
for(int A = 0; A < 32; A++){
ContentCarac = c1 + c2 + c3 + c4 + c5 +caracteres1[A];
DBM11.fillTablex(ContentCarac, jlbl_0);
//JOptionPane.showMessageDialog(null,""+ContentCarac,"Message",JOptionPane.INFORMATION_MESSAGE);
ContentCarac = "";
}
}
}
}
}
}
DBM11 = null;
}

public void GenerarDiccionario6_2(JLabel jlbl_0){
DBManagementx DBM11 = new DBManagementx();
String ContentCarac = "";
String c1 = "";
String c2 = "";
String c3 = "";
String c4 = "";
String c5 = "";
for(int a = 10; a < 20; a++){
c1 = caracteres1[a];
for(int e = 0; e < 15; e++){
c2 = caracteres1[e];
for(int i = 0; i < 32; i++){
c3 = caracteres1[i];
for(int o = 0; o < 32; o++){
c4 = caracteres1[o];
for(int u = 0; u < 32; u++){
c5 = caracteres1[u];
for(int A = 0; A < 32; A++){
ContentCarac = c1 + c2 + c3 + c4 + c5 +caracteres1[A];
DBM11.fillTablex(ContentCarac, jlbl_0);
//JOptionPane.showMessageDialog(null,""+ContentCarac,"Message",JOptionPane.INFORMATION_MESSAGE);
ContentCarac = "";
}
}
}
}
}
}
DBM11 = null;
}

public void GenerarDiccionario6_2_1(JLabel jlbl_0){
DBManagementx DBM11 = new DBManagementx();
String ContentCarac = "";
String c1 = "";
String c2 = "";
String c3 = "";
String c4 = "";
String c5 = "";
for(int a = 10; a < 20; a++){
c1 = caracteres1[a];
for(int e = 15; e < 32; e++){
c2 = caracteres1[e];
for(int i = 0; i < 32; i++){
c3 = caracteres1[i];
for(int o = 0; o < 32; o++){
c4 = caracteres1[o];
for(int u = 0; u < 32; u++){
c5 = caracteres1[u];
for(int A = 0; A < 32; A++){
ContentCarac = c1 + c2 + c3 + c4 + c5 +caracteres1[A];
DBM11.fillTablex(ContentCarac, jlbl_0);
//JOptionPane.showMessageDialog(null,""+ContentCarac,"Message",JOptionPane.INFORMATION_MESSAGE);
ContentCarac = "";
}
}
}
}
}
}
DBM11 = null;
}

public void GenerarDiccionario6_3(JLabel jlbl_0){
DBManagementx DBM11 = new DBManagementx();
String ContentCarac = "";
String c1 = "";
String c2 = "";
String c3 = "";
String c4 = "";
String c5 = "";
for(int a = 20; a < 32; a++){
c1 = caracteres1[a];
for(int e = 0; e < 15; e++){
c2 = caracteres1[e];
for(int i = 0; i < 32; i++){
c3 = caracteres1[i];
for(int o = 0; o < 32; o++){
c4 = caracteres1[o];
for(int u = 0; u < 32; u++){
c5 = caracteres1[u];
for(int A = 0; A < 32; A++){
ContentCarac = c1 + c2 + c3 + c4 + c5 +caracteres1[A];
DBM11.fillTablex(ContentCarac, jlbl_0);
//JOptionPane.showMessageDialog(null,""+ContentCarac,"Message",JOptionPane.INFORMATION_MESSAGE);
ContentCarac = "";
}
}
}
}
}
}
DBM11 = null;
}

public void GenerarDiccionario6_3_1(JLabel jlbl_0){
DBManagementx DBM11 = new DBManagementx();
String ContentCarac = "";
String c1 = "";
String c2 = "";
String c3 = "";
String c4 = "";
String c5 = "";
for(int a = 20; a < 32; a++){
c1 = caracteres1[a];
for(int e = 15; e < 32; e++){
c2 = caracteres1[e];
for(int i = 0; i < 32; i++){
c3 = caracteres1[i];
for(int o = 0; o < 32; o++){
c4 = caracteres1[o];
for(int u = 0; u < 32; u++){
c5 = caracteres1[u];
for(int A = 0; A < 32; A++){
ContentCarac = c1 + c2 + c3 + c4 + c5 +caracteres1[A];
DBM11.fillTablex(ContentCarac, jlbl_0);
//JOptionPane.showMessageDialog(null,""+ContentCarac,"Message",JOptionPane.INFORMATION_MESSAGE);
ContentCarac = "";
}
}
}
}
}
}
DBM11 = null;
}
...
...
...
//Ahora se llama a al método fillTable (el nombre del método no importa jejeje). En este método se llama la otro que coteje primero.
public void fillTable(String dato){
if(Cotejar(dato) == 0){
newCodigo();
idpalabra +=1;
String SQL = "INSERT INTO palabras (idpalabras, palabras, sha1, md5) Values ('" + idpalabra + "','" + dato + "', '', '');";
try{
st.executeUpdate(SQL);
}catch(Exception e){
e.printStackTrace();
}
}
}
...
...
...


Y este es el proceso. Lo importante esq se genera un objeto thread por cada bucle, y también para las conexiones. hay muchos bucles es verdad... para generar cadenas de 10 caracteres...

Lo que necesites! Gracias.

NetJava

Buenas,

os pregunto unas cuantas cosas que son especificas y supongo que esos conocimientos los da la experiencia jejeje. Todo esto en cuanto a rendimiento de la aplicación.

1.- Que es mejor, crear un objeto y utilizar el mismo 4 veces o crear 4 objetos¿? Por ejemplo yo cuando lanzo hilos, por cada botón tengo un objeto de la clase hilo. A lo mejor debería crear una variable private instanciarla, y llamarla en los botones con el método necesario.

2.- Cuando se conecta a una base de datos, que resulta más eficiente, conectar una vez, ejecutar tus acciones y cerrar conexión. O mantener la conexión "abierta" para siempre que la necesitéis.

Esta aplicación puede llegar a saturar mi ordenador en cuanto más hilos ponga a rular, afectando a la CPU. Ya habéis visto como va, por el código. ¿Es normal que el ordenador se sature?

Muchas gracias y saludos!

Aun q ya es un poco tarde por que hace tiempo que estoy con este tema, intento ver hasta donde puedo llegar, aun q esto se tenía que hacer antes, pero bueno. 

NetJava

Buenas,

pues nada os voy a poner hasta donde he llegado. He eliminado el método cotejar, que lo que hacía era comprobar si esa palabra ya existía. De esa manera me quito un acceso a la BD. Ahora solo se accede para insertar.

Para evitar que se dupliquen palabras inserto por orden, primero de 1 carácter, cuando acabe 2 caracteres, y así sucesivamente.

El proceso lo lanzo desde un thread, de esa manera tengo un "JLabel" que me va diciendo cuantos caracteres van siendo insertados. Ahora he añadido más caracteres para crear otra BD.

1) 44 = 44

2) 44 * 44 = 1936

3) 44 * 44 * 44 = 85184   

4) 44 * 44 * 44 * 44 = 3.748.096  ******

5) 44 * 44 * 44 * 44 * 44 = 164.916.224

6) 44 * 44 * 44 * 44 * 44 * 44 = 7.256.313.856

Cuando llegue a cantidades grandes modificaré los bucles para que haga la parte proporcional a un día. Al día siguiente o por la noche, lo dejare con la cantidad correspondiente.

No se si esto os sirve de algo. Pero me he dado cuenta que MySQL no hace distinciones entre:

a, á
....
u, ú
n, ñ
tampoco hace distinción entre mayúsculas y minúsculas.

Por lo que si busco en la BD "que", el resultado será:

que
qué
qúe
qúé

Seguiré con este tema formando la BD, si a alguien se le ocurre una idea, perfect.

Saludos, y espero que sirva la inf que he dejado.


KuraraGNU

Ya que me pierdo bastante con lo que intentas, se ve que no soy tan lista, te respondo esto, jeje:
Cita de: NetJava en  1 Abril 2011, 18:07 PM
1.- Que es mejor, crear un objeto y utilizar el mismo 4 veces o crear 4 objetos¿? Por ejemplo yo cuando lanzo hilos, por cada botón tengo un objeto de la clase hilo. A lo mejor debería crear una variable private instanciarla, y llamarla en los botones con el método necesario.
Hombre, ten en cuenta que a mas objetos creados, mas consumo de memoria, pero si controlas que dejas a un hilo en espera mientras se ejecuta otro el ordenador lo tendra mas facil a la hora de controlar los ciclos de tiempo.

Cita de: NetJava en  1 Abril 2011, 18:07 PM2.- Cuando se conecta a una base de datos, que resulta más eficiente, conectar una vez, ejecutar tus acciones y cerrar conexión. O mantener la conexión "abierta" para siempre que la necesitéis. 
A mi siempre me han dicho que mejor que se cierre, no se :/.

NetJava

Buenas,

muchas gracias por responder,  lo tendré en cuenta, llevo ya días generando. El tema de la memoria del ordena me rallaba bastante. Esta claro que tengo que mejorar el manejo con los objetos XD gracias. Justamente hoy pensando un poco se me ha ocurrido que las palabras que genere las podría ir guardando en un arraylist, en vez de generar una y guardar continuamente, y cuando haya llegado a 1 millón poner un hilo en paralelo a insertar en la base de datos, mientras que otro sigue generando palabras en otro arraylist, y cuando llegue a 1 millón pasarlo al hilo que inserta y reutilizar el hilo anterior. Creo que así podría ir más rápido... Voy a probarlo hoy XD

Un saludo y gracias!!!

NetJava

Buenas,

bueno sigo preguntando o escribiendo para mi mismo jajjaja. He probado la idea que se me ocurrió ayer, y es increíblemente más rápido, y ahora es ese el problema, 1 millón se genera enseguida, entonces comienza un thread paralelo para hacer la inserción en la base de datos, la inserción se hace repetidamente dentro de un bucle... El bucle no se desborda, esta siempre limitado a 1 millón, pero va tan rápido que llega un momento en el que no para de generar excepciones. Se os ocurre alguna idea¿?

Gracias y saludos!!!

KuraraGNU

Cita de: NetJava en 13 Abril 2011, 19:03 PM
pero va tan rápido que llega un momento en el que no para de generar excepciones. Se os ocurre alguna idea¿?

Gracias y saludos!!!
Que clase de excepciones? pega unas pocas aqui XD Ponle un sleep() si va muy rapido o un pause() o como se llame. Es que no se que metodo es el que esta deprecated y cual es el que hay que usar, tu me entiendes. Cuando lo hagas quedamos por msn y me explicas lo que estas haciendo que me gustaria saber como funcioa tu programa pero no lo pillo con tanto bucle o yo que se por que.