Go Down

Topic: Generare un numero casuale dato un seme (Read 928 times) previous topic - next topic

mounes

Per ora provo lo sketch, poi mi "cervellerò" con il boot.  :)

Grazie cmq per l'avvertimento.

mounes

Purtroppo qualcosa non va... è tutto il pomeriggio che provo ma non so veramente cosa non vada. Potete aiutarmi?!

Code: [Select]
// Inizializzazione

// definisco il pin associato al pulsante di START

const int buttonStart = 7;

// definisco i pin del DIP switch

const int SW1 = 14;
const int SW2 = 15;
const int SW3 = 16;
const int SW4 = 17;
const int SW5 = 18;
const int SW6 = 19;

// definisco i pin dei segmenti del Display LED

const int A = 12;  // pin che controllano i segmenti delle cifre
const int B = 8;
const int C = 4;
const int D = 2;
const int E = 1;
const int F = 11;
const int G = 5;
const int DP = 3;

const int DIG1 = 13;  // pin che controllano le singole cifre
const int DIG2 = 10;
const int DIG3 = 9;
const int DIG4 = 6;

// definisco il tipo dei pin

void setup(){
 
  pinMode(buttonStart, INPUT_PULLUP);
 
  pinMode(SW1, INPUT);
  pinMode(SW2, INPUT);
  pinMode(SW3, INPUT);
  pinMode(SW4, INPUT);
  pinMode(SW5, INPUT);
  pinMode(SW6, INPUT);
 
  pinMode(A, OUTPUT);
  pinMode(B, OUTPUT);
  pinMode(C, OUTPUT);
  pinMode(D, OUTPUT);
  pinMode(E, OUTPUT);
  pinMode(F, OUTPUT);
  pinMode(G, OUTPUT);
  pinMode(DP, OUTPUT);

  pinMode(DIG1, OUTPUT);
  pinMode(DIG2, OUTPUT);
  pinMode(DIG3, OUTPUT);
  pinMode(DIG4, OUTPUT);

}

int buttonState = 0;  // definisco una variabile per controllare lo stato del pulsante di START

void loop(){
 
  buttonState = digitalRead(buttonStart);  // legge lo stato del pulsante di START

  if (buttonState == LOW){
   
   // operazione che legge i bit del DIP switch e crea il seed
   
   byte seed; // variabile che otterò e manderò a randomSeed() per generare la one time password
   byte seedArray [8]={SW1,SW2,SW3,SW4,SW5,SW6,0,0}; // variabile array in cui associo i pin del DIP switch
   
   seed = 0;  // setto tutti i bit a 0
   for (int i = 0; i<8; i++){  // leggo lo stato di ogni pin del Dip switch e se è HIGH setto a 1 il bit del seed di quella data posizione
    if (digitalRead(seedArray [i]) == HIGH){
         bitSet(seed, i);
         
         // TEST: visualizzo allo shermo del pc i bit del seed e quest'ultimo in forma decimale
         Serial.begin(9600);
         Serial.print(seedArray [i], BIN);
         Serial.print(seed, DEC);
         Serial.print("\t");
         
    }
   }
   
  // generazione dellala one time password

  int otp;  // variabile in cui verrà salvata la one time password

  randomSeed(seed);  // inizializzo la funzione random che genererà la one time password
  otp = random(10000);  // dato che ho un display a 4 cifre potrò visualizzare solo un numero tra 0 e 9999

  // TEST: visualizzo allo schermo del pc la one time password
  Serial.begin(9600);
  Serial.print(otp);

  showDigits(otp);
 
  delay (5000);  // visualizzo la one time password per 5 secondi, prima di spegenere il Display LED
 
  digitalWrite(DIG1, LOW);
  digitalWrite(DIG2, LOW);
  digitalWrite(DIG3, LOW);
  digitalWrite(DIG4, LOW);
 
  delay (1);
 
  }
}

// definisco la funzione per visualizzare un numero da 0 a 9 in base alla cifra ricevuta

