IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++Builder Discussion :

Comment générer un uid vraiment aléatoire ?


Sujet :

C++Builder

  1. #1
    Membre régulier Avatar de benj63
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Mai 2002
    Messages
    207
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 207
    Points : 99
    Points
    99
    Par défaut Comment générer un uid vraiment aléatoire ?
    Bonjour,

    J'utilise des threads, qui peuvent se lancer simultanément, et il arrive que ces threads lisent ou écrivent un fichier en même temps...
    Afin d'éviter une concurrence à l'écriture du fichier, je fais en sorte que son nom contienne un uid généré aléatoirement...

    Pour générer un uid aléatoirement, j'ai fait une fonction contenant notamment :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    randomize();
    uid = rand()%100000;
    Seulement si la fonction est appelée simultanément par 2 threads, l'uid généré aléatoirement est malheureusement le même...
    Y'a-il un moyen de contourner cela, de générer vraiment un nombre aléatoire même s'il est généré au même instant ?
    Ou puis-je générer un uid à partir d'autres éléments (chaine de caractères par exemple) ?

    Merci d'avance pour votre aide !

  2. #2
    Membre chevronné
    Avatar de Crayon
    Inscrit en
    Avril 2005
    Messages
    1 811
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 811
    Points : 2 189
    Points
    2 189
    Par défaut
    Salut, à la place de gérer toi-même cet identifiant. Est-ce que tu pourrais utiliser la propriété ThreadID?
    • Plus un ordinateur possède de RAM, plus vite il peut générer un message d'erreur. - Dave Barry
    • Je n'ai pas peur des ordinateurs. J'ai peur qu'ils viennent à nous manquer. - Isaac Asimov
    • Le code source est comme une belle femme, plus on le regarde, plus on trouve des défauts. - Crayon

  3. #3
    Membre régulier Avatar de benj63
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Mai 2002
    Messages
    207
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 207
    Points : 99
    Points
    99
    Par défaut
    Merci, ça aurait pu être une solution... seulement en fait, ce thread lance un exécutable, qui lui, fait l'écriture de fichier qui pose problème. Car si le thread est lancé simultanément 2 fois, il lance 2 fois l'exécutable, qui cherche à écrire 2 fois le fichier avec un même nom...

    S'il n'y a pas de solution pour générer un nombre vraiment aléatoire, je vais faire un try { SaveToFile() } catch { } à l'ecriture du fichier, qui, en cas d'exception levée, renommera le nom du fichier de sortie...


    Quelques pistes et questions :

    - En cryptographie par exemple, j'imagine qu'on fait en sorte d'éviter la reproductibilité des nombres aléatoires (d'ailleurs sur la page Random, ils déconseillent d'utiliser cette fonction pour réaliser un algo de cryptographie), du coup qu'utilise-t'on comme fonction ?

    - ThreadId retourne l'identifiant d'un thread, mais si on est dans une fonction, n'y a-t'il pas moyen de récupérer un identifiant de cette fonction, comme un numéro d'Handle ?

    - Existe-t'il un autre élément du système qu'on pourrait récupérer, et qui change constamment ? (histoire que si on l'appelle 2 fois à la même milliseconde, on ait 2 valeurs différentes) ? J'ai tenté les fonctions qui fournissent la mémoire disponible, mais si on lance la fonction au même instant, je crois que le 2ème appel de la fonction retourne n'importe quoi

    - Existe-t-il des fonctions qui génèrent une "empreinte" unique (comme un md5 unique d'un fichier) à partir d'une chaine de caractères passée en argument ? Mon thread lancé 2 fois simultanément, lance 2 fois le même exécutable, mais avec des arguments différents... Du coup, pour choisir le nom du fichier de sortie généré, je pourrais le faire en fonction d'une empreinte qui serait générée à partie des arguments envoyés...

  4. #4
    Membre chevronné
    Avatar de Crayon
    Inscrit en
    Avril 2005
    Messages
    1 811
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 811
    Points : 2 189
    Points
    2 189
    Par défaut
    Salut, pourquoi ne pas simplement utiliser un compteur protéger avec des lock (TMonitor ou TCriticalSection)?
    • Plus un ordinateur possède de RAM, plus vite il peut générer un message d'erreur. - Dave Barry
    • Je n'ai pas peur des ordinateurs. J'ai peur qu'ils viennent à nous manquer. - Isaac Asimov
    • Le code source est comme une belle femme, plus on le regarde, plus on trouve des défauts. - Crayon

  5. #5
    Membre actif Avatar de Argol_Medusa
    Homme Profil pro
    Ingénieur Radiofréquences
    Inscrit en
    Août 2005
    Messages
    208
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur Radiofréquences
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 208
    Points : 242
    Points
    242
    Par défaut
    Pour info, verrouille bien ton autorisation d'écriture, et utilise un tampon mémoire si tu dois écrire à haute fréquence, car tu vas avoir des soucis à un moment donné :

    Perso j'ai déjà eu le cas avec mon exe qui écrivait dans son fichier txt à lui que personne d'autre n'utilisait, même pas un second exe.

    Sauf qu'il écrivait des trames ARINC recues directement dans le fichier (à genre une trame toutes les 10ms, j'avais fais confiance au buffer de l'OS pour le tampon HDD) et là ... le drame : L'ANTIVIRUS PREND LE LOCK DU FICHIER DE MANIERE NON SECURISEE !!

    Ce qui fait que de temps en temps ( en enregistrement en continue une fois toutes les 3 heures ), le fichier était verrouillé, impossible d'écrire dessus, c'était l'antivirus qui prenait la main, et pas en scan périodique, à chaque écriture de fichier il doit regarder ( je pense ) le contenu. Et ça, si tu ne le sais pas, tu peux chercher un moment l'origine du problème ...

    La parade -> mémoire tampon et écriture que de temps en temps (une fois toutes les 2 secondes), et pas à haute fréquence.



    Pour générer des nombres aléatoires, c'est un domaine particulier, une science à part.
    Tu ne peux générer que des nombres pseudo-aléatoires avec un PC, cette machine étant un système déterministe.

    En cryptographie, ce qui est important c'est de générer des nombres parfaitement aléatoires c'est vrai tu as raison, mais ce n'est pas si simple que cela.
    Il faut passer des algos mathématiques de vérifications des clefs, cette génération de nombres est d'ailleurs le point faible des systèmes de crypto parfait (type masque jetables) en fait.

    En réponse à ta question, ce qu'on utilise quand on veut générer quelque chose de parfaitement aléatoire : des choses physiques, réelles ( de vrai boules de loto calibrées très précisément en taille poid etc. par exemple ).

    Les casinos par exemple utilisent des systèmes physiques avec des tapis roulants pour remonter les boules après tirage et visualisation automatique du résultat par les ordinateurs.

    Mais dans ton cas je ne pense pas que tu es besoin de nombres parfaitement aléatoires.
    Si tu as juste besoin de générer des noms de fichiers différents, utilise une génération pseudo-aléatoire, avec mémorisation des numéros déjà tirés que tu mets de coté pour ne pas les retirer ( par exemple en créant une 3eme thread ou un exe indépendant de génération nombre aléatoire, interrogeable comme tu veux par exemple en serveur TCP/IP qui va naturellement serialiser tes données et donc générer les nombres les uns après les autres et les fournir à tous tes clients TCP -chacune de tes autres thread)
    Désolé, on savait pas que c'était impossible, alors on l'a fait

  6. #6
    Membre chevronné
    Avatar de DjmSoftware
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Mars 2002
    Messages
    1 044
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Responsable de compte
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 044
    Points : 2 187
    Points
    2 187
    Billets dans le blog
    1
    Par défaut
    Salut La RTL Offre la fontion CreateGUID(out GUID: TGuid):Integer;

    cette fonction est disponible également sous BCB6

    il existe par ailleurs un article intéressant ici:http://support.microsoft.com/kb/320375/fr

    cdlt
    vous trouverez mes tutoriels à l'adresse suivante: http://djmsoftware.developpez.com/
    je vous en souhaite une excellente lecture ...

    A lire : Les règles du forum

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 3
    Dernier message: 08/03/2008, 12h01
  2. Comment générer des nombres reéls aléatoires ?
    Par rzmadjid dans le forum Langage
    Réponses: 16
    Dernier message: 21/02/2008, 18h14
  3. Réponses: 4
    Dernier message: 25/04/2007, 21h18
  4. Réponses: 2
    Dernier message: 16/05/2006, 18h02

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo