PDA

View Full Version : (JAVA) generare password


prazision
01-03-2005, 18:10
classe:


import java.util.*;

public class PwdGenerator {

/** Creates a new instance of GeneratePwd */
public PwdGenerator() {

}

Random rnd = new Random();

public static void main(String arfgv[])
{
PwdGenerator a = new PwdGenerator();
System.out.println(a.getPWD());
PwdGenerator a2 = new PwdGenerator();
System.out.println(a2.getPWD());

}

public String getPWD() {

//decido dimensione password
int dim = 8;//rnd.nextInt(5);
//dim = dim+6;
//decido la quantità di cifre numeriche
int num = rnd.nextInt(dim-4)+1;
num= num+2;
//decido la quantità di cifre alfa
int alfa = dim-num;
int appoggio=0;
String pass="";
int alterna=0;
int contnum=1;
int contalfa=1;
for (int i=1;i<=dim;i++) {
alterna = rnd.nextInt(2);
if (contalfa>alfa){alterna=0;}
else{if (contnum>num) {alterna=1;}
}
if (alterna==1) {contalfa++;
appoggio = rnd.nextInt(25);
switch (appoggio) {
case 0 : pass = pass+"A";break;
case 1 : pass = pass+"B";break;
case 2 : pass = pass+"C";break;
case 3 : pass = pass+"D";break;
case 4 : pass = pass+"E";break;
case 5 : pass = pass+"F";break;
case 6 : pass = pass+"G";break;
case 7 : pass = pass+"H";break;
case 8 : pass = pass+"I";break;
case 9 : pass = pass+"J";break;
case 10 : pass = pass+"K";break;
case 11 : pass = pass+"L";break;
case 12 : pass = pass+"M";break;
case 13 : pass = pass+"N";break;
case 14 : pass = pass+"O";break;
case 15 : pass = pass+"P";break;
case 16 : pass = pass+"Q";break;
case 17 : pass = pass+"R";break;
case 18 : pass = pass+"S";break;
case 19 : pass = pass+"T";break;
case 20 : pass = pass+"U";break;
case 21 : pass = pass+"W";break;
case 22 : pass = pass+"X";break;
case 23 : pass = pass+"Y";break;
case 24 : pass = pass+"Z";break;
}
}
if (alterna==0) {contnum++;
appoggio = rnd.nextInt(10);
switch (appoggio) {
case 0 : pass = pass+"0";break;
case 1 : pass = pass+"1";break;
case 2 : pass = pass+"2";break;
case 3 : pass = pass+"3";break;
case 4 : pass = pass+"4";break;
case 5 : pass = pass+"5";break;
case 6 : pass = pass+"6";break;
case 7 : pass = pass+"7";break;
case 8 : pass = pass+"8";break;
case 9 : pass = pass+"9";break;
}
}
}

return pass;
}

}

viene richiamata da alcune pagine jsp(col codice che segue) per creare una password:
PwdGenerator a = new PwdGenerator();
String pws =a.getPWD();

Io penso che se la pagina che contiene la creazione della password viene richiamata contemporaneamente da 2 utenti(unpo' come avviene nel main che ho mostrato) le password generate sono uguali(per via delle caratteristiche della classe Random )

La mia paura è fondata o si tratta di un'ipotesi semimpossibile?
Come si puo' rimediare?

ciao grazie

kingv
01-03-2005, 21:55
Originariamente inviato da prazision

La mia paura è fondata o si tratta di un'ipotesi semimpossibile?
Come si puo' rimediare?

ciao grazie



statisticamente è molto difficile, ma se vuoi rimediare in maniera molto semplice basta che usi la stessa istanza di Random per generare tutti i numeri casuali usati da PwdGenerator.

prazision
01-03-2005, 22:13
ok grazie ma come faccio, con static??

kingv
01-03-2005, 22:16
Originariamente inviato da prazision
ok grazie ma come faccio, con static??


esatto. per non incorrere in problemi di concorrenza non dovresti pero' accedere direttamente all'oggetto ma farlo attraverso un metodo sincronizzato della tua classe, in modo che le richieste siano sequenziali.

prazision
01-03-2005, 22:18
tramite l'uso della classe Thread vero???(l'avevo visto qualche esempio)

prazision
01-03-2005, 22:30
(forse la classe Thread non centra nulla)

kingv
02-03-2005, 08:20
no lascia stare i thread, ti dichiari un getPwd() synchronized e solo lì accedi all'oggetto di classe Random condiviso tra tutte le istanza della tua classe.

Lo scopo è proprio quello di evitare di chiamare nextInt() da due thread contemporaneamente.

prazision
02-03-2005, 09:03
ok grazie, se avro' problemi ti scassero' :D

prazision
02-03-2005, 13:01
Ho notato che se metto