void showDigit (int digit){

   digitalWrite(A, HIGH);  // spengo tutti i LED della cifra (nel caso ad anodo comune si pongono i pin HIGH)
   digitalWrite(B, HIGH);
   digitalWrite(C, HIGH);
   digitalWrite(D, HIGH);
   digitalWrite(E, HIGH);
   digitalWrite(F, HIGH);
   digitalWrite(G, HIGH);
   digitalWrite(DP, HIGH);

  switch (digit) { 
   
   case 0:  //per ogni numero accenderò i relativi LED (nel caso ad anodo comune si pongono i pin LOW)

   digitalWrite(A, LOW);
   digitalWrite(B, LOW);
   digitalWrite(C, LOW);
   digitalWrite(D, LOW);
   digitalWrite(E, LOW);
   digitalWrite(F, LOW);

   break;

   case 1:
   
   digitalWrite(B, LOW);
   digitalWrite(C, LOW);

   break;

   case 2:

   digitalWrite(A, LOW);
   digitalWrite(B, LOW);
   digitalWrite(D, LOW);
   digitalWrite(E, LOW);
   digitalWrite(G, LOW);

   break;

   case 3:

   digitalWrite(A, LOW);
   digitalWrite(B, LOW);
   digitalWrite(C, LOW);
   digitalWrite(D, LOW);
   digitalWrite(G, LOW);

   break;

   case 4:

   digitalWrite(B, LOW);
   digitalWrite(C, LOW);
   digitalWrite(F, LOW);
   digitalWrite(G, LOW);

   break;

   case 5:

   digitalWrite(A, LOW);
   digitalWrite(C, LOW);
   digitalWrite(D, LOW);
   digitalWrite(F, LOW);
   digitalWrite(G, LOW);

   break;

   case 6:

   digitalWrite(A, LOW);
   digitalWrite(C, LOW);
   digitalWrite(D, LOW);
   digitalWrite(E, LOW);
   digitalWrite(F, LOW);
   digitalWrite(G, LOW);

   break;

   case 7:

   digitalWrite(A, LOW);
   digitalWrite(B, LOW);
   digitalWrite(C, LOW);

   break;

   case 8:

   digitalWrite(A, LOW);
   digitalWrite(B, LOW);
   digitalWrite(C, LOW);
   digitalWrite(D, LOW);
   digitalWrite(E, LOW);
   digitalWrite(F, LOW);
   digitalWrite(G, LOW);

   break;

   case 9:

   digitalWrite(A, LOW);
   digitalWrite(B, LOW);
   digitalWrite(C, LOW);
   digitalWrite(D, LOW);
   digitalWrite(F, LOW);
   digitalWrite(G, LOW);

   break;

   default:

   break;

}
}

// funzione per visualizzare le 4 cifre su Display LED

void showDigits (int digits){

  showDigit (digits/1000);  // mi restituisce solo la prima cifra (partendo da sinistra)
  digitalWrite(DIG1, HIGH); // accende solo la prima cifra (nel caso ad anodo comune si pone il pin HIGH)
  digitalWrite(DIG2, LOW);
  digitalWrite(DIG3, LOW);
  digitalWrite(DIG4, LOW);

  delay (1);  // ritardo di 1 ms prima di passare alla cifra successiva

  digits = digits%1000;  // mi restituisce solo la seconda cifra (partendo da sinistra)
  digitalWrite(DIG1, LOW);
  showDigit(digits/100);
  digitalWrite(DIG2, HIGH);

  delay (1);

  digits = digits%100;  // mi restituisce solo la terza cifra (partendo da sinistra) 
  digitalWrite(DIG2, LOW);
  showDigit(digits/10);
  digitalWrite(DIG3, HIGH);

  delay (1);

  digits = digits%10;  // mi restituisce solo la quarta cifra (partendo da sinistra)
  digitalWrite(DIG3, LOW);
  showDigit(digits);
  digitalWrite(DIG4, HIGH);

  delay (1);  // grazie ad ogni piccolo ritardo sì ha l'effetto che le cifre si accendano tutte contemporaneamente

}

mounes

