web-dev-qa-db-fra.com

Un algorithme pour générer un ID unique en C ++?

Quel peut être le meilleur algorithme pour générer un identifiant unique en C++? L'ID de longueur doit être un entier non signé de 32 bits.

29
Ajay

Obtenir un ID 32 bits unique est intuitivement simple: le suivant. Fonctionne 4 milliards de fois. Unique depuis 136 ans si vous en avez besoin d'une par seconde. Le diable est dans le détail: quel était le précédent? Vous avez besoin d'un moyen fiable pour conserver la dernière valeur utilisée et d'une méthode atomique pour la mettre à jour.

Le degré de difficulté dépend de la portée de l'ID. S'il s'agit d'un thread dans un processus, vous n'avez besoin que d'un fichier. S'il s'agit de plusieurs threads dans un processus, vous avez besoin d'un fichier et d'un mutex. S'il y a plusieurs processus sur une même machine, vous avez besoin d'un fichier et d'un mutex nommé. S'il s'agit de plusieurs processus sur plusieurs machines, vous devez attribuer un fournisseur d'ID faisant autorité, un serveur unique auquel toutes les machines parlent. Un moteur de base de données est un fournisseur commun comme ça, ils ont cette fonction intégrée, une colonne d'incrémentation automatique.

Les frais d'obtention de l'ID augmentent progressivement à mesure que la portée s'élargit. Lorsque cela devient impossible, la portée est Internet ou le fournisseur trop lent ou indisponible, vous devez abandonner une valeur 32 bits. Passez à une valeur aléatoire. Celui qui est suffisamment aléatoire pour faire en sorte que la machine soit frappée par un météore est au moins un million de fois plus probable que de répéter le même ID. Un goo-ID. Il n'est que 4 fois plus grand.

56
Hans Passant

Voici l'ID le plus simple auquel je puisse penser.

MyObject obj;
uint32_t id = reinterpret_cast<uint32_t>(&obj);

À tout moment, cet ID sera unique dans l'application. Aucun autre objet ne sera localisé à la même adresse. Bien sûr, si vous redémarrez l'application, l'objet peut recevoir un nouvel ID. Et une fois la durée de vie de l'objet terminée, un autre objet peut recevoir le même ID.

Et les objets dans différents espaces mémoire (par exemple, sur différents ordinateurs) peuvent se voir attribuer des ID identiques.

Enfin, si la taille du pointeur est supérieure à 32 bits, le mappage ne sera pas unique.

Mais comme nous ne savons rien du type de pièce d'identité que vous souhaitez et de son caractère unique, cela semble être une bonne réponse.

11
jalf

Vous pouvez voir ceci . (La réponse complète, je pense, est sur Stack Overflow.)
Quelques notes pour l'ID unique en C++ sous Linux dans ce site . Et vous pouvez utiliser uuid sous Linux, consultez cette page man et un exemple pour cela.

Si vous utilisez Windows et avez besoin d'API Windows, consultez cette page MSDN .

Cette page Wikipedia est également utile: http://en.wikipedia.org/wiki/Universally_Unique_Identifier .

7
Sajad Bahmani
DWORD uid = ::GetTickCount();
::Sleep(100);
1
an0nym0usc0ward

Si vous pouvez vous permettre d'utiliser Boost, il existe une bibliothèque UUID qui devrait faire l'affaire. C'est très simple à utiliser - consultez la documentation et cette réponse .

0
Sahib Yar