Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 12
  1. #1
    Utente di HTML.it
    Registrato dal
    Mar 2006
    Messaggi
    208

    Generazione automatica seriale 4 cifre

    Salve,
    vorrei implementare un sistema di generazione automatica di seriali progressivi alfanumerici di 4 cifre (ma immagino che questo parametro cambi poco nella soluzione).

    Riflettendoci, ho capito che probabilmente mi manca qualche strumento PHP per la soluzione.

    1) Il sistema dovrebbe ricavare i seriali già usati tramite query.
    2) Sulla base di questo generare il primo disponibile tramite funzione (max) di Mysql.

    E fin qui tutto ok.

    Il problema sorge sul modello da usare.

    Tecnicamente il modello dovrebbe essere questo

    A000 -> A999 -> 0A00-> 9A99 ->00A0 ->99A9 -> 000A -> 999A -> B000 e così via.

    Dalla serie principale verrebbero escluse le lettere J-K-X-Y-W perchè il sistema dovrebbe assegnarle solo in caso di selezione di una determinata opzione in fase di input. Per questo blocco immagino che una volta agganciata la logica, potrò arrivarci da solo.

    Come posso indicargli il modo?

    Grazie grazie in anticipo per il tempo dedicato.

  2. #2
    Non mi e' chiara la progressione, perche' dopo A999 viene 0A00? Non dovrebbe venire A99A?

    Comunque PHP offre la comoda funzione base_convert() che ti permette di convertire numeri in basi arbitrarie. Per basi maggiori di 10 vengono usati caratteri alfabetici, e la base massima e' 36. Contando che tu usi tutto l'alfabeto ti serve appunto base 36, quindi se hai la stringa alfanumerica la converti in decimale, la incrementi e la riconverti in stringa, esempio:

    Codice PHP:
    $string 'a999';
    $decimal base_convert($string3610);
    $number $decimal 1;
    $new_string base_convert($number1036);

    echo 
    $new_string"\n"

  3. #3
    Utente di HTML.it
    Registrato dal
    Mar 2006
    Messaggi
    208
    Uhm non so se questa soluzione va bene, in realtà come ti dicevo non uso tutto l'alfabeto, dovendo filtrare le lettere speciali. Però ho capito il senso. In pratica l'a999 in questione sarebbe il dato (max) proveniente da query e $number aggiunge 1.

    Sorge un ulteriore problema: causa gestione dissennata della parte tecnica negli anni (non mi compete questo disastro per fortuna), purtroppo nel db non ho valori sempre a 4 cifre. E non posso intervenire per modificare questa cosa in alcun modo poichè a quei valori corrisponde anche un archivio cartaceo tuttora presente che andrebbe riallineato, la cosa è semplicemente folle solo a pensarla. Semplicemente io da oggi devo proseguire sul criterio delle 4 cifre che è già stato comunque utilizzato per qualche tempo, tenendo presente che nel db ho anche seriali da 5 per una parte dei records. Questo chiaramente mi ha costretto ad impostare anche la lunghezza del carattere a db a 5 e non a 4...quindi non ho neanche a disposizione il controllo sulla lunghezza di Mysql.

    Credo che la soluzione quindi debba obbligatoriamente passare per una specifica del formato alfanumerico a 4 lettere tramite php

  4. #4
    Per il fatto delle lettere ad uso limitato, tu generi il nuovo codice incrementando il numero vecchio, se contiene quelle lettere e non e' il caso di usarle, lo scarti e passi al successivo. Sempre se ho capito il problema.

    Per il resto non mi e' chiara la questione. Tu hai uno storico incasinato e ok, pero' ad un certo punto avrai un id da cui cominci a lavorare tu nel nuovo formato, in altre parole l'ultimo dei "vecchi" id e tuo punto di partenza. Prendi quello e consideri che tutti i nuovi id debbano essere maggiori, o mi sono perso qualcosa?

  5. #5
    Utente di HTML.it
    Registrato dal
    Mar 2006
    Messaggi
    208
    No no non ti sei perso nulla. L'unica cosa è che la generazione della password dipenderà anche da una select effettuata dall'operatore in un campo specifico del pannello nuovo utente.

    Per capirci:
    a tipologia 1 verranno applicate tutti i seriali con lettera TRANNE quelli della tipologia 2
    a tipologia 2 verranno applicate le lettere speciali J,K,W,Y,Z.

    Non ho ben capito se con questo sistema c'è un effettivo workaround per escludere queste 5 lettere. Ad occhio mi è parso di capire di no, ma sicuramente è solo un mio limite di comprensione in questo momento

  6. #6
    No il sistema che ti ho indicato non fa altro che generare seriali incrementali senza nessun controllo sui caratteri. Pero' il problema non mi e' chiaro perche' ho alcuni dubbi:

    - i seriali devono comunque essere sempre sequenziali o quelli di tipologia 2 seguono un ordine separato? Cioe', se devo generare un seriale di tipologia 2 deve essere numericamente maggiore di tutti (tipologia 1 e 2) o solo di tipologia 2?
    - i seriali tipo 2 devono contenere almeno un carattere JKWYZ o solo quei caratteri?

  7. #7
    Utente di HTML.it
    Registrato dal
    Mar 2006
    Messaggi
    208
    No, i due gruppi separati seguono ciascuno per proprio conto il proprio ordine sequenziale.
    credo che specificherò lo switch in funzione tramite input utente. Oppure faccio uno switch in una funzione wrapper e divido il percorso in due function, li per li stabiliró l'opportuna forma.

    quanto al gruppo 2, in realtà pensandoci bene probabilmente dovrà essere che ci sia ALMENO uno di quei caratteri, mentre assolutamente nessuno di quelli nel gruppo 1. Credo che con questa distinzione, posto comunque un controllino di sicurezza generico prima del l'assegnazione, dovrei poter evitare duplicati a priori.
    Ultima modifica di Korenaar; 19-11-2014 a 20:57

  8. #8
    Utente di HTML.it L'avatar di badaze
    Registrato dal
    Jun 2002
    residenza
    Lyon
    Messaggi
    5,344
    Non tiene conto delle tipologie. Appena testato, non ottimizzato.

    Codice PHP:
    <?php 
    class baseX {
     
    //===== Trova la posizione della lettera
     
    private function charPosition($code) {
      
    $len strlen($code);
      
    $ind 0;
      
    $pos = -1;
      while (
    $ind $len) {
        if (!
    is_numeric(substr($code,$ind,1))) {
       
    $pos $ind;
     }
     
    $ind++;
      } 
    // while ($ind < $len)
      
    if ($pos == -1) {
       return 
    null;
      } else {
       return 
    $pos;
      } 
    // if ($pos == -1)
     
    // function decodeX($code)
     //===== decodifica un numero codificato in base 10
     
    function decodeBaseX($code) {
      
    $pos $this->charPosition($code);
      if ( 
    $pos === null) {
        return 
    null;
      } 
    // if ($this->charPosition($code) === null)
      
    $letter substr($code,$pos,1); 
      
    $resto  str_replace($letter,'',$code);
      
    $th     ord($letter) - 65;
      return (
    $th 4000) + ($pos  1000) + $resto;
     } 
    // function decodeBaseX($code) 
     
     //===== codifica un numero in base 10 
     
    function codeBaseX($number) {
      if (
    $this->charPosition($number) !== null) {
        return 
    null;
      } 
    // if ($this->charPosition($number) !== null)
      
      
    $th     = (int) ($number 1000);
      
    $resto  $number - ($th 1000);
      
    $restoF str_repeat('0',3-strlen($resto)).$resto;
      
    $tx     = (int) ($th 4);
      
    $pos    $th 4;
      
    $letter chr(65+$tx);
     
      if (
    $pos == 0) {
       
    $return $letter.$restoF;
      } else {
       if (
    $pos == 1) {
         
    $return substr($restoF,0,1).$letter.substr($restoF,1,2);
       } else {
         if (
    $pos == 2) {
        
    $return substr($restoF,0,2).$letter.substr($restoF,2,1);
      } else {
        
    $return $restoF.$letter;
      } 
    // if ($pos == 2)
       
    // if ($pos == 1)
      
    // if ($pos == 0) 
      
    return $return;
     } 
    // function codeBaseX($number) 
     //===== aggiunge due "numeri" 
     
    function add($element1,$element2) {
       if (
    $this->charPosition($element1) === null) {
        
    $add_element1 $element1;
       } else {
        
    $add_element1 $this->decodeBaseX($element1);
       } 
    // if (charPosition($element1) === null)
       
       
    if ($this->charPosition($element2) === null) {
        
    $add_element2 $element2;
       } else {
        
    $add_element2 $this->decodeBaseX($element2);
       } 
    // if (charPosition($element2) === null) 
       
    $inter $add_element1 $add_element2;
       
    //PRINT $inter;
       
    return $this->codeBaseX($inter);
     } 
    // function add($element1,$element2)
     
    // class baseX
    $a = new baseX();
    print 
    "Code :<br/>";
    print 
    $a->codeBaseX(15)."<br/>";
    print 
    $a->codeBaseX(999)."<br/>";
    print 
    $a->codeBaseX(3400)."<br/>";
    print 
    $a->codeBaseX(1999)."<br/>";
    print 
    $a->codeBaseX(2000)."<br/>";
    print 
    $a->codeBaseX(3000)."<br/>";
    print 
    $a->codeBaseX(4000)."<br/>";
    print 
    $a->codeBaseX(5000)."<br/>";
    print 
    "Decode :<br/>";
    print 
    $a->decodeBaseX('4D00')."<br/>";
    print 
    $a->decodeBaseX('8P99')."<br/>";
    print 
    "Add :<br/>";
    for (
    $i=0;$i<100;$i++) {
      print  
    $a->add('9D50',$i)."<br/>";
    // for ($i=0;$i<100;$i++) 
    print $a->codeBaseX(17128)."<br/>";
    print 
    $a->decodeBaseX('25I6')."<br/>";
    print 
    $a->add('1E28','1E28');
    ?>
    Ridatemi i miei 1000 posts persi !!!!
    Non serve a nulla ottimizzare qualcosa che non funziona.
    Cerco il manuale dell'Olivetti LOGOS 80B - www.emmella.fr

  9. #9
    Utente di HTML.it L'avatar di badaze
    Registrato dal
    Jun 2002
    residenza
    Lyon
    Messaggi
    5,344
    Con le tipologie. Potenza dell'OOP.

    Codice PHP:
    <?php 
    class baseX {
     protected 
    $arrChr = array('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','Q','T','U','V','W','X','Y','Z');
     protected 
    $arrOrd;
     function 
    __construct() {
       
    $this->arrOrd array_flip($this->arrChr);
     } 
    // function __construct()
     
     //===== Ordine della lettera 
     
    private function ordL($letter) {
        
    $temp $this->arrOrd[$letter];
     return 
    $temp;
     } 
    // private function ordL($letter)
     
     //===== Carattere del numero 
     
    private function chrL($numero) {
        
    $temp $this->arrChr[$numero];
     return 
    $temp
     } 
    // private function chrL($numero)
     
     //===== Trova la posizione della lettera
     
    private function charPosition($code) {
      
    $len strlen($code);
      
    $ind 0;
      
    $pos = -1;
      while (
    $ind $len) {
        if (!
    is_numeric(substr($code,$ind,1))) {
       
    $pos $ind;
     }
     
    $ind++;
      } 
    // while ($ind < $len)
      
    if ($pos == -1) {
       return 
    null;
      } else {
       return 
    $pos;
      } 
    // if ($pos == -1)
     
    // function decodeX($code)
     //===== decodifica un numero codificato in base 10
     
    function decodeBaseX($code) {
      
    $pos $this->charPosition($code);
      if ( 
    $pos === null) {
        return 
    null;
      } 
    // if ($this->charPosition($code) === null)
      
    $letter substr($code,$pos,1); 
      
    $resto  str_replace($letter,'',$code);
      
    $th     $this->ordL($letter);
      return (
    $th 4000) + ($pos  1000) + $resto;
     } 
    // function decodeBaseX($code) 
     
     //===== codifica un numero in base 10 
     
    function codeBaseX($number) {
      if (
    $this->charPosition($number) !== null) {
        return 
    null;
      } 
    // if ($this->charPosition($number) !== null)
      
      
    $th     = (int) ($number 1000);
      
    $resto  $number - ($th 1000);
      
    $restoF str_repeat('0',3-strlen($resto)).$resto;
      
    $tx     = (int) ($th 4);
      
    $pos    $th 4;
      
    $letter $this->chrL($tx);
     
      if (
    $pos == 0) {
       
    $return $letter.$restoF;
      } else {
       if (
    $pos == 1) {
         
    $return substr($restoF,0,1).$letter.substr($restoF,1,2);
       } else {
         if (
    $pos == 2) {
        
    $return substr($restoF,0,2).$letter.substr($restoF,2,1);
      } else {
        
    $return $restoF.$letter;
      } 
    // if ($pos == 2)
       
    // if ($pos == 1)
      
    // if ($pos == 0) 
      
    return $return;
     } 
    // function codeBaseX($number) 
     //===== aggiunge due "numeri" 
     
    function add($element1,$element2) {
       if (
    $this->charPosition($element1) === null) {
        
    $add_element1 $element1;
       } else {
        
    $add_element1 $this->decodeBaseX($element1);
       } 
    // if (charPosition($element1) === null)
       
       
    if ($this->charPosition($element2) === null) {
        
    $add_element2 $element2;
       } else {
        
    $add_element2 $this->decodeBaseX($element2);
       } 
    // if (charPosition($element2) === null) 
       
    $inter $add_element1 $add_element2;
       return 
    $this->codeBaseX($inter);
     } 
    // function add($element1,$element2)
     
    // class baseX


    class baseX_tipo1 extends baseX {
     protected 
    $arrChr = array('A','B','C','D','E','F','G','H','I','L','M','N','O','P','Q','R','S','Q','T','U','V','W','X');
    // class baseX_tipo1 extends baseX


    class baseX_tipo2 extends baseX {
     protected 
    $arrChr = array('J','K','W','X','Z');
    // class baseX_tipo2 extends baseX


    $a = new baseX();
    print 
    "Code :<br/>";
    print 
    $a->codeBaseX(15)."<br/>";
    print 
    $a->codeBaseX(999)."<br/>";
    print 
    $a->codeBaseX(3400)."<br/>";
    print 
    $a->codeBaseX(1999)."<br/>";
    print 
    $a->codeBaseX(2000)."<br/>";
    print 
    $a->codeBaseX(3000)."<br/>";
    print 
    $a->codeBaseX(4000)."<br/>";
    print 
    $a->codeBaseX(5000)."<br/>";
    print 
    "Decode :<br/>";
    print 
    $a->decodeBaseX('4D00')."<br/>";
    print 
    $a->decodeBaseX('8P99')."<br/>";
    print 
    "Add :<br/>";
    for (
    $i=0;$i<100;$i++) {
      print  
    $a->add('9D50',$i)."<br/>";
    // for ($i=0;$i<100;$i++) 
    print $a->codeBaseX(17128)."<br/>";
    print 
    $a->decodeBaseX('25I6')."<br/>";
    print 
    $a->add('1E28','1E28')."<br/>";
    print 
    "<hr/>";


    print 
    "Tipologia 1 :<br/>";
    $b = new baseX_tipo1();
    print 
    $b->codeBaseX(999)."<br/>";
    print 
    "<hr/>";


    print 
    "Tipologia 2 :<br/>";
    $c = new baseX_tipo2();
    print 
    $c->codeBaseX(999)."<br/>";
    ?>
    Ridatemi i miei 1000 posts persi !!!!
    Non serve a nulla ottimizzare qualcosa che non funziona.
    Cerco il manuale dell'Olivetti LOGOS 80B - www.emmella.fr

  10. #10
    Utente di HTML.it
    Registrato dal
    Mar 2006
    Messaggi
    208
    Mamma mia, sei andato decisamente oltre ogni mia aspettativa.

    Fammi capire:
    - le classi base_tipo1 e tipo2 praticamente vanno a sostituire l'array di valori permessi estendendo la classe base.
    - il metodo charposition($code) praticamente controlla se ogni carattere della stringa passata è numerico parsando le singole posizioni e facendo questo fintanto che l'indice è minore della lunghezza.
    - il resto di codebaseX() mi resta vagamente oscuro passo per passo (così come decodebasex(), sono i due metodi per cifra->numero o numero->cifra), ma mi pare di aver capito che è il motore di generazione del codice tramite vari passaggi che vanno a chiamare le lettere permesse nell'array $arrChr e ricorrendo questa selezione nel caso in cui il controllo risulti nullo.


    Non so se tutto questo che ho scritto è giusto, ma la domanda che ora mi sorge è una:
    partendo dal presupposto che tecnicamente questo sistema dovrebbe partire dal controllo dei seriali già presenti (o in alternativa per logica, dovrebbe generare un codice PER POI controllare se esiste), io che parametro gli passo esattamente? Qui vedo che fai dei tentativi con una serie di numeri/codici arbitrari. Cosa gli imposto? questo passaggio mi manca proprio.

    Grazie intanto, sei stato pazzesco.

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 © 2024 vBulletin Solutions, Inc. All rights reserved.