#17
Jul 22, 2014, 11:40 am Last Edit: Jul 22, 2014, 04:44 pm by mounes Reason: 1
Scusate, la mia domanda era troppo generica... cmq non mi visualizzava correttamente il numero, ora lo visualizza ma per un atimo e rimane accesa solo l'ultima cifra.

Ho capito che devo modificare l'ultima funzione che ho scritto "showDigits", devo sfruttare un ciclo for o lo switch case? (è tutto i lgiorno che ci lavoro) :P

mounes

Ho risolto la visualizzazione del display led a 4 cifre, se può servire a qualcuno:

Code: [Select]
void showDigits (int digits){
 
  int temp; // variabile in cui salvo temporaneamente il resto della one time password per determinare di quante cifre è composta
 
  // definisco le variabili in cui salverò le migliaia, centinaia, decine ed unità della one time password
 
  int thousand = digits/1000;
  temp = digits%1000;
  int hundred = temp/100;
  temp = temp%100;
  int ten = temp/10 ;
  temp = temp%10;
  int unit = temp;
 
  // ciclo che determina la visualizzazione delle singole cifre
 
  if (thousand == 0){
    if (hundred == 0){
      if (ten == 0){  // accende solo la cifra delle unità (nel caso ad anodo comune si pone il pin HIGH)
        digitalWrite(DIG1, LOW);
        digitalWrite(DIG2, LOW);
        digitalWrite(DIG3, LOW);
        digitalWrite(DIG4, HIGH);
showDigit (unit);                
        delay(5);
      }
      else {  // accende la cifra delle decine e delle unità
        digitalWrite(DIG1, LOW);
digitalWrite(DIG2, LOW);
digitalWrite(DIG3, HIGH);
showDigit (ten);
delay(5);
        digitalWrite(DIG3, LOW);
digitalWrite(DIG4, HIGH);
showDigit (unit);
delay(5);
digitalWrite(DIG4, LOW);
      }
    }
    else{  // accende la cifra delle centinaia, delle decine e delle unità
      digitalWrite(DIG1, LOW);
      digitalWrite(DIG2, HIGH);
      showDigit(hundred);
      delay(5);
      digitalWrite(DIG2, LOW);
      digitalWrite(DIG3, HIGH);
      showDigit(ten);
      delay(5);
      digitalWrite(DIG3, LOW);
      digitalWrite(DIG4, HIGH);
      showDigit(unit);
      delay(5);
      digitalWrite(DIG4, LOW);
    }
  }
  else{  // accende la cifra delle migliaia, delle centinaia, delle decine e delle unità
    digitalWrite(DIG1, HIGH);
    showDigit(thousand);
    delay(5);
    digitalWrite(DIG1, LOW);
    digitalWrite(DIG2, HIGH);
    showDigit(hundred);
    delay(5);
    digitalWrite(DIG2, LOW);
    digitalWrite(DIG3, HIGH);
    showDigit(ten);
    delay(5);
    digitalWrite(DIG3, LOW);
    digitalWrite(DIG4, HIGH);
    showDigit(unit);
    delay(5);
    digitalWrite(DIG4, LOW);
  }
}

mounes

Rieccomi, spero qualcuno possa aiutarmi, ho quasi finito il mio progetto, ma ho un problema nella generazione del numero random ovvero se gli passo un seed di soli 0 mi genera bene una sequenza random ogni volta che premo il pulsante ma se pongo almeno un bit del seed ad 1 premendo il pulsante ottengo sempre lo stesso numero.
Aiutatemi perfavore non so prorpio come risolverlo.  :~

