Mysql
 sql >> Base de données >  >> RDS >> Mysql

Génération d'ID unique court PHP à l'aide d'auto_increment ?

Vous aurez besoin de quelque chose qui soit correct par construction, c'est-à-dire une fonction de permutation :il s'agit d'une fonction qui effectue un mappage réversible un à un d'un entier (votre compteur séquentiel) à un autre. Quelques exemples (toute combinaison de ceux-ci devrait également travail):

  • en inversant certains des bits (par exemple en utilisant un XOR, ^ en PHP)
  • échanger les places des bits (($i &0xc)>> 2 | ($i &0x3) <<2), ou simplement inverser l'ordre de tous les bits
  • ajouter une valeur constante modulo votre plage maximale (doit être un facteur de deux, si vous combinez cela avec ceux ci-dessus)

Exemple :cette fonction convertira 0, 1, 2, 3, 5, .. en 13, 4, 12, 7, 15, .. pour les nombres jusqu'à 15 :

$i=($input+97) & 0xf;
$result=((($i&0x1) << 3) + (($i&0xe) >> 1)) ^ 0x5;

MODIFIER

Un moyen plus simple serait d'utiliser un générateur congruentiel linéaire (LCG, qui est généralement utilisé pour générer des nombres aléatoires), qui est défini par une formule de la forme :

X_n+1 = (a * X_n + c) mod m

Pour bonnes valeurs de a, c et m, la séquence de X_0, X_1 .. X_m-1 contiendra tous les nombres entre 0 et m-1 exactement une fois. Vous pouvez maintenant commencer à partir d'un index croissant de manière linéaire et utiliser le suivant valeur dans la séquence LCG comme clé "secrète".

EDIT2

Implémentation :vous pouvez concevoir vos propres paramètres LCG , mais si vous vous trompez, il ne couvrira pas toute la gamme (et aura donc des doublons) donc j'utiliserai un ensemble de paramètres publié et essayé ici à partir de cet article :

a = 16807, c = 0, m = 2147483647

Cela vous donne une plage de 2 ** 31. Avec pack() vous pouvez obtenir l'entier résultant sous forme de chaîne, base64_encode() en fait une chaîne lisible (jusqu'à 6 caractères significatifs, 6 bits par octet) donc cela pourrait être votre fonction :

substr(base64_encode(pack("l", (16807 * $index) % 2147483647)), 0, 6)