How to generate a serial key that contains a prefix in the first 5 characters?

Asked

Viewed 1,768 times

7

I have a script in PHP that generates a "serial key", but I need this script to generate this "serial key" with a pattern at the beginning, as if it were a prefix.

The code I already have is:

<?php
$chars = array(0,1,2,3,4,5,6,7,8,9,'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z');
$serial = '';
$max = count($chars)-1;
for($i=0;$i<20;$i++){
    $serial .= (!($i % 5) && $i ? '-' : '').$chars[rand(0, $max)];
}
echo $serial;
?>

That generates a serial like this:

  • "HJMW0-5RRXT-CS853-BD888"

I want the first 5 characters (the first set before the " - ") of all generated serials to be the same and the others to be just numbers, without letters, that way:

  • "XYAMN-97354-81037-01936"

  • "XYAMN-75903-81938-01936"

4 answers

3

Separate into two functions as in the code below:


function prefixo(){
    $chars = array(0,1,2,3,4,5,6,7,8,9,'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z');
    $prefixo = '';
    $max = count($chars)-1;
    for($i=0;$i&lt5$i++){
        $prefixo .= (!($i % 5) && $i ? '-' : '').$chars[rand(0, $max)];
    }
    return $prefixo;
}

function serial(){
    $chars = array(0,1,2,3,4,5,6,7,8,9);
    $serial = '';
    $max = count($chars)-1;
    for($i=0;$i&lt15$i++){
        $serial .= (!($i % 5) && $i ? '-' : '').$chars[rand(0, $max)];
    }
    return $serial;
}
echo prefixo()."-".serial();

3


I don’t know if I got this right, but your serial prefix, is it a fixed text that you’re going to choose for yourself? If it is you can make a very simple change to your code, which is to take all the letters from the array, and decrease the count from 20 to 15 digits, and put your prefix text manually, thus:

$chars = array(0,1,2,3,4,5,6,7,8,9);
$serial = '';
$max = count($chars)-1;
for($i=0;$i<15;$i++){
    $serial .= (!($i % 5) && $i ? '-' : '').$chars[rand(0, $max)];
}
echo 'XYAMN-'.$serial;

Now if you want the prefix to be random letters, you can separate in 2 array, one for numbers and one for letters, and create 2 for. But I suggested a simplified form without arrays using the function chr php, thus:

for($i=0; $i<5; $i++){
    $prefixo .= strtoupper(chr(rand(97, 122))); //97 é o codigo ascii para 'a' e 122 para z
}

for($i=0; $i<15; $i++){
    $serial .= (!($i % 5) && $i ? '-' : '').rand(0, 9);
}
echo $prefixo.'-'.$serial;

And if you create functions and classes to make your serial generator much more dynamic. Such as making a modifier for the digit separator, using a single for both situations, and etc. For example:

function Serial($tipo = '', $qtdigitos = 5, $qtdbaterias = 4, $separador = '-') {
    $qtdtotal = $qtdbaterias * $qtdigitos;
    $letrasnumeros = array_merge(range(0,9), range('A', 'Z')); // Cria um array de letras e numeros de forma simplificada

    for($i=0; $i < $qtdtotal; $i++){

        if ($tipo == 'numeros') { $digito = rand(0, 9); } 
        else if($tipo == 'letras') { $digito = chr(rand(65, 90)); }   //65 é o codigo ascii para 'A' e 90 para 'Z'
        else { $digito = $letrasnumeros[rand(0, count($letrasnumeros) - 1)]; }

        $serial .= (!($i % $qtdigitos) && $i ? $separador : '').$digito;
    }
  return $serial;
}

And then you can use the function in various ways:

// Retorna serial com letras e numeros, 
// Ex: RQ4BD-1NSBA-PXUD9-DOKS6
echo Serial(); 

// Retorna serial só com números, 
// Ex: 07295-31860-33824-63832
echo Serial('numeros'); 

// Retorna serial só com letras, 
// Ex: CDMIC-AXLET-BRMGW-QUVWL
echo Serial('letras'); 

// Retorna serial só com números mas quantidade diferente de caracteres, 
// Ex: 339-671-633-081-731-120
echo Serial('numeros', 3, 6); 

// Utilizar separadores diferentes,
// Ex: 2CQHJ.SF1E6.D5SOG.UA10K
echo Serial('aleatorio', 5, 4, '.');

// Juntar formas e quantidades diferentes,
// Ex: AMQGUUY-82468-32482-84190
echo Serial('letras', 7, 1).'-'.Serial('numeros', 5, 3);

// Juntar texto fixo com serial
// Ex: XYAMN-16697-17479-56095
echo 'XYAMN-'.Serial('numeros', 5, 3);

I hope I’ve helped

2

I believe you should use random_bytes or random_int instead of rand(). The difference is that the random_* will use the CSRPNG present in the operating system, which is more secure than LGC or Mersenne Twister.

You can use the random_int with the pack, as follows:

function letra(int $limite) : string {
    $b = '';

    while(strlen($b) < $limite){
        $b .= pack('C', random_int(65, 90));
    }

    return $b;
}

function numero(int $limite) : string{
    return str_pad(
        random_int(0, str_repeat(9, $limite)),
        $limite, '0', STR_PAD_LEFT);
}

echo letra(5) . '-' . numero(5) . '-' . numero(5) . '-' . numero(5);

1

You can create a class, example:

Class serial.class.php

class Serial
{
  private $prefixo = "";
  public $letras = array('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z');
  public $numeros = array(0,1,2,3,4,5,6,7,8,9);

  /* 
   * Método construtor
   * Cria um prefixo para cada objeto criado
   */
  public function __construct() {
    $max = count($this->letras)-1;
    for($a=0;$a<5;$a++) {
      $this->prefixo .= $this->letras[rand(0, $max)];
    }
    return $this;
  }

  /* 
   * Método get
   * Gera um serial de 15 digitos toda vez que o método for chamado
   */
  public function get() {
    $serial = '';
    $max = count($this->numeros)-1;
    for($b=0;$b<15;$b++){
      $serial .= (!($b % 5) && $b ? '-' : ''). $this->numeros[rand(0, $max)];
    }
    echo $this->prefixo."-".$serial."\n";
    return $this;
  }

}

How to use:

require_once('serial.class.php');

$serial_A = new Serial();
$serial_A->get()->get()->get()
         ->get()->get()->get()
         ->get()->get()->get()
         ->get()->get()->get()
         ->get()->get()->get()
         ->get()->get()->get();

Output example

MPRDM-68308-47678-09412
MPRDM-34567-47698-43685
MPRDM-79111-86573-68267
MPRDM-78570-58526-57259
MPRDM-89941-85110-50824
MPRDM-41477-69233-60018
MPRDM-76481-63231-98672
MPRDM-14028-03542-56162
MPRDM-41338-20932-00450
MPRDM-72468-49538-39004
MPRDM-82852-74510-92625
MPRDM-34866-98635-93850
MPRDM-42227-33041-72832
MPRDM-15014-94731-68651
MPRDM-12007-58515-50146
MPRDM-27148-78106-34490
MPRDM-99967-35102-51586
MPRDM-47226-20839-60614

You can see it working on repl it.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.