Je souhaite obtenir de tout système de type Unix (si cela est possible) un identifiant unique qui sera persistant à chaque fois que mon application s'exécute sur le même ordinateur. Si cela est possible, je souhaite obtenir le même identifiant sous Linux, FreeBSD ou Solaris, etc. Je ne souhaite pas générer un nouvel identifiant pour chaque machine, mais obtenir un identifiant déjà existant et je préfère cet identifiant. viens du système d'exploitation et je ne préfère pas utiliser quelque chose comme l'adresse MAC.
S'il n'y a pas d'autre option disponible, je peux utiliser MAC en combinaison avec autre chose, par exemple, l'ID peut être le hachage md5 de la combinaison de l'adresse MAC et de quelque chose d'autre.
Je voudrais écouter vos suggestions.
Si cela est utile, mon application est écrite en C/C++.
Le but de tout cela est d'empêcher un utilisateur d'exécuter mon application deux fois ou plus. Je veux courir juste une fois.
Qu'en est-il de l'UUID du système de fichiers racine? Vous pouvez obtenir le périphérique de système de fichiers racine à partir de /etc/fstab
, soit en analysant manuellement le fichier, soit en utilisant getfsent (3)
ou getfsfile (3)
. Une fois que vous avez le périphérique, vous pouvez obtenir l'UUID en vérifiant les liens dans /dev/disk/by-uuid
ou à partir de la commande blkid
.
Solaris et Linux fournissent tous deux l'utilitaire hostid
(1).
Le meilleur moyen est, comme d’habitude, de voir comment d’autres personnes ont déjà résolu le même problème.
FLEXlm utilise également un identifiant d'hôte pour ses licences verrouillées par nœud. L’identificateur d’hôte le plus courant qu’il utilise est l’adresse MAC Ethernet de l’une de vos interfaces réseau, écrasée sans séparateur.
Il peut également utiliser (sous Windows) le numéro de série du volume du lecteur C: (de nouveau brisé sans séparateurs) et sous Solaris le résultat de la commande hostid
(IIRC, sur les ordinateurs Sun, ce numéro est unique et situé sur une petite EEPROM amovible de la carte système).
Bien que l’adresse MAC soit extrêmement facile à simuler, c’est un identificateur presque universel de nos jours (presque tous les nouveaux ordinateurs ont au moins un port Ethernet, et il est très courant qu’ils soient à bord), et se veulent réellement uniques au monde (en fait, les protocoles Ethernet dépendent de cette unicité). Les principaux problèmes que vous auriez avec cette approche:
Une autre option consiste à utiliser les informations dérivées de dmidecode , une commande présente sur linux. Ces informations sont décodées à partir de/dev/mem, ce qui nécessite un accès root.
Les informations lues par dmidecode sont connues pour être erronées, car certains fabricants de cartes mères mentent ou simulent certains des champs.
Il n'y a pas de moyen général et fiable d'obtenir ce que vous voulez.
Je ne pense pas que ce soit possible. Le mieux que vous puissiez faire est de créer une très longue chaîne aléatoire (comme MS le fait avec des GUID) et de la stocker quelque part sur votre système.
Vous devez tenir compte du fait que de nombreuses configurations ont peut-être créé une image de système de fichiers et cloné sur de nombreuses machines, plutôt que de les configurer individuellement. Dans d'autres cas, une machine peut être réinitialisée plusieurs fois. En d'autres termes, tout ce que le système d'exploitation fourni ne peut faire confiance.
Cependant, la CPU conserve un numéro de série unique, mais l'accès à celui-ci doit être différent sur différents systèmes.
Vous ne mentionnez pas à quel point l'identifiant unique doit être stable - voulez-vous toujours que le même hôte produise le même ID à chaque exécution de votre code?
Si non, alors la suggestion de fuzzymonk de uuidgen est ce que vous voulez.
Si oui, vous devez décider de ce qui constitue "la même chose" en ce qui concerne l'hôte concerné. Une solution serait, comme vous le suggérez, la somme MD5 du MAC de la première interface Ethernet et "quelque chose". Pour "quelque chose" dans ce cas, je considérerais le nom de domaine complet, sauf si votre notion de "même hôte" inclut le nom de domaine complet qui change ...
Vous pouvez obtenir l'UUID du système de fichiers racine /
, qui est assez fiable, mais il ne fera pas la différence entre les chroots et éventuellement vms s'exécutant sur le même disque.
Si vous travaillez principalement avec des disques durs internes ou statiques dédiés à l'exécution d'un système d'exploitation particulier, vous devriez pouvoir utiliser l'UUID du système de fichiers racine pour détecter le système.
Vous pouvez obtenir l'UUID de la racine f avec quelque chose comme ceci: alias sys_guid='Sudo /sbin/blkid | grep "$(df -h / | sed -n 2p | cut -d" " -f1):" | grep -o "UUID=\"[^\"]*\" " | sed "s/UUID=\"//;s/\"//"'
Si vous avez besoin de différencier davantage les versions de noyau du même système d'exploitation ou de systèmes d'exploitation différents exécutés sur le même disque, vous pouvez utiliser les données de uname
et/ou les combiner avec l'UUID de la racine.
On dirait que vous recherchez un UUID. C'est un identifiant unique et universel commun (en réalité, la même chose qu'un GUID)
Il existe de nombreuses implémentations C++ dans différentes bibliothèques, ou vous pouvez utiliser la commande uuidgen et capturer la sortie.
La plupart des machines de type Unix ont un générateur de nombres aléatoires accessible via / dev/random . Vous aurez besoin de quelque chose comme une adresse MAC et un temps pour donner une authenticité unique au générateur GUID (c'est ce que fait le générateur GUID sous Windows). De plus, obtenir quelque chose de/dev/random vous donnera une construction de type GUID raisonnablement bonne. En pratique, les bibliothèques UUID font ce genre de choses en coulisse.
Si vous n'avez besoin que d'un numéro par machine, une adresse MAC sera probablement suffisante. Celles-ci sont administrées par un organisme central et on peut raisonnablement supposer qu'aucune adresse MAC ne sera identique. Toutefois, si vous essayez d'utiliser ceci pour lier une installation logicielle à une adresse MAC, sachez que certains composants ont des adresses MAC programmables ou des composants programmables de l'adresse MAC. Les systèmes d'exploitation de type Unix, en particulier ceux à code source ouvert, n'ont généralement pas de numéro de série câblé. Cette approche peut également entraîner des problèmes lors de l'exécution de plusieurs instances du logiciel dans les ordinateurs virtuels.
Une option pourrait être une clé USB { dongle, } qui peut être obtenue auprès de plusieurs fabricants. Une autre option pourrait être un serveur de licences, où le code unique est fourni au serveur. Encore une fois, plusieurs solutions prédéfinies à cette fin sont disponibles auprès de différentes sources.
Vous avez mentionné que vous utilisiez un GUID sous Windows ... Avez-vous des détails sur la façon dont il est créé?
En dehors de cela, vous pouvez essayer quelque chose comme un ID de processeur ou un ID de disque dur ... Je suppose que ceux-ci ne peuvent pas être modifiés (mais vous aurez des problèmes si un disque dur défectueux est remplacé).
Les réponses de Jason Day et A.Danischewski semblent être sur la bonne voie, mais ne répondent à vos critères d'aucun "système de type Unix" car /sbin/blkid
et /etc/fstab
n'existent pas sous OSX.
La seule approche 100% portable consiste à choisir un emplacement standard pour un fichier que votre propre application créera, par exemple. /etc/YOURAPP.cfg
et y stocker un UUID s'il n'en existe pas déjà un.
Loin d'être idéal, puisqu'un autre utilisateur ou une autre application pourrait supprimer ou modifier le fichier, ou si l'utilisateur modifiait le système de fichiers racine, vous pourriez perdre l'ID de la machine en cours ou le créer sur une autre machine. Sans parler des problèmes d'autorisations de lecture et d'écriture, etc.
Mais à la fin, il n’existe pas de "même machine". N'importe quel ordinateur n'est ni plus ni moins que ses composants + configuration actuelle. Je ne pense pas que vous puissiez faire mieux que cela, de manière portable.