Code: [Select]
void loop(){
 
  buttonState = digitalRead(buttonStart);  // legge lo stato del pulsante di START

  if (buttonState == LOW){
   
   // operazione che legge i bit del DIP switch e crea il seed 
   
   int dipArray [6]={SW6,SW5,SW4,SW3,SW2,SW1}; // variabile array in cui associo i pin del DIP switch
   int seedArray [8]={0,0,0,0,0,0,0,0};  // variabile array in cui salvo i valori dei pin
   int val = 0;
   for (int j=0; j<6; j++){
     val = digitalRead(dipArray [j]);
      if (val > 0){
       seedArray [j+2] = 1;
     }
   }
       
   byte seed; // variabile che otterò e manderò a randomSeed() per generare la one time password     
   seed = 0;  // setto a 0 tutti i bit
   for (int i = 0; i<8; i++){  // leggo lo stato di ogni pin del Dip switch e se è HIGH setto a 1 il bit del seed di quella data posizione
    if (seedArray [i] == 1){
         bitSet(seed, i);
        }
   }
   

   
   Serial.begin(9600);
   Serial.print("\t");
   Serial.println("Bit del Seed");
 
   
   for (int k = 0; k<8; k++){
   // TEST: visualizzo allo shermo del pc i bit del seed e quest'ultimo in forma decimale
         Serial.begin(9600);
         Serial.print("\t");
         Serial.print(bitRead(seed, k));
         Serial.print("\t");
   }

  // generazione dellala one time password

  int otp;  // variabile in cui verrà salvata la one time password
 
  randomSeed(seed);  // inizializzo la funzione random che genererà la one time password
  otp = random(10000);  // dato che ho un display a 4 cifre potrò visualizzare solo un numero tra 0 e 9999

  // TEST: visualizzo allo schermo del pc la one time password
  Serial.begin(9600);
  Serial.println("");
  Serial.print("\t");
  Serial.println("Seed in Decimale");
  Serial.print("\t");
  Serial.print(seed, DEC);
  Serial.println("");
  Serial.print("\t");
  Serial.println("One Time Password");
  Serial.print("\t");
  Serial.print(otp);
  Serial.println("");
 
  // visualizzo la one time password per circa 3 secondi, prima di spegenere il Display LED
 
  for (int t = 0; t<100; t++){ 
  showDigits(otp);
  }
 
  delay (5);
 
  }

simonenascivera

Forse sarebbe più "casuale" se prendessi un valore da un Pin analogico a cui non è collegato nulla poi o usi map per trasformarlo nel valore che vuoi così sei sicuro che ricevi un valore! =0

gpb01

Se poi usasse la libreria che gli ho suggerito QUI, e che lui ha completamente ignorato, sarebbe ancora meglio  ]:D ]:D ]:D

Guglielmo
Search is Your friend ... or I am Your enemy !

mounes

Ho risolto in un altro modo...  :P

Ora il mio prossimo passo è generare invece one time password. Ho trovato come algoritmo il SHA-1, ma non ho capito bene come potergli passare il seed e come scegliere il numero da concatenargli. Poi mi si pone il problema di dover ridurre la otp a un numero a 4 cifre per visualizzarlo su display LED.
Sapete suggerirmi qualche lavoro simile o darmi consiglio?

:)

mounes

Bene ho trovato la libreria da Cryptosuite dello SHA1 che da quello che ho capito in giro è più sicuro rispetto lo MD5:

https://github.com/Cathedrow/Cryptosuite/blob/master/Sha/sha1.h

Ora scusate la mia ignoranza ma è la prima volta che lavoro con gli algoritmi e le mie conoscenze di programmazione sono di base, quindi scusatemi se sto per fare delle domande sciocche:

1) ho incluso la libreria nel mio sketch, ma come si usa ovvero come si richiama la funzione?

2) la mia intenzione è generare one time password, come faccio a passargli il seed (1 byte) e il numero da cui partire?


leo72

1) Ho usato la CryptoSuite un paio d'anni fa, non ricordo bene.
Però la classe SHA è distribuita con degli esempi, hai provato a guardarne uno?

2) sei sicuro che ti serva una funzione di hashing? Una funzione di hashing come la SHA-1 restituisce una stringa a 128 bit che corrisponde alla somma di controllo dei dati passati alla funzione. Potresti forse usare la funzione così: passi un timestamp composto da data/ora e da quello calcoli l'hash con SHA-1. Siccome il tempo passa, non c'è possibilità (a meno di non passare la stessa combinazione di data/ora) di avere una somma di controllo identica ad un'altra. Questa potrebbe essere la tua password OTP. Però la cosa è un pò più complessa, forse dovresti tenere conto anche delle password generate in precedenza.
http://en.wikipedia.org/wiki/One-time_password

Go Up