Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 11
  1. #1

    [Java] Generatore di numeri primi in Java

    Ciao a tutto il forum!

    Sto avendo un problema con un programma che dovrebbe generare numeri primi della grandezza in bit inserita dall'utente, ma durante la compilazione viene riscontrato il seguente problema:
    "the field BigInteger.TWO is not visible"

    in relazione alla linea di codice:
    r=BigInteger.TWO.multiply(i).multiply(t).add(BigIn teger.ONE);

    Qualcuno saprebbe spiegarmi dov'è il probelema?

    Grazie mille!


    questo il programma completo:

    codice:
    import java.security.*;
    import java.math.*;
    import java.util.*;
    
    /**
    * Permette di ottenere un numero primo.
    * */
    
    public class PrimeGenerator {
    
    //Per trovare numeri primi, bisogna specificare la lunghezza minima di quest'ultimi in //bit
       int minBitLength;
    
    //Numero di test di primalistà
       int certainty;
    
       SecureRandom sr;
    
    
    /**
    * Costruttore
    * @param minBitLength di tipo int, rappresenta lunghezza minima in termini
    di bit del numero primo
    * @param certainty di tipo int, rappresenta il numero di tentativi
    * @param sr di tipo SecureRandom, rappresenta l'oggetto che permette di
    generare numeri casuali
    * @exception, nel caso in cui si cerchi di instanziare un numero primo
    minore di 64 byte
    * */
    
    public PrimeGenerator(int minBitLength, int certainty, SecureRandom sr) {
       if (minBitLength<512)
       throw new IllegalArgumentException("Un numero primo sicuro deve essere composto almeno da 64 byte.");
    
    //Associa i valori
       this.minBitLength=minBitLength;
       this.certainty=certainty;
       this.sr=sr;
       }
    
    
    /**
    * @return Restituisce un numero primo sicuro
    * */
    
    public BigInteger getStrongPrime() {
    
    //Il numero primo p sarà tale che p+1 sia composto da un grande fattore s
       BigInteger s = new BigInteger(minBitLength/2-8,certainty,sr);
    //t will be a large prime factor of r, which follows
    //t sarà un grande fattore di r
       BigInteger t=new BigInteger(minBitLength/2-8,certainty,sr);
       BigInteger i=BigInteger.valueOf(1);
    //p-1 avrà un grande fattore r
    //r sarà il primo numero nella sequenza 2t+1, 2*2t+1, 2*3t+1,...
       BigInteger r;
       do {
           r=BigInteger.TWO.multiply(i).multiply(t).add(BigInteger.ONE);
           i=i.add(BigInteger.ONE);
       } while (!r.isProbablePrime(certainty));
       
       BigInteger z=s.modPow(r.subtract(BigInteger.TWO),r);
       BigInteger
       pstar=BigInteger.TWO.multiply(z).multiply(s).subtract(BigInteger.ONE);
       BigInteger k=BigInteger.valueOf(1);
    
    //Il numero primo p è il primo nella sequenza 2rs+p*, 2*2rs+p*, 2*3rs+p*,...
       BigInteger p=BigInteger.TWO.multiply(r).multiply(s).add(pstar); 
       while (p.bitLength()<=minBitLength) {
       k=k.multiply(BigInteger.TWO);
       p=BigInteger.TWO.multiply(k).multiply(r).multiply(s).add(pstar);
       }
    
       while (!p.isProbablePrime(certainty)) {
       k=k.add(BigInteger.ONE); 
       p=BigInteger.TWO.multiply(k).multiply(r).multiply(s).add(pstar);
       }
    
       return p;
    }
    
    
    /**
    * @return un primo sicuro da 2rt+1 dove t è un grande primo
    * */
    
    public BigInteger getSafePrime() {
       BigInteger p;
       BigInteger r=BigInteger.valueOf(0x7fffffff);
       BigInteger t=new BigInteger(minBitLength-30,certainty,sr);
    
    //Il numero primo p è il primo nella sequenza 2rt+1, 2*2rt+1, 2*3rt+1,...
       do {
       r=r.add(BigInteger.ONE);
       p=BigInteger.TWO.multiply(r).multiply(t).add(BigInteger.ONE);
       } while (!p.isProbablePrime(certainty));
       
       return p;
    }
    
    
    
    
    
    /**
    * Restituisce un primo sicuro della forma 2rt+1 dove t è un grande primo
    * e la fattorizzazione di r è nota.
    * Inoltre restituisce un generatore per il primo sicuro.
    * @return un array di due elementi di tipo BigInteger[], il quale nella
    * posizione 0 c'è il numero primo, mentre nella posizione 1 c'è il suo
    * generatore.
    * */
    
       public BigInteger[] getSafePrimeAndGenerator() {
       BigInteger[] p=new BigInteger[2];
       BigInteger r=BigInteger.valueOf(0x7fffffff);
       BigInteger t=new BigInteger(minBitLength-30,certainty,sr);
    
    //p è il numero primo nella sequenza 2rt+1, 2*2rt+1, 2*3rt+1,...
       do {
       r=r.add(BigIntegerMath.ONE);
       p[0]=BigIntegerMath.TWO.multiply(r).multiply(t).add(BigIntegerMath.ONE);
       } while (!p[0].isProbablePrime(certainty));
    
    //Bisogna ottenere i fattori primi da p-1=2rt
    //Inseriammo i fattori primi, presi una sola volta, in un Vector
    Vector factors=new Vector();
    
    //Aggiungiamo t nel vettore, ove t è un fattore primo di p-1=2rt
    factors.addElement(t);
    
    //Sappiamo che 2 è un fattore di p-1=2rt, così aggiungiamo 2 al vettore
    factors.addElement(BigInteger.valueOf(2));
    
    //r potrebbe non essere un fattore
    if (r.isProbablePrime(10))
    factors.addElement(r);
    
    //diversamente, cerca i fattori di r e lo aggiungiamo al vettore
    else {
    
    //Riduce dutti e due i fattori di r e li aggiunge al vettore
       while (r.mod(BigIntegerMath.TWO).equals(BigIntegerMath.ZERO)) {
       r=r.divide(BigIntegerMath.TWO);
       }
    
    //Otteniamo ora i fattori primi di r, i quali dovrebbero essere sufficientemente piccoli
    //partiamo con 3 - 2 che sono già nel vettore
    
    BigInteger divisor=BigInteger.valueOf(3);
    BigInteger square=divisor.multiply(divisor);
       
    while (square.compareTo(r)<=0) {
    //se questi divide r, lo aggiungiamo al vettore
    if (r.mod(divisor).equals(BigIntegerMath.ZERO)) {
    factors.addElement(divisor);
    
    //Riduce il divisore
    while (r.mod(divisor).equals(BigIntegerMath.ZERO))
    r=r.divide(divisor);
    }
    
    divisor=divisor.add(BigIntegerMath.ONE);
    square=divisor.multiply(divisor);
    }
    }
    
    //Ora, partiamo con la ricerca del generatore
    boolean isGenerator;
    BigInteger pMinusOne=p[0].subtract(BigIntegerMath.ONE);
    BigInteger x,z,lnr;
    
    do {
    //Ipotiziamo che il vaore di test sia un generatore
    isGenerator=true;
    
    //Scegliamo un piccolo intero casuale x più piccolo del primo p
    x=new BigInteger(p[0].bitLength()-1,sr);
    for (int i=0;i<factors.size();i++) {
    
    //Calcoliamo z come p-1 dividendo con l'i-esimo fattore primo nel vettore
    z=pMinusOne.divide((BigInteger)factors.elementAt(i));
    
    //Calcoliamo x^z(mod p)
    lnr=x.modPow(z,p[0]);
    
    //Se questi è pari ad 1, non è un generatore
    if (lnr.equals(BigIntegerMath.ONE)) {
    isGenerator=false;
    
    //Cerchiamo un nuovo generatore
    break;
    }
    }
    
    //Finche x non è un generatore, ritorniamo indietro e generiamo un nuovo x
    } while (!isGenerator);
    
    //Abbiamo trovato un insieme di generatori, e li restituiamo
    p[1]=x;
    return p;
    }
    }

  2. #2
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,320

    Moderazione

    Alcune semplici informazioni:

    1) Java ha un forum dedicato: Java

    2) Quando si posta del codice, si devono usare gli appositi tag CODE (da scrivere a mano)
    [CODE]
    codice
    [/CODE]

    In modo da rendere leggibile il codice (mantenimento della formattazione e dell'indentazione... non che il tuo codice sia particolarmente ben indentato, anzi...).

    Sposto la discussione e metto io i tag CODE.

    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  3. #3
    Utente di HTML.it
    Registrato dal
    Nov 2009
    Messaggi
    755
    mmm mi spieghi la field "BigInteger.TWO" da dove l'hai presa?Sulla documentazione ufficiale (link ) non esiste...

    EDIT:
    BigInteger.TWO è "private" quindi non accessibile dall'esterno

  4. #4
    Quindi in cosa dovrei modificarlo per non perdere l'operazione che il codice dovrebbe eseguire?

  5. #5
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,320
    Originariamente inviato da alexwroma
    Quindi in cosa dovrei modificarlo per non perdere l'operazione che il codice dovrebbe eseguire?
    Mi sembra banale... invece di usare l'oggetto BigInteger.TWO (che è privato e non è accessibile), costruisciti un tuo oggetto BigInteger che valga 2...

    codice:
    BigInteger due = new BigInteger(2);
    e sostituisci "due" ovunque tu abbia usato BigInteger.TWO.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  6. #6
    Il fatto è che sto cercando di riutilizzare questo codice che non è mio, e finora ho sempre e solo programmato in C++ e non in Java: diciamo che sto facendo una corsa contro il tempo...

    Ho effettuato le modiche che mi hai detto, ma dopodichè mi riporta la stessa problematica per i valori "ONE" e "ZERO", ma effettuando simili modifiche questa volta non va, e l'errore non scompare.

    E' possibile che il codice è stato scritto in una versione veramente vecchia di Java, in cui c'era la possibilità di usare la classe BigInteger in questo modo...?

    Se qualcuno mi aiutasse ad avere un codice fully runnable a partire da quello postato, gliene sarei infinitamente grato... (mi serve generare i primi per poi poter fare dei test di sisteme sui tempi impiegati dai vari algoritmi crittografici, quindi diciamo che il programma in questione è solo un mezzo e non il fine, ma cmq mi è indispensabile! ).

    Thanks!

  7. #7
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,320
    Originariamente inviato da alexwroma
    Ho effettuato le modiche che mi hai detto, ma dopodichè mi riporta la stessa problematica per i valori "ONE" e "ZERO", ma effettuando simili modifiche questa volta non va, e l'errore non scompare.
    No, BigInteger.ZERO e BigInteger.ONE sono pubblici e accessibilissimi... loro non possono dare alcun problema.

    E' possibile che il codice è stato scritto in una versione veramente vecchia di Java, in cui c'era la possibilità di usare la classe BigInteger in questo modo...?
    Non per quanto riguarda il problema di BigInteger.ZERO e BigInteger.ONE che ci sono praticamente da sempre e sono rimaste invariate.

    Se qualcuno mi aiutasse ad avere un codice fully runnable a partire da quello postato, gliene sarei infinitamente grato... (mi serve generare i primi per poi poter fare dei test di sisteme sui tempi impiegati dai vari algoritmi crittografici, quindi diciamo che il programma in questione è solo un mezzo e non il fine, ma cmq mi è indispensabile! ).
    Thanks!
    Questo tipo di richieste, però, non sono ammesse su questo forum. Lo sviluppo di codice (o l'adattamento di codice altrui) è un lavoro non da poco e queste richieste trovano spazio nel forum "Offro Lavoro / Collaborazione".

    Il mio consiglio è quello di effettuare la sostituzione che ho suggerito prima ed, eventualmente, postare i nuovi errori ottenuti.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  8. #8
    Ok, grazie per il tuo aiuto, allora ti provo a scrivere i tentativi che ho fatto...

    come mi hai consigliato ho creato l'oggetto ed inserito all'inizio del metodo, ma mi viene restituito questo messaggio di errore:
    "The constructor BigInteger(long) is not visible"

    Ho sbagliato a posizionarlo, o cosa?

    Grazie!

    codice:
    /**
    * @return Restituisce un numero primo sicuro
    * */
    
    public BigInteger getStrongPrime() {
    
    BigInteger due = new BigInteger(2);
    
    //Il numero primo p sarà tale che p+1 sia composto da un grande fattore s
    BigInteger s = new BigInteger(minBitLength/2-8,certainty,sr);
    //t will be a large prime factor of r, which follows
    //t sarà un grande fattore di r
    BigInteger t=new BigInteger(minBitLength/2-8,certainty,sr);
    BigInteger i=BigInteger.valueOf(1);
    //p-1 avrà un grande fattore r
    //r sarà il primo numero nella sequenza 2t+1, 2*2t+1, 2*3t+1,...
    BigInteger r;
    do {
    r=BigInteger.TWO.multiply(i).multiply(t).add(BigInteger.ONE);
    i=i.add(BigInteger.ONE);
    } while (!r.isProbablePrime(certainty));
    BigInteger z=s.modPow(r.subtract(BigInteger.TWO),r);
    BigInteger
    pstar=BigInteger.TWO.multiply(z).multiply(s).subtract(BigInteger.ONE);
    BigInteger k=BigInteger.valueOf(1);
    
    //Il numero primo p è il primo nella sequenza 2rs+p*, 2*2rs+p*, 2*3rs+p*,...
    BigInteger p=BigInteger.TWO.multiply(r).multiply(s).add(pstar);
    while (p.bitLength()<=minBitLength) {
    k=k.multiply(BigInteger.TWO);
    p=BigInteger.TWO.multiply(k).multiply(r).multiply(s).add(pstar);
    }
    while (!p.isProbablePrime(certainty)) {
    k=k.add(BigInteger.ONE);
    p=BigInteger.TWO.multiply(k).multiply(r).multiply(s).add(pstar);
    }
    return p;
    }
    BigInteger due = new BigInteger(2);

  9. #9
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,320
    Sì, ma devi anche dire a quale riga viene sollevato quell'errore... il compilatore te lo dice e tu dovresti riportarlo qui ed evidenziarcela (o provare a correggerla)... perchè non è di certo quella riga che solleva quell'errore. 2 è una costante intera, non long.

    Il messaggio d'errore è chiarissimo: stai cercando di invocare il costruttore di BigInteger passandogli un valore di tipo long, ma il costruttore che prevede un long, anche in questo caso, non è pubblico. Ti consiglio, inoltre, di dimenticarti per un momento il sorgente della classe BugInteger: è chiaro che la lettura di un sorgente Sun/Oracle è troppo complessa per le tue attuali conoscenze... limitati ad usare ciò che la Documentazione di BigInteger espone.

    E in ogni caso, nel codice che hai postato, continui ad usare BigInteger.TWO, nonostante ti abbia detto di sostituire quelle chiamate con il riferimento a "due".

    Terza cosa... elimina l'ultima riga (quella in rosso)... è al di fuori della classe (o così mi pare), e ciò è errato.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  10. #10
    compare a fianco di ogni linea una "x con una lampadina" se sposto il cursore sopra mi dice di che errore si tratta.

    Tale lampadina compare sulla dichiarazione del "BigInteger due=..." e su tutte le linee di codice successive in cui vi è "TWO" che poi abbiamo sostituito con "due"...


Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.