Исправлен идентификатор машины (uuid.getnode)

Я пытаюсь найти что-то, что я могу использовать в качестве уникальной строки/номера для моего скрипта, который зафиксирован на машине и легко доступен (кроссплатформенный). Я предполагаю, что у машины будет сетевая карта. Мне не нужно, чтобы он был действительно уникальным, но необходимо, чтобы он был исправлен в долгосрочной перспективе и как можно реже.

Я знаю, что MAC можно изменить, и я, вероятно, сделаю предупреждение об этом в своем сценарии, однако я не ожидаю, что кто-либо будет менять MAC каждое утро.

Я придумал uuid.getnode(), но в документации есть:

Если все попытки получить аппаратный адрес не удаются, мы выбираем случайное 48-битное число

Означает ли это, что для каждого вызова функции я получаю другое случайное число, поэтому невозможно использовать его, если MAC недоступен?

... на машине с несколькими сетевыми интерфейсами может быть возвращен MAC-адрес любого из них.

Означает ли это предложение, что getnode() получает случайный (или первый) MAC из всех доступных? Что если он получит MAC A при первом запуске и MAC B в следующий раз? Не было бы проблем, если бы я получил фиксированный список (сортировать, объединять, тадааа!)

Я спрашиваю, потому что у меня нет способа как это проверить самому.

Ответ 1

Мне удалось проверить первую часть на моем устройстве Android и на каждом новом запуске python создать произвольное число, поэтому для этой цели оно неприменимо.

Второй тип проблемы утонул сам, потому что если в документах он упоминал, что он может возвращать any one of them, тогда это не то, на что вы могли бы положиться (+ я не мог найти машину, на которой я мог бы ее протестировать). Хороший пакет netifaces пришел на помощь, что делает аналогичную вещь

netifaces.interfaces() # returns e.g. ['lo', 'eth0', 'tun2']

netifaces.ifaddresses('eth0')[netifaces.AF_LINK]
# returns [{'addr': '08:00:27:50:f2:51', 'broadcast': 'ff:ff:ff:ff:ff:ff'}]

Однако я скорее отказался от использования MAC-адресов, я получил что-то более стабильное.

Теперь к идентификаторам:

1) Windows:

Выполнение этого и получение вывода может быть достаточно хорошим:

wmic csproduct get UUID

или тот, который я использовал и доступен в реестре (HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography):

import _winreg
registry = _winreg.HKEY_LOCAL_MACHINE
address = 'SOFTWARE\\Microsoft\\Cryptography'
keyargs = _winreg.KEY_READ | _winreg.KEY_WOW64_64KEY
key = _winreg.OpenKey(registry, address, 0, keyargs)
value = _winreg.QueryValueEx(key, 'MachineGuid')
_winreg.CloseKey(key)
unique = value[0]

2) Linux:

/sys/class/dmi/id/board_serial

или

/sys/class/dmi/id/product_uuid

или если не root:

cat /var/lib/dbus/machine-id

3) Android:

Если вы работаете с python и не хотите вмешиваться в Java-материал, это должно работать очень хорошо:

import subprocess
cmd = ['getprop', 'ril.serialnumber']
self.unique = subprocess.check_output(cmd)[:-1]

но если вам нравится Java, то перейдите этот ответ, хотя даже ANDROID_ID уникальность довольно дискуссионная, если она позволила изменить, поэтому, скорее всего, серийный номер более безопасная ставка.

Обратите внимание, что, как уже упоминалось в связанном ответе, даже ril.serialnumber может быть пустым или пустым или отсутствующим (отсутствующий ключ). То же самое происходит и с официальным Android API, где он четко заявил об этом:

Серийный номер оборудования, , если он доступен.

Mac/iPhone: Я не мог найти какое-либо решение, поскольку у меня нет доступа к ним, но если есть переменная, содержащая значение идентификатора машины, то вы сможете получить там простой subprocess.check_output()

Ответ 2

Для Mac/iphone вы можете попробовать выполнить команду ниже:

import subprocess
subprocess.check_output("ioreg -rd1 -c IOPlatformExpertDevice | grep -E '(UUID)'", shell=True).split('"')[-2] # for me i got it on list value -2 if having any trouble try getting it with any alternative list element.

Ответ 3

/var/lib/dbus/machine-id можно легко подделать. как насчет /proc/cpuinfo? ENTRY (Serial) Предположительно, это перезаписывается при каждой загрузке с серийным номером процессора