在c編程中產生一致的機器唯一ID

在c編程中產生一致的機器唯一ID

是否可以產生一個唯一的 ID,除非硬體發生變化,否則該 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。但是我怎麼能過濾曲目以僅選擇正在變化的曲目。我能否確定他們的 orderrer 不會被交換,從而更改附加的字串以及 UUID。

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

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

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

答案1

簡短回答

根據我所有的研究和嘗試,我想說,不可能製作一個程式來產生遵守以下約束的唯一 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)上,它是目錄,在其中您會發現“address”文件,其中包含mac地址和指向“sys/devices”中目錄的符號連結。如果在更高的 Linux 版本上,它將直接是指向“/sys/devices”中目錄的符號鏈接,您將在其中找到“address”檔案。 (我嘗試過 RHEL 6、Debian 7、Debian 8、Ubuntu 15 和核心更新為 linux 4.3 的 Ubuntu 15)

即使在新的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/virtual/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 中的任何位置都會有一個「虛擬」資料夾。上面連結的規則中從未說過情況總是如此。所以這個問題不能這樣回答。

我希望我所有的研究都能幫助別人。

相關內容