Get a unique computer ID in Python on windows and linux

前端 未结 12 911
野趣味
野趣味 2020-11-29 02:27

I\'d like to get an id unique to a computer with Python on Windows and Linux. It could be the CPU ID, the motherboard serial, ... or anything else.

I looked at sever

相关标签:
12条回答
  • 2020-11-29 02:47

    There seems to be no direct "python" way of doing this. On modern PC hardware, there usually is an UUID stored in the BIOS - on Linux there is a command line utility dmidecode that can read this; example from my desktop:

    System Information
            Manufacturer: Dell Inc.
            Product Name: OptiPlex 755                 
            Version: Not Specified
            Serial Number: 5Y8YF3J
            UUID: 44454C4C-5900-1038-8059-B5C04F46334A
            Wake-up Type: Power Switch
            SKU Number: Not Specified
            Family: Not Specified
    

    The problem with MAC addresses is that usually you can easily change them programmatically (at least if you run the OS in a VM)

    On Windows, you can use this C API

    0 讨论(0)
  • 2020-11-29 02:47

    Invoke one of these in the shell or through a pipe in Python to get the hardware serial number of Apple machines running OS X >= 10.5:

    /usr/sbin/system_profiler SPHardwareDataType | fgrep 'Serial' | awk '{print $NF}'

    or

    ioreg -l | awk '/IOPlatformSerialNumber/ { print $4 }' | sed s/\"//g

    BTW: MAC addresses are not a good idea: there can be >1 network cards in a machine, and MAC addresses can be spoofed.

    0 讨论(0)
  • 2020-11-29 02:49

    I found something else that I'm using. Mac address for linux, MachineGuid for windows and there is also something for mac.

    More details here: http://www.serialsense.com/blog/2011/02/generating-unique-machine-ids/

    0 讨论(0)
  • 2020-11-29 02:51

    This should work on windows:

    import subprocess
    current_machine_id = subprocess.check_output('wmic csproduct get uuid').split('\n')[1].strip()
    
    0 讨论(0)
  • 2020-11-29 02:51

    2019 Answer (for Windows):

    from typing import Optional
    import re
    import subprocess
    import uuid
    
    def get_windows_uuid() -> Optional[uuid.UUID]:
        try:
            # Ask Windows for the device's permanent UUID. Throws if command missing/fails.
            txt = subprocess.check_output("wmic csproduct get uuid").decode()
    
            # Attempt to extract the UUID from the command's result.
            match = re.search(r"\bUUID\b[\s\r\n]+([^\s\r\n]+)", txt)
            if match is not None:
                txt = match.group(1)
                if txt is not None:
                    # Remove the surrounding whitespace (newlines, space, etc)
                    # and useless dashes etc, by only keeping hex (0-9 A-F) chars.
                    txt = re.sub(r"[^0-9A-Fa-f]+", "", txt)
    
                    # Ensure we have exactly 32 characters (16 bytes).
                    if len(txt) == 32:
                        return uuid.UUID(txt)
        except:
            pass # Silence subprocess exception.
    
        return None
    
    print(get_windows_uuid())
    

    Uses Windows API to get the computer's permanent UUID, then processes the string to ensure it's a valid UUID, and lastly returns a Python object (https://docs.python.org/3/library/uuid.html) which gives you convenient ways to use the data (such as 128-bit integer, hex string, etc).

    Good luck!

    PS: The subprocess call could probably be replaced with ctypes directly calling Windows kernel/DLLs for the Win32_ComputerSystemProduct API (which is what wmic uses internally). But then you have to be very careful and ensure that you call it properly on all systems. For my purposes this wmic-based function is safer and is all I need. It does strong validation and produces correct results. And if the wmic output is wrong or if the command is missing, our function returns None to let you handle that any way you want (such as generating a random UUID and saving it in your app's config file instead).

    0 讨论(0)
  • 2020-11-29 02:52

    Funny! But uuid.getnode return the same value as dmidecode.exe.

    subprocess.Popen('dmidecode.exe -s system-uuid'.split())
    
    00000000-0000-0000-0000-001FD088565A
    
    import uuid    
    uuid.UUID(int=uuid.getnode())
    
    UUID('00000000-0000-0000-0000-001fd088565a')
    
    0 讨论(0)
提交回复
热议问题