108 votes

Comment générer un uid court comme "aX4j9Z" (en JS)

Pour mon application web (en JavaScript), je souhaite générer des guids courts (pour différents objets - qui sont en fait des types différents - des chaînes et des tableaux de chaînes).

Je veux quelque chose comme "aX4j9Z" pour mes uids (guids).

Ces identifiants doivent donc être suffisamment légers pour être transférés sur le web et traités par des chaînes de caractères js, et assez uniques pour ne pas constituer une structure énorme (pas plus de 10 000 éléments). En disant "assez unique", je veux dire qu'après la génération de l'uid, je pourrais vérifier si cet uid existe déjà dans la structure et le régénérer si c'est le cas.

151voto

KennyTM Points 232647

Voir Réponse de @Mohamed pour une solution toute faite (le shortid paquet ). Préférez cette solution à toutes celles proposées sur cette page si vous n'avez pas d'exigences particulières.


Une séquence alphanumérique de 6 caractères est suffisante pour indexer de manière aléatoire une collection de 10 000 pièces (36 6 \= 2,2 milliards et 36 3 \= 46656).

function generateUID() {
    // I generate the UID from two parts here 
    // to ensure the random number provide enough bits.
    var firstPart = (Math.random() * 46656) | 0;
    var secondPart = (Math.random() * 46656) | 0;
    firstPart = ("000" + firstPart.toString(36)).slice(-3);
    secondPart = ("000" + secondPart.toString(36)).slice(-3);
    return firstPart + secondPart;
}

Les UIDs générés aléatoirement auront une collision après avoir généré ~ √N nombres (paradoxe de l'anniversaire), donc 6 chiffres sont nécessaires pour une génération sûre sans vérification (l'ancienne version ne génère que 4 chiffres qui auraient une collision après 1300 IDs si vous ne vérifiez pas).

Si vous effectuez un contrôle des collisions, le nombre de chiffres peut être réduit de 3 ou 4, mais notez que les performances diminuent de façon linéaire lorsque vous générez de plus en plus d'UID.

var _generatedUIDs = {};
function generateUIDWithCollisionChecking() {
    while (true) {
        var uid = ("0000" + ((Math.random() * Math.pow(36, 4)) | 0).toString(36)).slice(-4);
        if (!_generatedUIDs.hasOwnProperty(uid)) {
            _generatedUIDs[uid] = true;
            return uid;
        }
    }
}

Envisagez d'utiliser un générateur séquentiel (par ex. user134_item1 , user134_item2 ) si vous avez besoin d'unicité et non d'imprévisibilité. Vous pouvez "hacher" la chaîne générée séquentiellement pour récupérer l'imprévisibilité.

Les UID générés à l'aide de Math.random n'est pas sûr (et vous ne devriez pas faire confiance au client de toute façon). Faire no se fier à son caractère unique ou imprévisible dans les tâches critiques.

73voto

Mohamed Ramrami Points 1889

Mise à jour 08/2020 :

shortid a été supprimée au profit de nanoïde qui est plus petit et plus rapide :

  • Petit . 108 octets (minifiés et gzippés). Aucune dépendance. La limite de taille contrôle la taille.
  • Rapide . Il est 40% plus rapide que l'UUID.
  • Sûr . Il utilise des API aléatoires cryptographiquement fortes. Il peut être utilisé en grappes.
  • Compact . Il utilise un alphabet plus large que l'UUID (A-Za-z0-9_-). La taille de l'ID a donc été réduite de 36 à 21 symboles.
  • Portable . Nano ID a été porté à 14 langages de programmation.
import { nanoid } from 'nanoid'

// 21 characters (default)
// ~149 billion years needed, in order to have a 1% probability of at least one collision.
console.log(nanoid()) //=> "V1StGXR8_Z5jdHi6B-myT"

// 11 characters
// ~139 years needed, in order to have a 1% probability of at least one collision.
console.log(nanoid(11)) //=> "bdkjNOkq9PO"

Plus d'informations ici : https://zelark.github.io/nano-id-cc/


Ancienne réponse

Il y a aussi un paquet npm génial pour cela : shortd

Générateur d'identifiant unique non séquentiel incroyablement court et convivial.

ShortId crée des identifiants uniques non séquentiels étonnamment courts et conviviaux. Parfait pour les raccourcisseurs d'url, les identifiants MongoDB et Redis, et tout autre identifiant que les utilisateurs pourraient voir.

  • Par défaut, il s'agit de 7 à 14 caractères conviviaux : A-Z, a-z, 0-9, _-
  • Non séquentiels, ils ne sont donc pas prévisibles.
  • Prend en charge les grappes (automatiquement), les semences personnalisées et l'alphabet personnalisé.
  • Peut générer n'importe quel nombre d'identifiants sans doublons, même des millions par jour.
  • Parfait pour les jeux, surtout si vous craignez la tricherie et que vous ne voulez pas d'identifiant facilement devinable.
  • Les applications peuvent être redémarrées autant de fois que nécessaire sans risque de répétition d'une erreur.
  • Remplacement populaire de Mongo ID/Mongoose ID.
  • Fonctionne avec Node, io.js et les navigateurs web.
  • Inclut les tests Mocha.

Utilisation

var shortid = require('shortid');
console.log(shortid.generate()); //PPBqWA9

30voto

modiX Points 397

Voici un exemple, mais il ne donne que les lettres minuscules et les chiffres :

var uuid = Math.random().toString(36).slice(-6);

console.log(uuid);

13voto

Muduo Lin Points 61

Obtenez un compteur simple commençant à 100000000, convertissez le nombre en radix 36.

(100000000).toString(36);  //1njchs

(2100000000).toString(36); //yqaadc

Vous pouvez confortablement avoir 2 milliards d'identifiants uniques et élégants, tout comme YouTube.

5voto

RobG Points 41170

L'exemple suivant génère 62^3 (238 328) valeurs uniques de 3 caractères à condition que la sensibilité à la casse soit unique et que les chiffres soient autorisés dans toutes les positions. Si l'insensibilité à la casse est requise, supprimez les majuscules ou les minuscules de la chaîne de caractères et vous obtiendrez 35^3 (42 875) valeurs uniques.

Peut être facilement adapté pour que le premier caractère soit toujours une lettre, ou toutes les lettres.

Non, mais il peut être optimisé et pourrait également refuser de renvoyer un identifiant lorsque la limite est atteinte.

var nextId = (function() {
  var nextIndex = [0,0,0];
  var chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
  var num = chars.length;

  return function() {
    var a = nextIndex[0];
    var b = nextIndex[1];
    var c = nextIndex[2];
    var id = chars[a] + chars[b] + chars[c];

    a = ++a % num;

    if (!a) {
      b = ++b % num; 

      if (!b) {
        c = ++c % num; 
      }
    }
    nextIndex = [a, b, c]; 
    return id;
  }
}());

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X