Newsgroup: it.comp.java
Titolo: generare password

questa 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 )
E' una paura reale o è impossibile che si verifichi tale ipotesi?
Come si puo' rimediare?
ciao grazie
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 
tramite l'uso della classe Thread o dell'interfaccia runnable.
crei un'istanza della tua classe e ne vieti l'accesso fino a quando non 
torna disponibile.
altrimenti con una variabile statica setti il numero massimo di istanze di 
PwdGenerator e sollevi un'eccezione quando il numero è superiore a 1.
ho detto la mia, x quanto ne so potrebbe essere tutto sbagliato o tutto 
molto più complicato di come è in realtà :)
-- 
Nuno® su Charlize (con la bua) con Denise a tracolla.
"sono cretino dentro, mi riprendo in fretta.." cit. GSchicco
ICQ - 140416778
(elimina OGNI DUBBIO per la mail)

 PwdGenerator e sollevi un'eccezione quando il numero è superiore a 1.
ok ma cosa succede se un utente richiede la pagina e in quel momento c'è
già un'istanza della classe???succede che quell'utente non riesce ad avere
la password???
ma la paura è fondata o si puo' verificare un caso su 1000miliardi in cui
succede quello che dico?


 
penso sia un caso su milioni di miliardi che due utenti chiamino 
esattamente nello stesso istante la pagina...
da quanto mi pare di ricordare il generatore di numeri casuali si 
inizializza in base ai millisecondi passati dopo la mezzanotte giusto? 
funziona così anche in java?
se così fosse basta mettere un tempo di attesa all'interno della classe 
PwdGeneretor superiore al millesimo di secondo...ecco quindi che, anche se 
fosse possibile chiamare nello stesso millisecondo la classe Random per più 
di una volta, elimini l'eventualità che ciò accada.
il tutto mi sembra molto macchinoso...una corretta gestione del Threads è 
la cosa più semplice e pulita.



Forse si, ma se anche fosse? Le password non devono essere per forza 
differenti, le username si.
Inoltre se vuoi un codice piu' carino:
public class PasswordGenerator {
 final static String PASSWORD_CHARS = 
"QWERTYUIOPASDFGHJKLZXCVBNM1234567890";
 final static int SIZE = 6;
 public static String generate() {
  Random rand = new Random(System.currentTimeMillis());
  int length = PASSWORD_CHARS.length();
  String password = "";
  for(int i = 0; i < SIZE; ++i) {
   int index = rand.nextInt(length-1);
   password += PASSWORD_CHARS.charAt(index);
  }
  return password;
 }
}

> Inoltre se vuoi un codice piu' carino:
ah scusa per la presunzione! ;)
mi sono accorto adesso che il tuo codice fa qualcosina in piu'. 

grazie mille a tutti


grazie a tutti


La classe Random garantisce che la sequenza pseudocasuale non si ripeta mai, 
la probabilità che due sequenze numeriche coincidono è nulla. Se le radici
di generazione dei  numeri sono diverse.
Nel tuo codice se scrivi nel main:
        PwdGenerator a = new PwdGenerator();
        PwdGenerator a2 = new PwdGenerator();
        System.out.println(a.getPWD());
        System.out.println(a2.getPWD());
Hai la certezza che le due sequanze sono uguali perchè viene usato come
radice il timestamp e le due istanza vengono create nel medesimo
millisecondo.
Se però trasformi il Randon in static:
        static Random random = new Random();
le due sequenze saranno sempre univoche:
-- 
----------------------------------------------------------
......vieni a trovarmi 
http://www.glz.it
......novità java, forum e altro 
http://www.javastaff.com
----------------------------------------------------------
------dai voce al tuo sito e monitorizza gli accessi------
---------------
http://www.talkwithus.it-------------------
----------------------------------------------------------

 le due sequenze saranno sempre univoche:
effettivamente(sembra così semplice)


ma scusa in questo caso, mettendo
static Random rnd = new Random();
cosa succede di diverso???
se le chiamate sono istantanee il seme di Random non dovrebbe essere cmq
lo stesso??
forse dipende dal fatto che essendo l'oggetto Random rnd condiviso dalle 2
pagine chiamate il metodo nextInt viene chiamato sempre dallo stesso
oggetto(prima da una pagina e poi dall'altra) e quindi da 2 risultati
diversi???(mentre prima il metodo veniva chiamato da 2 oggetti diversi)


forse però non è tanto bello avere lo stesso oggetto Random condiviso dai
vari oggetti PwdGenerator nelle pagine jsp, che problemi potrebbe dare? 


Random DEVE essere condiviso, proprio per garantire l'univocità della serie,
e static ha proprio questo scopo.
Il seme viene inizializzato all'istanziazione della classe random. Hai la
garanzia di univocità di una serie se usi la medesima istanza di Random(),
se hai più istanze di random non hai più la garanzia di univocità nelle
serie generate.
Siccome è previsto l'uso della medesima istanza di random da parte di +
thread(per i motivi che ti ho esposto sopra) il metodo che genera il numero
successivo nella sequenza è già sync e non devi aggiungere nessuna
sicronizzazione nel tuo codice(vedi javadoc):
protected synchronized int next(int bits){...}
tutti gli altri metodi chiamano questo metodo.


grazie mille
