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  }