赞
踩
48位mac地址+16位进程号+32位时间戳+8位时间戳内偏移量
48位mac地址保证了同一机器上生成的uuid不会和其他机器冲突
16位进程号保证了同一机器上的不同进程生成的uuid不冲突
32位时间戳保证了同一进程上不同时间生成的uuid不冲突
8位时间戳内偏移量保证了同一进程同一时间生成的uuid不唯一
这样子,我们的uuid就是全世界唯一的了
package main import ( "fmt" "net" "os" "strings" "time" ) var lastTimestamp int64 = time.Now().Unix() var count byte = 0 func main() { fmt.Println(getUUIDBytes()) } func getUUIDBytes() []byte { //最终存放的字节数组 uuidBytes := make([]byte, 13) offset := 0 copy(uuidBytes[offset:], getPidBytes()) offset += 2 copy(uuidBytes[offset:], getLocalMacBytes()) offset += 6 copy(uuidBytes[offset:], getTimestampBytes()) offset += 4 copy(uuidBytes[offset:], getCountInTimeBytes()) return uuidBytes } //16进制字符转数字 func hexCharToNum(hex byte) byte { if hex >= 'a' { return hex - 'a' + 10 } if hex >= 'A' { return hex - 'A' + 10 } return hex - '0' } // 获取时间戳内偏移量 func getCountInTimeBytes() []byte { bytes := make([]byte, 1) now := time.Now().Unix() if now == lastTimestamp { count++ } else { count = 0 } lastTimestamp = now bytes[0] = count return bytes } // 获取时间戳的byte[]数组 func getTimestampBytes() []byte { bytes := make([]byte, 4) timestamp := uint32(time.Now().Unix()) for i := 3; i >= 0; i-- { bytes[i] = byte(timestamp) timestamp >>= 8 } return bytes } // 获取本程序的进程号byte[]数组 func getPidBytes() []byte { bytes := make([]byte, 2) pid := uint16(os.Getpid()) bytes[0] = byte(pid >> 8) bytes[1] = byte(pid) return bytes } // 获取本机的MAC地址byte[]数组 func getLocalMacBytes() []byte { bytes := make([]byte, 6) interfaces, err := net.Interfaces() if err != nil { return nil } macString := "" for _, inter := range interfaces { macString = inter.HardwareAddr.String() break } if macString == "" { return nil } macStrSplits := strings.Split(macString, ":") for index, split := range macStrSplits { bytes[index] = hexCharToNum(split[0])<<4 + hexCharToNum(split[1]) } return bytes }
输出:
[37 184 0 78 1 158 184 47 99 31 44 217 1]
处理结果:
这里程序生成的是一个长度为13的byte数组,具体如何把这个数组转成一个用户友好的字符串方法有很多,比如6字节6字节为一个单位映射成字符。具体不作实现。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。