内容简介:这里仅根据CPU、系统GUID和MAC地址来生成的机器码。WINDOWS下貌似无法获取硬盘序列号(没找到怎么获取)
package main import ( "context" "crypto/md5" "crypto/rand" "encoding/base64" "encoding/hex" "errors" "fmt" "github.com/StackExchange/wmi" "golang.org/x/sys/windows" "net" "sort" "strings" "time" "unsafe" ) func main(){ t := time.Now() a:=GetPhysicalID() fmt.Println(time.Since(t), a) } func GetPhysicalID() string{ var ids []string if guid,err := getMachineGuid(); err != nil{ panic(err.Error()) }else{ ids = append(ids, guid) } if cpuinfo,err := getCPUInfo();err != nil && len(cpuinfo) > 0 { panic(err.Error()) }else{ ids = append(ids, cpuinfo[0].VendorID+cpuinfo[0].PhysicalID) } if mac,err := getMACAddress();err!=nil{ panic(err.Error()) }else{ ids = append(ids, mac) } sort.Strings(ids) idsstr := strings.Join(ids, "|/|") return GetMd5String(idsstr,true,true) } func getMACAddress() (string, error){ netInterfaces, err := net.Interfaces() if err != nil { panic(err.Error()) } mac,macerr := "",errors.New("无法获取到正确的MAC地址") for i := 0; i < len(netInterfaces); i++ { //fmt.Println(netInterfaces[i]) if (netInterfaces[i].Flags & net.FlagUp) != 0 && (netInterfaces[i].Flags & net.FlagLoopback) == 0{ addrs, _ := netInterfaces[i].Addrs() for _, address := range addrs { ipnet, ok := address.(*net.IPNet) //fmt.Println(ipnet.IP) if ok && ipnet.IP.IsGlobalUnicast() { // 如果IP是全局单拨地址,则返回MAC地址 mac = netInterfaces[i].HardwareAddr.String() return mac,nil } } } } return mac,macerr } type cpuInfo struct { CPU int32 `json:"cpu"` VendorID string `json:"vendorId"` PhysicalID string `json:"physicalId"` } type win32_Processor struct { Manufacturer string ProcessorID *string } func getCPUInfo() ([]cpuInfo, error) { var ret []cpuInfo var dst []win32_Processor q := wmi.CreateQuery(&dst, "") fmt.Println(q) if err := wmiQuery(q, &dst); err != nil { return ret, err } var procID string for i, l := range dst { procID = "" if l.ProcessorID != nil { procID = *l.ProcessorID } cpu := cpuInfo{ CPU: int32(i), VendorID: l.Manufacturer, PhysicalID: procID, } ret = append(ret, cpu) } return ret, nil } // WMIQueryWithContext - wraps wmi.Query with a timed-out context to avoid hanging func wmiQuery(query string, dst interface{}, connectServerArgs ...interface{}) error { ctx := context.Background() if _, ok := ctx.Deadline(); !ok { ctxTimeout, cancel := context.WithTimeout(ctx, 3000000000)//超时时间3s defer cancel() ctx = ctxTimeout } errChan := make(chan error, 1) go func() { errChan <- wmi.Query(query, dst, connectServerArgs...) }() select { case <-ctx.Done(): return ctx.Err() case err := <-errChan: return err } } func getMachineGuid() (string, error) { // there has been reports of issues on 32bit using golang.org/x/sys/windows/registry, see https://github.com/shirou/gopsutil/pull/312#issuecomment-277422612 // for rationale of using windows.RegOpenKeyEx/RegQueryValueEx instead of registry.OpenKey/GetStringValue var h windows.Handle err := windows.RegOpenKeyEx(windows.HKEY_LOCAL_MACHINE, windows.StringToUTF16Ptr(`SOFTWARE\Microsoft\Cryptography`), 0, windows.KEY_READ|windows.KEY_WOW64_64KEY, &h) if err != nil { return "", err } defer windows.RegCloseKey(h) const windowsRegBufLen = 74 // len(`{`) + len(`abcdefgh-1234-456789012-123345456671` * 2) + len(`}`) // 2 == bytes/UTF16 const uuidLen = 36 var regBuf [windowsRegBufLen]uint16 bufLen := uint32(windowsRegBufLen) var valType uint32 err = windows.RegQueryValueEx(h, windows.StringToUTF16Ptr(`MachineGuid`), nil, &valType, (*byte)(unsafe.Pointer(®Buf[0])), &bufLen) if err != nil { return "", err } hostID := windows.UTF16ToString(regBuf[:]) hostIDLen := len(hostID) if hostIDLen != uuidLen { return "", fmt.Errorf("HostID incorrect: %q\n", hostID) } return hostID, nil } //生成32位md5字串 func GetMd5String(s string, upper bool, half bool) string { h := md5.New() h.Write([]byte(s)) result := hex.EncodeToString(h.Sum(nil)) if upper == true { result = strings.ToUpper(result) } if half == true { result = result[8:24] } return result } //利用随机数生成Guid字串 func UniqueId() string { b := make([]byte, 48) if _,err := rand.Read(b); err!=nil{ return "" } return GetMd5String(base64.URLEncoding.EncodeToString(b), true,false) }
这里仅根据CPU、系统GUID和MAC地址来生成的机器码。WINDOWS下貌似无法获取硬盘序列号(没找到怎么获取)
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- Go 程序到机器码的编译之旅
- 指令集架构、机器码与 Go 语言
- [译] Go 程序到机器码的编译之旅
- Go 程序是如何编译成目标机器码的
- Android ART JVM中和机器码编译有关的小知识
- 不依赖OS编译器,不依赖库,用汇编/机器码直接编程
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。