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

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

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

MAC 주소나 하드 드라이브 일련번호 스푸핑과 같은 스푸핑으로부터 보호할 수 있다면 좋을 것입니다. 그러나 이것이 절대적인 요구사항은 아닙니다.

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

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

일반 사용자로 실행하려면 이 프로그램이 필요하므로 "dmidecode"와 같은 명령을 사용할 수 없습니다. MAC 주소를 사용하는 것 외에는 해결책이 없더라도 사용자가 Wi-Fi에서 이더넷으로 전환할 때 UUID가 변경되는 것을 원하지 않으므로 첫 번째 MAC 주소만 가져오는 것이 문제가 될 수 있습니다. 가장 중요한 점은 VMware 또는 VPN이 설치된 경우에도 UUID가 동일하게 유지되어야 한다는 것입니다. 따라서 모든 mac 주소를 얻는 것은 이전 도구가 더 많은 네트워크 인터페이스와 더 많은 mac 주소를 생성하여 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" 디렉터리에 대한 직접 심볼릭 링크가 됩니다. (커널을 Linux 4.3으로 업데이트하여 RHEL 6, Debian 7, Debian 8, Ubuntu 15 및 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의 이전 레이아웃(리눅스 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 어딘가에 "가상" 폴더가 있을 것이라는 사실에 의존하고 싶지 않다는 것입니다. 위에 링크된 규칙은 이것이 항상 사실이라고 말하지 않습니다. 그러므로 이 질문에는 이런 식으로 대답할 수 없습니다.

내 모든 연구가 다른 사람들에게 도움이 되기를 바랍니다.

관련 정보