12
votes

Générer des uuids aléatoires sous Linux

Je suis coincé dans une situation étrange. Je dois générer des uuids dans mon programme Linux (que je distribue à l'aide de RPM). Je ne veux pas ajouter une autre dépendance à mon application en demandant à l'utilisateur d'installer libuuid (semble que Libuuid ne figure pas dans la plupart des distributions Linux, telles que Centos).

N'y a-t-il pas un appel de système Linux standard qui génère des uuids (comme dites, sous Windows là-bas CoCreateguid)? Que utilise la commande uuidgen?


0 commentaires

8 Réponses :


2
votes

Peut-être ooid aidera-t-il? http://ooid.sourceforge.net/


0 commentaires

2
votes

aucun appel système n'existe dans POSIX pour générer UUID, mais je suppose que vous pouvez trouver un autre code BSD / mit pour générer l'UUID. Ooid est publié sous la licence logicielle Boost, qui, selon Wikipedia, est une licence permissive dans le style de BSD / MIT. Ensuite, vous pouvez simplement le coller dans votre application, sans qu'il soit nécessaire d'ajouter des dépendances.


0 commentaires

3
votes

Y a-t-il une raison pour laquelle vous ne pouvez pas simplement relier statiquement à Libuuid?


1 commentaires

Libuuid semble être LGPL, la demande de l'OP devrait donc également être LGPL. La liaison dynamique évite l'exigence de licence. source . Sauf si vous parlez d'un différent libruduide.



11
votes

merci pour tous vos commentaires!

J'ai traversé chacun, et voici ce que vous avez adapté à mes besoins: P>

Ce dont j'avais besoin était juste des uuides de temps simples générés à partir de nombres aléatoires une fois pour chaque utilisateur qui a installé l'application. UUID Version 4 Comme spécifié dans RFC 4122 était exactement. J'ai suivi un algorithme suggéré et j'ai trouvé une solution assez simple qui fonctionnerait sous Linux ainsi que de fenêtres (peut-être qu'elle est trop simpliste, mais elle satisfasse le besoin!): P>

srand(time(NULL));

sprintf(strUuid, "%x%x-%x-%x-%x-%x%x%x", 
    rand(), rand(),                 // Generates a 64-bit Hex number
    rand(),                         // Generates a 32-bit Hex number
    ((rand() & 0x0fff) | 0x4000),   // Generates a 32-bit Hex number of the form 4xxx (4 indicates the UUID version)
    rand() % 0x3fff + 0x8000,       // Generates a 32-bit Hex number in the range [0x8000, 0xbfff]
    rand(), rand(), rand());        // Generates a 96-bit Hex number


5 commentaires

Sûr! Merci de me pointer dans la bonne direction, je n'avais aucune idée! Je n'avais pas accepté la réponse parce que je l'aurais monté seul et je l'ai pensé trop simpliste !!


Votre terminologie est un peu déroutant - le terme "UUID basé sur le temps" n'est pas la version 4 mais la version 1. du côté théorique, à l'aide de MODULUS 0X3FFF ne vous donnerait pas une distribution en douceur des résultats, bien que je doute que cela aurait des implications pratiques .


Donc, si cette fonction est appelée deux fois sur la même seconde, elle renvoie la même valeur. Comment gérez-vous cela?


Réponse de travail très simple ... merci. Il est également portable et peut fonctionner directement sur de nombreuses plates-formes.


@themoondothshine Merci un million. Cointé toute l'après-midi sur HP-UX essayant de générer un UUID et vous avez proposé cette solution super élégante. J'ai un gâteau au chocolat dans le frigo, je me serais volontiers la nuit à vous comme merci!



19
votes

Est-ce que je manque quelque chose? Ne pouvez-vous pas:

cat /proc/sys/kernel/random/uuid


2 commentaires

Peut ne pas être portable avec d'autres systèmes Linux.


À quel point est-ce cher? N'est-ce pas un pool d'entropie basé sur le matériel pour Linux? Ceux-ci sont généralement chers.



10
votes

Un bon moyen que j'ai trouvé (pour Linux dev) est de #include code>. Ensuite, vous avez quelques fonctions que vous pouvez appeler:

void uuid_generate(uuid_t out);
void uuid_generate_random(uuid_t out);


0 commentaires

0
votes

uuidgen sur mon ubuntu linux dist fonctionne très bien.


0 commentaires

0
votes

Je ne peux pas encore poster des commentaires sur les réponses, mais j'aimerais simplement souligner que l'utilisation de Rand () de la réponse acceptée ne fonctionnera pas du tout sous Windows, où Rand_max est défini comme 0x7fff, donnant simplement 15 bits de hasard. Sur Linux, il est plus élevé, mais on dirait qu'il est 0x7FFFFFFFF, donnant 31 bits de hasard, il manque toujours 1 bit à 32 bits de longueur 32 bits.

Le moyen le plus sûr d'utiliser Rand () serait de compter sur le fait que le plus bas garanti rand_max la valeur n'importe où va être 0x7fff - appelez-les plusieurs fois, changeant à gauche de 15 bits et ou avec une nouvelle valeur, jusqu'à ce que la quantité requise de bits aléatoires soit produite. p>

aussi, la chaîne de format dans Sprintf Code> doit avoir une largeur spécifiée, de sorte que les zéros de premier plan sont pris en compte (les largeurs sont basées sur les bits mentionnés dans le commentaire de l'argument respectif): P>

#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <cstdint>

uint32_t rand32()
{
    return ((rand() & 0x3) << 30) | ((rand() & 0x7fff) << 15) | (rand() & 0x7fff);
}

bool gen_uuid4(char dst[37], size_t len)
{
    int n = snprintf(dst, len, "%08x-%04x-%04x-%04x-%04x%08x", 
        rand32(),                         // Generates a 32-bit Hex number
        rand32() & 0xffff,                // Generates a 16-bit Hex number
        ((rand32() & 0x0fff) | 0x4000),   // Generates a 16-bit Hex number of the form 4xxx (4 indicates the UUID version)
        (rand32() & 0x3fff) + 0x8000,     // Generates a 16-bit Hex number in the range [0x8000, 0xbfff]
        rand32() & 0xffff, rand32());     // Generates a 48-bit Hex number
        
    return n >= 0 && n < len;             // Success only when snprintf result is a positive number and the provided buffer was large enough.
}

int main()
{
    char strUuid[37];
    srand(time(NULL));
    
    bool success = gen_uuid4(strUuid, sizeof(strUuid));
    
    printf("%s\n", success ? strUuid : "UUID generation failed!");
    
    return 0;
}


0 commentaires