C 프로그래밍에서 일관된 기계 고유 ID 생성

C 프로그래밍에서 일관된 기계 고유 ID 생성

하드웨어가 변경되지 않는 한 시간이 지나도 변경되지 않는 고유 ID를 생성할 수 있습니까? 하드웨어는 ac 프로그램으로 생성되어야 합니다.

MAC 주소나 하드 디스크 일련 번호 스푸핑과 같은 스푸핑에 강력하다면 그것도 좋을 것입니다. 그러나 그것이 절대적인 요구사항은 아닙니다.

다양한 컴퓨터에서 통계를 위한 소프트웨어 데이터를 수집하려면 이러한 ID가 필요합니다.

나는 이미 다음과 같은 유사한 게시물을 많이 읽었습니다. 일관된 시스템 고유 ID 생성; 하지만 그것들은 내 필요에 맞지 않아요.

일반 사용자로 실행하려면 이 프로그램이 필요하므로 "dmidecode"와 같은 명령을 사용할 수 없습니다. MAC 주소를 사용하는 것 외에는 다른 해결책이 없더라도 사용자가 Wi-Fi에서 이더넷으로 전환하면 UUID가 변경되는 것을 원하지 않으므로 첫 번째 Mac 주소만 사용하면 문제가 될 수 있습니다. 또한 VMware 또는 VPN을 설치하더라도 UUID는 동일하게 유지되어야 합니다. 따라서 모든 mac 주소를 가져오는 것은 옵션이 아닙니다. 이전 도구는 더 많은 네트워크 인터페이스와 더 많은 mac 주소를 생성하여 UUID를 변경하기 때문입니다.

또한 가상 머신에서도 작동하기를 원합니다. 생성된 게스트 uuid는 호스트 uuid와 달라야 합니다.

이 문제에 대한 그러한 해결책이 있는지조차 모르겠습니다. 하지만 제가 생각한 것은 sys/class/net/*/addresses를 읽어 기존의 모든 물리적 하드웨어 인터페이스의 mac 주소만 가져오는 것이었습니다. 그런 다음 모든 Mac 주소를 추가하고 sha1로 해싱하여 UUID를 생성합니다. 그러나 변경되지 않는 레퍼토리만 선택하도록 레퍼토리를 필터링하려면 어떻게 해야 합니까? 그리고 순서가 바뀌지 않아 추가된 문자열과 UUID가 변경되지 않을 것이라고 확신할 수 있습니까?

그렇지 않으면 루트 권한이나 타사 도구 없이 하드 디스크 일련 번호를 검색할 수 있습니까? (타사 소프트웨어의 소스를 찾을 수 있다면 괜찮습니다)

다른 솔루션도 매우 환영받을 것입니다.

추신: 커널 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를 사용했습니다)에서는 디렉토리이며 특히 "sys/devices"의 디렉토리를 대상으로 하는 심볼릭 링크와 mac 주소를 포함하는 "address" 파일을 찾을 수 있습니다. 상위 Linux 버전에서는 "/sys/devices" 디렉터리에 대한 직접 심볼릭 링크가 되며, 여기에서 "주소" 파일을 찾을 수 있습니다. (저는 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/virtual/net/eth1"

eth1은 다음 주제에 따라 만든 더미 가상 NIC였습니다.물리적 어댑터 없이 머신에서 가상 이더넷 인터페이스를 어떻게 생성할 수 있습니까?

따라서 가상 폴더가 "가상" 폴더에 있다는 것을 알 수 있으므로 이를 구별하는 방법이 됩니다.

sysfs의 이전 레이아웃(리눅스 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 어디에든 "가상" 폴더가 있을 것이라는 사실에 의존하고 싶지 않았다는 것입니다. 위에 링크된 규칙에서는 이것이 항상 사실일 것이라고 언급한 적이 없습니다. 그래서 문제는 이런 식으로 대답할 수 없습니다.

내 모든 연구가 누군가에게 도움이 되기를 바랍니다.

관련 정보