github.com/whoyao/protocol@v0.0.0-20230519045905-2d8ace718ca5/utils/id.go (about) 1 package utils 2 3 import ( 4 "crypto/sha1" 5 "fmt" 6 "os" 7 8 "github.com/jxskiss/base62" 9 "github.com/lithammer/shortuuid/v4" 10 11 "github.com/whoyao/protocol/livekit" 12 ) 13 14 const guidSize = 12 15 16 const ( 17 RoomPrefix = "RM_" 18 NodePrefix = "ND_" 19 ParticipantPrefix = "PA_" 20 TrackPrefix = "TR_" 21 APIKeyPrefix = "API" 22 EgressPrefix = "EG_" 23 IngressPrefix = "IN_" 24 RPCPrefix = "RPC_" 25 WHIPResourcePrefix = "WH_" 26 ) 27 28 func NewGuid(prefix string) string { 29 return prefix + shortuuid.New()[:guidSize] 30 } 31 32 // Creates a hashed ID from a unique string 33 func HashedID(id string) string { 34 h := sha1.New() 35 h.Write([]byte(id)) 36 val := h.Sum(nil) 37 38 return base62.EncodeToString(val) 39 } 40 41 func LocalNodeID() (string, error) { 42 hostname, err := os.Hostname() 43 if err != nil { 44 return "", err 45 } 46 return fmt.Sprintf("%s%s", NodePrefix, HashedID(hostname)[:8]), nil 47 } 48 49 var b62Index = newB62Index() 50 var b62Chars = []byte(shortuuid.DefaultAlphabet) 51 52 func newB62Index() [256]byte { 53 var index [256]byte 54 for i := 0; i < len(shortuuid.DefaultAlphabet); i++ { 55 index[shortuuid.DefaultAlphabet[i]] = byte(i) 56 } 57 return index 58 } 59 60 func guidPrefix[T livekit.Guid]() string { 61 var id T 62 switch any(id).(type) { 63 case livekit.TrackID: 64 return TrackPrefix 65 case livekit.ParticipantID: 66 return ParticipantPrefix 67 case livekit.RoomID: 68 return RoomPrefix 69 default: 70 panic("unreachable") 71 } 72 } 73 74 func MarshalGuid[T livekit.Guid](id T) livekit.GuidBlock { 75 var b livekit.GuidBlock 76 idb := []byte(id)[len(guidPrefix[T]()):] 77 for i := 0; i < 3; i++ { 78 j := i * 3 79 k := i * 4 80 b[j] = b62Index[idb[k]]<<2 | b62Index[idb[k+1]]>>4 81 b[j+1] = b62Index[idb[k+1]]<<4 | b62Index[idb[k+2]]>>2 82 b[j+2] = b62Index[idb[k+2]]<<6 | b62Index[idb[k+3]] 83 } 84 return b 85 } 86 87 func UnmarshalGuid[T livekit.Guid](b livekit.GuidBlock) T { 88 prefix := guidPrefix[T]() 89 id := make([]byte, len(prefix)+guidSize) 90 copy(id, []byte(prefix)) 91 idb := id[len(prefix):] 92 for i := 0; i < 3; i++ { 93 j := i * 3 94 k := i * 4 95 idb[k] = b62Chars[b[j]>>2] 96 idb[k+1] = b62Chars[(b[j]&3)<<4|b[j+1]>>4] 97 idb[k+2] = b62Chars[(b[j+1]&15)<<2|b[j+2]>>6] 98 idb[k+3] = b62Chars[b[j+2]&63] 99 } 100 return T(id) 101 }