ag_toolsbox/serial_code/uuid/short_uuid.go

66 lines
1.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package uuid
import (
"unsafe"
"github.com/google/uuid"
)
const (
letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
MIN_LENGTH = 2 // 最小长度为2的原因是Go中整型长度最大为64位而UUID v4是128位长所以最小长度为2。
MAX_LENGTH = 128
)
// 将一个字节拆分成8个比特位并以一个8位长字节数组输出。
func breakByte(b byte) []byte {
bytes := make([]byte, 8)
for i := byte(0); i < 8; i++ {
mask := byte(0x1) << (7 - i)
bytes[i] = (b & mask) >> (7 - i)
}
return bytes
}
// 根据UUID v4生成一个指定长度的短UUID字符串。
func ShortUUID(length uint) string {
var uuidLength uint
if length < MIN_LENGTH {
uuidLength = MIN_LENGTH
} else if length > MAX_LENGTH {
uuidLength = MAX_LENGTH
} else {
uuidLength = length
}
// UUID是一个16字节长的字节数组每个字节都可以拆分成8个比特位共128比特位。
newUUID := uuid.New()
uuidBits := make([]byte, 0)
for _, b := range newUUID[:] {
uuidBits = append(uuidBits, breakByte(b)...)
}
var partitionLength uint = 0
if 128%uuidLength == 0 {
partitionLength = 128 / uuidLength
} else {
partitionLength = 128/uuidLength + 1
}
var paritionedUUID = make([][]byte, uuidLength)
for i := uint(0); i < uuidLength; i++ {
if i != uuidLength-1 {
paritionedUUID[i] = uuidBits[i*partitionLength : (i+1)*partitionLength]
} else {
paritionedUUID[i] = uuidBits[i*partitionLength:]
}
}
result := make([]byte, uuidLength)
for i := uint(0); i < uuidLength; i++ {
var assembledRune uint64 = 0
for j := uint(0); j < uint(len(paritionedUUID[i])); j++ {
assembledRune |= uint64(paritionedUUID[i][j]) << (partitionLength - j - 1)
}
result[i] = letters[assembledRune%uint64(len(letters))]
}
return *(*string)(unsafe.Pointer(&result))
}