package public import ( "crypto/md5" "encoding/hex" "encoding/json" "fmt" "io/ioutil" "os" "os/exec" "runtime" "strconv" "strings" ) const ( DMIDECODE = "dmidecode" ) func CheckCmdExists(command string) (string, error) { path, err := exec.LookPath(command) if err != nil { if runtime.GOOS != "darwin" || //macos,windows测试使用,不获取硬盘分区UUID runtime.GOOS != "windows" { fmt.Printf("didn't find 'blkid' executable,err %s\n", err.Error()) } return "", err } return path, nil } func IsExistFile(path string) bool { _, err := os.Stat(path) //os.Stat获取文件信息 if err != nil { if os.IsExist(err) { return true } return false } return true } func ReadSysFile(filePath string) ([]byte, error) { isExist := IsExistFile(filePath) if isExist == false { return nil, fmt.Errorf("%s file does not exist", filePath) } fd, err := os.OpenFile(filePath, os.O_RDONLY, 0644) if err != nil { if os.IsPermission(err) { return nil, fmt.Errorf("%s", "permission denied get machine id") } return nil, fmt.Errorf("%s", "get machine id failed") } defer fd.Close() fstabText, err := ioutil.ReadAll(fd) if err != nil { return nil, err } return fstabText, nil } //降低数字串长度 func Sum(data []byte) string { var ( sum uint64 length int = len(data) index int ) //以32位求和 for length >= 4 { sum += uint64(data[index])<<24 + uint64(data[index+1])<<16 + uint64(data[index+2])<<8 + uint64(data[index+3]) index += 4 length -= 4 } switch length { case 3: sum += uint64(data[index])<<16 + uint64(data[index+1])<<8 + uint64(data[index+2]) case 2: sum += uint64(data[index])<<8 + uint64(data[index+1]) case 1: sum += uint64(data[index]) case 0: break } return strconv.FormatUint(sum, 16) } //获取BIOS出厂UUID func GetProductUUID() (string, error) { if runtime.GOOS == "darwin" { return GetProductUUIDMac() } if runtime.GOOS == "windows" { return GetProductUUIDWin() } cmd := exec.Command("dmidecode", "-s", "system-uuid") output, err := cmd.CombinedOutput() if err != nil { return "", err } if len(output) == 0 { return "", fmt.Errorf("%s", "uuid is empty string") } system_uuid := string(output) cmd = exec.Command("dmidecode", "-s", "system-serial-number") output, err = cmd.CombinedOutput() if err != nil { return "", err } if len(output) == 0 { return "", fmt.Errorf("%s", "serial-number is empty string") } system_serial_number := string(output) deviceID := system_uuid + "_starwiz_" + system_serial_number return GetMd5String(deviceID), nil } /* GetMachineID 获取机器ID (分区UUID和网卡地址 or Product UUID) */ func GetMachineID() (string, error) { var ( MachineIDList []string ) productUUID, err := GetProductUUID() if err != nil { return "", err } MachineIDList = append(MachineIDList, productUUID) //编码 encByte, err := json.Marshal(MachineIDList) if err != nil { return "", err } //降低长度 return Sum(encByte), nil } func GetMd5String(s string) string { h := md5.New() h.Write([]byte(s)) return hex.EncodeToString(h.Sum(nil)) } func GetProductUUIDMac() (string, error) { // 从系统调用获取硬件 UUID out, err := exec.Command("system_profiler", "SPHardwareDataType").Output() if err != nil { return "", err } // 解析输出以获取 UUID lines := strings.Split(string(out), "\n") for _, line := range lines { if strings.Contains(line, "Hardware UUID:") { parts := strings.Split(line, ":") if len(parts) == 2 { return strings.TrimSpace(parts[1]), nil } } } return "", fmt.Errorf("could not find hardware UUID in system_profiler output") } func GetProductUUIDWin() (string, error) { // 使用系统调用获取计算机的注册表信息 out, err := exec.Command("reg", "query", "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography", "/v", "MachineGuid").Output() if err != nil { return "", err } // 解析注册表输出以获取 MachineGuid lines := strings.Split(string(out), "\n") for _, line := range lines { if strings.Contains(line, "REG_SZ") { parts := strings.Fields(line) if len(parts) >= 3 { return strings.TrimSpace(parts[2]), nil } } } return "", fmt.Errorf("MachineGuid not found in registry") }