从类Unix系统获取唯一标识符

29
我希望能够从任何类Unix系统(如果这是可能的话)中获取一个唯一的持久化ID,以便每次我的应用程序在同一台机器上运行时都具有相同的ID。 如果可能的话,我希望从Linux、FreeBSD、Solaris等获得相同的ID... 我不想为每台机器生成新的ID,而是要获取已经存在的ID,而且我更喜欢此ID来自操作系统,而不是使用类似MAC地址之类的东西。
如果没有其他可用选项,我可以将MAC与其他内容结合使用,例如ID可以是MAC地址和其他信息的组合的MD5哈希值。
我想听听您的建议。
如果有用的话,我的应用程序是用C/C++编写的。
所有这些的目的是防止用户多次运行我的应用程序。我只想运行一次。

我觉得这不太清楚。你想要识别什么?你运行的硬件?用户?还是其他什么?并且要在什么范围内唯一? - dmckee --- ex-moderator kitten
我必须同意。为什么要这么多限制? - Brian C. Lane
我有一个灵感。我认为他想要帮助实现复制限制机制。这使得硬件和uzhin的答案合理。 - dmckee --- ex-moderator kitten
你能澄清一下吗——这是一个关于复制保护的问题吗? - Jeff Atwood
1
在Mac OS X上,您可能会获得系统ID - https://dev59.com/Am_Xa4cB1Zd3GeqP4b7R。 - petert
这个问题已经在这里得到了解决:http://unix.stackexchange.com/questions/144812/generate-consistent-machine-unique-id - nightcod3r
15个回答

0

Jason Day和A.Danischewski的答案似乎是正确的方向,但不符合您对“类Unix系统”的标准,因为在OSX上不存在/sbin/blkid/etc/fstab

唯一100%可移植的方法是选择一个标准位置用于创建您自己的应用程序文件,例如/etc/YOURAPP.cfg,如果不存在UUID,则在那里存储它。

远非理想,因为另一个人或应用程序可能会删除文件或更改文件,或者如果用户更换了根文件系统,则可能会从当前机器丢失ID,或者它可能会出现在另一台机器上。更不用说读写权限等问题。

但最终没有“相同的机器”。任何计算机都不过是其组件+当前配置而已。我认为您无法比这更好地实现可移植性。


0

你提到在Windows上使用了一些GUID... 你有关于它是如何创建的详细信息吗?

除此之外,你可以尝试像CPU ID或硬盘ID这样的东西... 我想那些是不能被更改的(但如果更换了有故障的硬盘,你会遇到麻烦)。


这个 SO 上的答案解释了如何在 Windows 上实现:https://dev59.com/2nA75IYBdhLWcg3wubun#23584584 - kodybrown

-1

听起来你在寻找 UUID。这是一种普遍的全球唯一标识符(实际上和 GUID 是一样的)

有很多 C++ 的实现方式在不同的库中,或者你可以使用 uuidgen 命令并捕获输出。


1
错误,UUID 每次生成时都是不同的:"在同一台机器上运行我的应用程序时将保持不变的唯一标识符"。 - user23167

-1

大多数类Unix系统都有一个可通过/dev/random访问的随机数生成器。您需要像MAC地址和时间这样的东西来为GUID生成器提供真正的唯一性(这就是Windows上的GUID生成器所做的)。在此基础上,从/dev/random获取一些内容将为您提供一个相当好的GUID类型结构。实际上,UUID库在幕后执行此类操作。

如果您只需要每台计算机一个数字,那么MAC地址可能就足够了。这些由中央机构管理,并且可以合理地假设没有两个MAC地址相同。但是,如果您尝试使用它将软件安装与MAC地址绑定,请注意某些组件具有可编程的MAC地址或MAC地址的可编程组件。类Unix操作系统,特别是开源操作系统,倾向于没有硬连序列号。这种方法也可能会导致在虚拟机中运行多个软件实例时出现问题。

一种选择可能是从几个制造商获取的 USB dongle。另一个选择可能是许可证服务器,其中提供唯一代码给服务器。同样,不同来源提供了几个现成的解决方案。


我需要每台机器一个持久的数字。我了解所有关于MAC地址的信息,因为它们可能会改变,所以它们是我的最后解决方案。 - Blue

-2

在以下场合中,您可以使用锁文件:

  • /var/run/yourapp.pid(如果程序由root运行)
  • $HOME/.yourapp.pid(如果由用户和本地文件系统运行)
  • $HOME/.yourapp.$(hostname -f).pid(nfs上的主目录)

当您的程序运行时,它应该执行以下操作:

lock = open(filename, O_CREAT | O_EXCL);
dprintf(lock, "%u", getpid());

如果打开失败,请检查进程是否仍在运行,如果不是,则删除文件并重试。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接