├── .gitignore ├── go.mod ├── go.sum ├── machine_demo.go ├── README.md └── machine ├── windows.go ├── machine_code.go ├── linux.go └── mac.go /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | *.log 3 | logs/ 4 | urldb 5 | urldb.db 6 | *.zip 7 | *.exe 8 | release 9 | static 10 | driver 11 | build 12 | doc 13 | *.lock -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/soxft/go-machine-code 2 | 3 | go 1.19 4 | 5 | require github.com/tidwall/gjson v1.17.0 6 | 7 | require ( 8 | github.com/tidwall/match v1.1.1 // indirect 9 | github.com/tidwall/pretty v1.2.1 // indirect 10 | ) 11 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/soxft/go-machine-code v0.0.0-20240103154945-1ab849533250 h1:WV4XlWzrdaPxCGA8OQ3lMlIXxEXpfldWUWyU04WwC1s= 2 | github.com/soxft/go-machine-code v0.0.0-20240103154945-1ab849533250/go.mod h1:2n1+W6xUX4pdBsJhtqTi0ZSWeMVm8znaYu0L8CFBIJU= 3 | github.com/tidwall/gjson v1.17.0 h1:/Jocvlh98kcTfpN2+JzGQWQcqrPQwDrVEMApx/M5ZwM= 4 | github.com/tidwall/gjson v1.17.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= 5 | github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= 6 | github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= 7 | github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= 8 | github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= 9 | github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= 10 | -------------------------------------------------------------------------------- /machine_demo.go: -------------------------------------------------------------------------------- 1 | /* 2 | author: superl[N.S.T] 3 | github: https://github.com/super-l/ 4 | */ 5 | package main 6 | 7 | import ( 8 | "encoding/json" 9 | "fmt" 10 | 11 | "github.com/soxft/go-machine-code/machine" 12 | ) 13 | 14 | // https://www.icode9.com/content-3-710187.html go 获取linux cpuId 的方法 15 | func main() { 16 | serialNumber, err := machine.GetSerialNumber() 17 | if err != nil { 18 | fmt.Println(err.Error()) 19 | } 20 | fmt.Println("serialNumber = ", serialNumber) 21 | 22 | uuid, err := machine.GetPlatformUUID() 23 | if err != nil { 24 | fmt.Println(err.Error()) 25 | } 26 | fmt.Println("uuid = ", uuid) 27 | 28 | cpuid, err := machine.GetCpuId() 29 | if err != nil { 30 | fmt.Println(err.Error()) 31 | } 32 | fmt.Println("cpuid = ", cpuid) 33 | 34 | macInfo, err := machine.GetMACAddress() 35 | if err != nil { 36 | fmt.Println(err.Error()) 37 | } 38 | fmt.Println("mac = ", macInfo) 39 | 40 | machineData := machine.GetMachineData() 41 | result, err := json.Marshal(machineData) 42 | if err != nil { 43 | fmt.Println(err.Error()) 44 | } 45 | fmt.Println(string(result)) 46 | } 47 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### 一、程序简介 2 | 3 | machine-code,是GO语言实现的跨平台机器码(硬件信息)获取程序,包括PlatformUUID、SerialNumber、MAC网卡信息、CPUID信息等。同时支持windows、Linux、mac等系统! 4 | 5 | 6 | #### 支持的系统: 7 | windows 8 | linux 9 | mac 10 | 11 | #### 目前可获取的信息 12 | PlatformUUID 13 | SerialNumber 14 | MAC网卡信息 15 | CPUID 16 | 17 | ### 二、安装说明 18 | 19 | ``` 20 | $ go get github.com/soxft/go-machine-code/machine 21 | ``` 22 | 23 | 24 | ### 三、实例代码 25 | 26 | #### 1:单独获取信息 27 | ``` 28 | serialNumber, err := machine.GetSerialNumber() 29 | if err != nil { 30 | fmt.Println(err.Error()) 31 | } 32 | fmt.Println("serialNumber = ", serialNumber) 33 | 34 | uuid, err := machine.GetPlatformUUID() 35 | if err != nil { 36 | fmt.Println(err.Error()) 37 | } 38 | fmt.Println("uuid = ", uuid) 39 | 40 | cpuid, err := machine.GetCpuId() 41 | if err != nil { 42 | fmt.Println(err.Error()) 43 | } 44 | fmt.Println("cpuid = ", cpuid) 45 | 46 | macInfo, err := machine.GetMACAddress() 47 | if err != nil { 48 | fmt.Println(err.Error()) 49 | } 50 | fmt.Println("mac = ", macInfo) 51 | ``` 52 | 53 | 运行结果: 54 | 55 | ``` 56 | serialNumber = C02P7676XXXX 57 | uuid = 748869E5-06B6-5855-A0A4-7E19497XXXXX 58 | cpuid = 0x00040000 59 | mac = 34:36:3b:XX:XX:XX 60 | 61 | ``` 62 | 63 | #### 2:获取全部信息 64 | 65 | 实例代码: 66 | ``` 67 | machineData := machine.GetMachineData() 68 | result, err := json.Marshal(machineData) 69 | if err != nil { 70 | fmt.Println(err.Error()) 71 | } 72 | fmt.Println(string(result)) 73 | ``` 74 | 75 | 运行结果: 76 | 77 | ``` 78 | { 79 | "platformUUID": "748869E5-06B6-5855-A0A4-7E19497XXXXX", 80 | "serialNumber": "C02P767XXXXX", 81 | "cpuId": "0x00040000", 82 | "mac": "34:36:3b:XX:XX:XX" 83 | } 84 | 85 | ``` 86 | 87 | ## 修改自 88 | ``` 89 | author: superl[N.S.T] 90 | github: https://github.com/super-l/ 91 | 92 | ``` -------------------------------------------------------------------------------- /machine/windows.go: -------------------------------------------------------------------------------- 1 | package machine 2 | 3 | import ( 4 | "os/exec" 5 | "strings" 6 | ) 7 | 8 | type WindowsMachine struct{} 9 | 10 | func (WindowsMachine) getMachine() MachineData { 11 | machineData := MachineData{} 12 | machineData.PlatformUUID, _ = GetPlatformUUID() 13 | machineData.SerialNumber, _ = GetSerialNumber() 14 | machineData.CpuId, _ = GetCpuId() 15 | return machineData 16 | } 17 | 18 | func (WindowsMachine) getSerialNumber() (serialNumber string, err error) { 19 | // wmic baseboard get serialnumber 20 | cmd := exec.Command("wmic", "baseboard", "get", "serialnumber") 21 | b, e := cmd.CombinedOutput() 22 | if e == nil { 23 | serialNumber = string(b) 24 | serialNumber = serialNumber[12 : len(serialNumber)-2] 25 | serialNumber = strings.ReplaceAll(serialNumber, "\n", "") 26 | serialNumber = strings.ReplaceAll(serialNumber, " ", "") 27 | serialNumber = strings.ReplaceAll(serialNumber, "\r", "") 28 | if len(serialNumber) < 8 { 29 | // 服务器 无主板序列号 30 | puuid, _ := GetPlatformUUID() 31 | mac, _ := GetMACAddress() 32 | cpuId, _ := GetCpuId() 33 | serialNumber = puuid[0:4] + mac[0:2] + cpuId[0:2] 34 | serialNumber = strings.ToUpper(serialNumber) 35 | } 36 | 37 | return serialNumber, nil 38 | } else { 39 | return "", nil 40 | } 41 | return serialNumber, nil 42 | } 43 | 44 | func (WindowsMachine) getPlatformUUID() (uuid string, err error) { 45 | // wmic csproduct get uuid 46 | var cmd *exec.Cmd 47 | cmd = exec.Command("wmic", "csproduct", "get", "uuid") 48 | b, e := cmd.CombinedOutput() 49 | 50 | if e == nil { 51 | uuid = string(b) 52 | uuid = uuid[4 : len(uuid)-1] 53 | uuid = strings.ReplaceAll(uuid, "\n", "") 54 | uuid = strings.ReplaceAll(uuid, " ", "") 55 | uuid = strings.ReplaceAll(uuid, "\r", "") 56 | } else { 57 | return "", nil 58 | } 59 | return uuid, nil 60 | } 61 | 62 | func (WindowsMachine) getCpuId() (cpuId string, err error) { 63 | // wmic cpu get processorid 64 | var cpuid string 65 | cmd := exec.Command("wmic", "cpu", "get", "processorid") 66 | b, e := cmd.CombinedOutput() 67 | 68 | if e == nil { 69 | cpuid = string(b) 70 | cpuid = cpuid[12 : len(cpuid)-2] 71 | cpuid = strings.ReplaceAll(cpuid, "\n", "") 72 | cpuid = strings.ReplaceAll(cpuid, " ", "") 73 | cpuid = strings.ReplaceAll(cpuid, "\r", "") 74 | } else { 75 | return "", nil 76 | } 77 | return cpuid, nil 78 | } 79 | -------------------------------------------------------------------------------- /machine/machine_code.go: -------------------------------------------------------------------------------- 1 | package machine 2 | 3 | import ( 4 | "crypto/md5" 5 | "encoding/hex" 6 | "errors" 7 | "net" 8 | "runtime" 9 | "strings" 10 | ) 11 | 12 | type MachineData struct { 13 | PlatformUUID string `json:"platformUUID"` 14 | SerialNumber string `json:"serialNumber"` 15 | CpuId string `json:"cpuId"` 16 | Mac string `json:"mac"` 17 | } 18 | 19 | func GetMachineData() (data MachineData) { 20 | if runtime.GOOS == "darwin" { 21 | sysInfo, _ := MacMachine{}.getMacSysInfo() 22 | sysInfo.Mac, _ = GetMACAddress() 23 | return sysInfo 24 | } else if runtime.GOOS == "linux" { 25 | machineData := MachineData{} 26 | machineData.SerialNumber, _ = LinuxMachine{}.getSerialNumber() 27 | machineData.PlatformUUID, _ = LinuxMachine{}.getPlatformUUID() 28 | machineData.CpuId, _ = LinuxMachine{}.getCpuId() 29 | machineData.Mac, _ = GetMACAddress() 30 | return machineData 31 | } else if runtime.GOOS == "windows" { 32 | machineData := MachineData{} 33 | machineData.SerialNumber, _ = WindowsMachine{}.getSerialNumber() 34 | machineData.PlatformUUID, _ = WindowsMachine{}.getPlatformUUID() 35 | machineData.CpuId, _ = WindowsMachine{}.getCpuId() 36 | machineData.Mac, _ = GetMACAddress() 37 | return machineData 38 | } 39 | return MachineData{} 40 | } 41 | 42 | func GetSerialNumber() (data string, err error) { 43 | if runtime.GOOS == "darwin" { 44 | return MacMachine{}.getSerialNumber() 45 | } else if runtime.GOOS == "linux" { 46 | return LinuxMachine{}.getSerialNumber() 47 | } else if runtime.GOOS == "windows" { 48 | return WindowsMachine{}.getSerialNumber() 49 | } 50 | return "", nil 51 | } 52 | 53 | func GetPlatformUUID() (data string, err error) { 54 | if runtime.GOOS == "darwin" { 55 | return MacMachine{}.getPlatformUUID() 56 | } else if runtime.GOOS == "linux" { 57 | return LinuxMachine{}.getPlatformUUID() 58 | } else if runtime.GOOS == "windows" { 59 | return WindowsMachine{}.getPlatformUUID() 60 | } 61 | return "", nil 62 | } 63 | 64 | func GetCpuId() (data string, err error) { 65 | if runtime.GOOS == "darwin" { 66 | return MacMachine{}.getCpuId() 67 | } else if runtime.GOOS == "linux" { 68 | return LinuxMachine{}.getCpuId() 69 | } else if runtime.GOOS == "windows" { 70 | return WindowsMachine{}.getCpuId() 71 | } 72 | return "", nil 73 | } 74 | 75 | func GetMACAddress() (string, error) { 76 | netInterfaces, err := net.Interfaces() 77 | if err != nil { 78 | return "", err 79 | } 80 | var mac string 81 | for i := 0; i < len(netInterfaces); i++ { 82 | if (netInterfaces[i].Flags&net.FlagUp) != 0 && (netInterfaces[i].Flags&net.FlagLoopback) == 0 { 83 | addrs, _ := netInterfaces[i].Addrs() 84 | for _, address := range addrs { 85 | ipnet, ok := address.(*net.IPNet) 86 | if ok && ipnet.IP.IsGlobalUnicast() { 87 | mac = netInterfaces[i].HardwareAddr.String() 88 | return mac, nil 89 | } 90 | } 91 | } 92 | } 93 | return mac, errors.New("无法获取到正确的MAC地址") 94 | } 95 | 96 | func GetMd5String(s string, upper bool, half bool) string { 97 | h := md5.New() 98 | h.Write([]byte(s)) 99 | result := hex.EncodeToString(h.Sum(nil)) 100 | if upper == true { 101 | result = strings.ToUpper(result) 102 | } 103 | if half == true { 104 | result = result[8:24] 105 | } 106 | return result 107 | } 108 | -------------------------------------------------------------------------------- /machine/linux.go: -------------------------------------------------------------------------------- 1 | package machine 2 | 3 | import ( 4 | "bytes" 5 | "errors" 6 | "os" 7 | "os/exec" 8 | "strings" 9 | ) 10 | 11 | type LinuxMachine struct{} 12 | 13 | func (LinuxMachine) getMachine() MachineData { 14 | machineData := MachineData{} 15 | machineData.PlatformUUID, _ = GetPlatformUUID() 16 | machineData.SerialNumber, _ = GetSerialNumber() 17 | machineData.CpuId, _ = GetCpuId() 18 | return machineData 19 | } 20 | 21 | func (LinuxMachine) getSerialNumber() (serialNumber string, err error) { 22 | // dmidecode -s system-serial-number 序列号 23 | var cmd *exec.Cmd 24 | cmd = exec.Command("dmidecode", "-s", "system-serial-number") 25 | 26 | var out bytes.Buffer 27 | cmd.Stdout = &out 28 | cmd.Stderr = os.Stderr 29 | 30 | err = cmd.Start() 31 | if err != nil { 32 | return "", err 33 | } 34 | err = cmd.Wait() 35 | if err == nil { 36 | serial_number := out.String() 37 | serial_number = strings.Replace(serial_number, "\n", "", -1) 38 | return serial_number, nil 39 | } else { 40 | return "", err 41 | } 42 | } 43 | 44 | func (LinuxMachine) getPlatformUUID() (UUID string, err error) { 45 | // dmidecode -s system-uuid UUID 46 | var cmd *exec.Cmd 47 | cmd = exec.Command("dmidecode", "-s", "system-uuid") 48 | 49 | var out bytes.Buffer 50 | cmd.Stdout = &out 51 | cmd.Stderr = os.Stderr 52 | 53 | err = cmd.Start() 54 | if err != nil { 55 | return "", err 56 | } 57 | err = cmd.Wait() 58 | if err == nil { 59 | uuid := out.String() 60 | uuid = strings.Replace(uuid, "\n", "", -1) 61 | return uuid, nil 62 | } else { 63 | return "", err 64 | } 65 | } 66 | 67 | func (LinuxMachine) getCpuId2() (cpuId string, err error) { 68 | // dmidecode -t processor |grep ID |head -1 69 | var cmd *exec.Cmd 70 | cmd = exec.Command("dmidecode", "-t", "processor", "|grep ID |head -1") 71 | 72 | var out bytes.Buffer 73 | cmd.Stdout = &out 74 | cmd.Stderr = os.Stderr 75 | 76 | err = cmd.Start() 77 | if err != nil { 78 | return "", err 79 | } 80 | err = cmd.Wait() 81 | if err == nil { 82 | uuid := out.String() 83 | //uuid = strings.Replace(uuid, "\n", "", -1) 84 | return uuid, nil 85 | } else { 86 | return "", err 87 | } 88 | } 89 | 90 | func (LinuxMachine) getCpuId() (cpuId string, err error) { 91 | // dmidecode -t processor |grep ID |head -1 92 | cmds := []*exec.Cmd{ 93 | exec.Command("dmidecode", "-t", "processor"), 94 | exec.Command("grep", "ID"), 95 | exec.Command("head", "-1"), 96 | } 97 | cpuId, err = ExecPipeLine(cmds...) 98 | cpuId = strings.TrimSpace(cpuId) 99 | cpuId = strings.Replace(cpuId, "ID: ", "", -1) 100 | cpuId = strings.Replace(cpuId, "\t", "", -1) 101 | cpuId = strings.Replace(cpuId, "\n", "", -1) 102 | cpuId = strings.Replace(cpuId, " ", "-", -1) 103 | return 104 | } 105 | 106 | func Pipeline(cmds ...*exec.Cmd) (pipeLineOutput, collectedStandardError []byte, pipeLineError error) { 107 | if len(cmds) < 1 { 108 | return nil, nil, nil 109 | } 110 | 111 | var output bytes.Buffer 112 | var stderr bytes.Buffer 113 | 114 | last := len(cmds) - 1 115 | for i, cmd := range cmds[:last] { 116 | var err error 117 | if cmds[i+1].Stdin, err = cmd.StdoutPipe(); err != nil { 118 | return nil, nil, err 119 | } 120 | cmd.Stderr = &stderr 121 | } 122 | 123 | cmds[last].Stdout, cmds[last].Stderr = &output, &stderr 124 | 125 | for _, cmd := range cmds { 126 | if err := cmd.Start(); err != nil { 127 | return output.Bytes(), stderr.Bytes(), err 128 | } 129 | } 130 | 131 | for _, cmd := range cmds { 132 | if err := cmd.Wait(); err != nil { 133 | return output.Bytes(), stderr.Bytes(), err 134 | } 135 | } 136 | 137 | return output.Bytes(), stderr.Bytes(), nil 138 | } 139 | 140 | func ExecPipeLine(cmds ...*exec.Cmd) (string, error) { 141 | output, stderr, err := Pipeline(cmds...) 142 | if err != nil { 143 | return "", err 144 | } 145 | 146 | if len(output) > 0 { 147 | return string(output), nil 148 | } 149 | 150 | if len(stderr) > 0 { 151 | return string(stderr), nil 152 | } 153 | return "", errors.New("no returns") 154 | } 155 | -------------------------------------------------------------------------------- /machine/mac.go: -------------------------------------------------------------------------------- 1 | package machine 2 | 3 | import ( 4 | "bytes" 5 | "encoding/xml" 6 | "fmt" 7 | "os" 8 | "os/exec" 9 | "runtime" 10 | "strings" 11 | 12 | "github.com/tidwall/gjson" 13 | ) 14 | 15 | type MacMachine struct{} 16 | 17 | var macMachineData MachineData 18 | 19 | type macXmlStruct struct { 20 | XMLName xml.Name `xml:"plist"` 21 | Array macDataArrayStruct `xml:"array"` 22 | } 23 | 24 | type macDataArrayStruct struct { 25 | Dict macDictStruct `xml:"dict"` // 读取user数组 26 | } 27 | 28 | type macDictStruct struct { 29 | Key []string `xml:"key"` 30 | Real []string `xml:"real"` 31 | String []string `xml:"string"` 32 | Array macDictArrayStruct `xml:"array"` 33 | } 34 | 35 | type macDictArrayStruct struct { 36 | Dict macDictItemStruct `xml:"dict"` // 读取user数组 37 | } 38 | 39 | type macDictItemStruct struct { 40 | Key []string `xml:"key"` 41 | Integer []int `xml:"integer"` 42 | String []string `xml:"string"` 43 | } 44 | 45 | func (machine MacMachine) getSerialNumber() (data string, err error) { 46 | sysInfo, err := machine.getMacSysInfo() 47 | if err != nil { 48 | return "", err 49 | } 50 | return sysInfo.SerialNumber, err 51 | } 52 | 53 | func (machine MacMachine) getPlatformUUID() (UUID string, err error) { 54 | sysInfo, err := machine.getMacSysInfo() 55 | if err != nil { 56 | return "", err 57 | } 58 | return sysInfo.PlatformUUID, err 59 | } 60 | 61 | func (machine MacMachine) getCpuId() (cpuId string, err error) { 62 | sysInfo, err := machine.getMacSysInfo() 63 | if err != nil { 64 | return "", err 65 | } 66 | return sysInfo.CpuId, err 67 | } 68 | 69 | func (machine MacMachine) getMacSysInfo() (data MachineData, err error) { 70 | var cmd *exec.Cmd 71 | cmd = exec.Command("system_profiler", "SPHardwareDataType", "-xml") 72 | 73 | var out bytes.Buffer 74 | cmd.Stdout = &out 75 | cmd.Stderr = os.Stderr 76 | 77 | err = cmd.Start() 78 | if err != nil { 79 | fmt.Println(err.Error()) 80 | return 81 | } 82 | 83 | err = cmd.Wait() 84 | if err == nil { 85 | macMachineData, err = machine.macXmlToData(out.String()) 86 | if err == nil { 87 | cpuid, _ := machine.getSysCpuId() 88 | macMachineData.CpuId = cpuid 89 | } 90 | return macMachineData, nil 91 | } else { 92 | return MachineData{}, err 93 | } 94 | } 95 | 96 | func (MacMachine) macXmlToData(xmlcontent string) (MachineData, error) { 97 | x := macXmlStruct{} 98 | err := xml.Unmarshal([]byte(xmlcontent), &x) 99 | if err != nil { 100 | return MachineData{}, err 101 | } else { 102 | count := len(x.Array.Dict.Array.Dict.String) 103 | serialData := MachineData{ 104 | PlatformUUID: x.Array.Dict.Array.Dict.String[count-2], 105 | SerialNumber: x.Array.Dict.Array.Dict.String[count-1], 106 | CpuId: "", 107 | } 108 | return serialData, nil 109 | } 110 | } 111 | 112 | func (machine MacMachine) getSysCpuId() (cpuId string, err error) { 113 | //sysctl -x machdep.cpu.signature 114 | if runtime.GOARCH == "arm64" { 115 | // m1 116 | var cmd *exec.Cmd 117 | cmd = exec.Command("system_profiler", "SPHardwareDataType", "-json") 118 | 119 | var out bytes.Buffer 120 | cmd.Stdout = &out 121 | cmd.Stderr = os.Stderr 122 | 123 | err = cmd.Start() 124 | if err != nil { 125 | return "", err 126 | } 127 | err = cmd.Wait() 128 | if err == nil { 129 | cpuId = out.String() 130 | data := gjson.Get(cpuId, "SPHardwareDataType.0.platform_UUID") 131 | return data.String(), nil 132 | } 133 | return "", nil 134 | } 135 | 136 | var cmd *exec.Cmd 137 | cmd = exec.Command("sysctl", "-x", "machdep.cpu.signature") 138 | 139 | var out bytes.Buffer 140 | cmd.Stdout = &out 141 | cmd.Stderr = os.Stderr 142 | 143 | err = cmd.Start() 144 | if err != nil { 145 | return "", err 146 | } 147 | err = cmd.Wait() 148 | if err == nil { 149 | cpuId = out.String() 150 | cpuId = strings.Replace(cpuId, " ", "", -1) 151 | cpuId = strings.Replace(cpuId, "\n", "", -1) 152 | cpuId = strings.Replace(cpuId, "machdep.cpu.signature:", "", -1) 153 | return cpuId, nil 154 | } else { 155 | return "", err 156 | } 157 | } 158 | --------------------------------------------------------------------------------