Hardware

在 c 程式中生成一致的機器唯一 ID

  • November 25, 2015

是否可以生成一個不會隨著時間而改變的唯一 ID,除非有硬體更改。硬體必須使用 ac 程序生成。

如果它對欺騙(如 MAC 地址或硬碟序列號欺騙)具有強韌性,那也很棒。但這不是絕對的要求。

我需要這樣的 ID 以便從許多不同的電腦收集軟體數據以進行統計。

我已經閱讀了很多類似的文章,比如這個: 生成一致的機器唯一 ID;但它們不適合我的需要。

我需要這個程序以普通使用者身份執行,所以我不能使用“dmidecode”之類的命令。即使除了使用 MAC 地址我沒有其他解決方案,如果使用者從 Wifi 切換到乙太網,我也不希望 UUID 改變,所以只取第一個 mac 地址可能會有問題。最重要的是,即使他們安裝了 VMware 或 VPN,UUID 也必須保持相同。因此,獲取所有的 MAC 地址也不是一種選擇,因為那些以前的工具會生成更多的網路介面和更多的 MAC 地址,從而更改 UUID。

我也希望它在虛擬機上工作,生成的來賓 uuid 應該與主機不同。

我什至不知道這個問題是否有這樣的解決方案。但我認為只能通過讀取 sys/class/net/*/addresses 來獲取所有物理現有硬體介面的 mac 地址。然後附加所有 mac 地址並使用 sha1 對它們進行散列以生成 UUID。但是我怎樣才能過濾劇目以只選擇改變的劇目。我可以確定他們的訂單不會被交換,從而改變附加的字元串和 UUID。

否則,我可以在沒有root權限和第三方工具的情況下檢索硬碟序列號嗎?(如果我能找到第三方軟體的來源就可以了)

任何其他解決方案也將受到歡迎。

PS:它必須與核心 2.6 或更高版本的任何 linux 版本兼容

簡短的回答

從我所有的研究和嘗試中,我會說不可能製作一個程序來生成一個符合以下約束的唯一 ID。

  • 如果在同一台電腦上生成,則 ID 每次都必須相同。
  • 如果在不同的電腦上生成,則 ID 必須不同。
  • 該程序必須以使用者身份執行。
  • 該程序必須與任何具有 2.6 核心版本或更高版本的 linux 發行版兼容
  • 如果電腦被修改,ID可能會不同(例如:硬體更換)
  • 該程序不應依賴必須安裝在電腦上的第三方工具

長答案

在這裡,我將介紹我對 mac 地址的嘗試。

這裡的目標是找到一種方法來檢索所有物理網路介面的地址。作為一個普通使用者,我看到找到mac地址的最簡單方法是讀取“/sys”目錄中的系統文件。這些文件從 linux 2.6 開始就可用,所以這很完美。

我的研究把我帶到了這些規則集: https ://www.kernel.org/doc/Documentation/sysfs-rules.txt

無法按照這些規則中的建議使用 udev 庫,因為它必須從外部添加。所以我深入研究了可以在這裡找到的原始碼:http: //cgit.freedesktop.org/systemd/systemd/tree/src/libudev

我從中學到的是,要檢索 mac 地址,您應該查找“sys/subsystem”,如果存在,則在其中查找“net”目錄,您將找到每個網路介面的目錄。如果沒有“subsystem”文件夾,則必須在“sys/class”、“sys/bus”和“sys/block”文件夾中查找“net”目錄。事實上,我一直在“課堂”中找到它們,但規則說不應該期望。

上面我說過,在“net”文件夾中,你會找到網路目錄,這並不完全正確。在 linux 2.6(我使用 RHEL 4)上,它是目錄,您會在其中找到包含 mac 地址的“地址”文件,該文件是針對“sys/devices”中目錄的符號連結。如果在更高的 linux 版本上,它將直接成為“/sys/devices”中目錄的符號連結,您將在其中找到“address”文件。(我在 RHEL 6、Debian 7、Debian 8、Ubuntu 15 和 Ubuntu 15 上進行了嘗試,核心更新為 linux 4.3)

即使在新的 linux 版本(4.3)中,我也從未見過“/sys/subsystem”目錄。

sysfs 的新佈局(>= linux 3):為了從虛擬介面中區分物理介面,我想查看設備的 devpath。我在“/sys/class/net”中的符號連結指向這些目錄:

  • “/sys/devices/pci0000:00/0000:00:11.0/0000:02:01.0/net/eth0”
  • “/sys/devices/虛擬/net/eth1”

eth1 是我按照以下主題創建的虛擬虛擬網卡:如何在沒有物理適配器的機器上創建虛擬乙太網介面?

因此,您可以看到虛擬文件夾位於“虛擬”文件夾中,這就是區分它們的方法。

sysfs (linux 2.6) 的舊佈局:

虛擬網路介面的目錄中沒有“設備”符號連結。

你會發現“/sys/class/net/eth0/device -> /sys/devices….” 但是如果有一個虛擬 eth1,那麼“/sys/class/net/eth1”中就不會有這樣的符號連結.


總而言之,使用“opendir”、“readdir”、“access(’…’,F_OK)”、“fopen”.. 你可以只檢索物理介面的 mac 地址。

然後只需對它們進行排序,這樣您就可以確定它們會以相同的順序出現,然後將所有內容附加到緩衝區中並使用 openssl 中的 SHA1,進行一些解析以使其看起來像 UUID,您就可以開始了。

但問題是,我不想依賴這樣一個事實,即網路設備的 devpath 中的任何地方都會有一個“虛擬”文件夾。上面連結的規則中從未說過總是如此。所以這個問題不能這樣回答。

我希望我所有的研究都會對某人有所幫助。

引用自:https://unix.stackexchange.com/questions/241278