static Random rnd = new Random();
invece di Random rnd = new Random();
e utilizzo un metodo static cosi:

public static void main(String arfgv[])
{
PwdGenerator a = new PwdGenerator();
System.out.println(a.getPWD());

PwdGenerator a2 = new PwdGenerator();
System.out.println(a2.getPWD());
}

ottengo 2 password diverse (al contrario di quando rnd non è static)

Perchè succede questo?
se le chiamate sono istantanee il seme di Random non dovrebbe essere cmq
lo stesso??

Forse perchè l'oggetto rnd è condiviso dalle classi istanziate e quindi il metodo nextInt() viene eseguito dallo stesso oggetto(e quindi per forza in maniera sequenziale, dando 2 risultati diversi)?

E quindi tale cosa potrebbe risolvere il mio problema nel senso che anche se ci fossero 2 chiamate a 2 pagine nello stesso istante la password generate sarebbero diverse(unpo' come nel main della mia classe)?

spero di essermi spiegato grazie

kingv
02-03-2005, 13:51
ma scusa di che stavamo parlando? :D

la "new" viene eseguita solo la prima volta che la classe viene istanziata, per cui la seconda opera sulla stessa istanza e quindi nextInt() richiama un nuumero successivo nella sequenza pseudocasuale e non è mai uguale al precedente (salvo che ci siano due numeri uguali nella sequenza naturalmente)

prazision
02-03-2005, 14:03
ma tu parlavi di synchronized , come ho fatto io(aggiungendo solo Static) non è sufficiente?

inoltre ti chiedo:"nextInt() richiama un nuumero successivo nella sequenza pseudocasuale" perchè viene eseguito dallo stesso oggetto(anche se magari richiamato nello stesso isstante)?

siam sicuri che non ci sono pericoli???


grazie

kingv
02-03-2005, 14:07
Originariamente inviato da prazision
ok grazie ma come faccio, con static??


Originariamente inviato da kingv
esatto. per non incorrere in problemi di concorrenza non dovresti pero' accedere direttamente all'oggetto ma farlo attraverso un metodo sincronizzato della tua classe, in modo che le richieste siano sequenziali.


io ti ho detto di metterlo static ma di non accedere a esso direttamente ma tramite un metodo synchronized, per prevenire possibili comportamenti anomali, se piu' thread accedessero contemporaneamente. ;)


"nextInt() richiama un nuumero successivo nella sequenza pseudocasuale" perchè viene eseguito SULLO stesso oggetto

prazision
02-03-2005, 14:14
azz i metodi synchronized non li ho ancora manco visti.

dici che è una cosa obbligatoria usarlo o vabene anche cosi??? :mc:

kingv
02-03-2005, 14:26
Originariamente inviato da prazision
azz i metodi synchronized non li ho ancora manco visti.

dici che è una cosa obbligatoria usarlo o vabene anche cosi??? :mc:




non so se va bene anche così o meno perchè bisognerebbe andare a vedere il
codice di java.util.Random, ma dubito che sia thread safe di suo ;)




basta che nella tua classe crei un metodo

protected synchronized int nextInt()
{
return rnd.nextInt();
}




e poi al posto di chiamare rnd.nextInt() chiami questo.

prazision
02-03-2005, 14:32
ok provero' e poi ti faro' sapere
grazie

prazision
02-03-2005, 15:23
penso che vada bene anche senza crearsi un metodo apposta synchronized


http://java.sun.com/j2se/1.4.2/docs/api/java/util/Random.html#nextInt(int)

kingv
02-03-2005, 15:35
Originariamente inviato da prazision
penso che vada bene anche senza crearsi un metodo apposta synchronized


http://java.sun.com/j2se/1.4.2/docs/api/java/util/Random.html#nextInt(int)



dove sta scritto che è thread safe? :confused:

prazision
02-03-2005, 15:48
dopo ci guardo bene(confesso che mi è stato detto, non ho approfondito :cool: )

kingv
02-03-2005, 15:57
Originariamente inviato da prazision
dopo ci guardo bene(confesso che mi è stato detto, non ho approfondito :cool: )


ok, la risposta che mi hai mandato mi hai convinto.
in effetti avevo guardato il sorgente di Random del jdk 1.5 e il fatto che next() non fosse synchronized mi aveva fatto "rizzare le antenne"

ma PGI qui non si fa piu' vedere?

prazision
02-03-2005, 16:03
non so,non ci ho mai fatto caso.
cmq non volevo fare il rompi*****, ti ringrazio tantissimo

kingv
02-03-2005, 16:24
Originariamente inviato da prazision
non so,non ci ho mai fatto caso.
cmq non volevo fare il rompi*****, ti ringrazio tantissimo



figurati, abbiamo imparato qualcosa in due ;)