mirror of
https://github.com/pikami/cosmium.git
synced 2025-12-18 16:30:44 +00:00
Generate more realistic resource ids
This commit is contained in:
@@ -3,32 +3,76 @@ package resourceid
|
||||
import (
|
||||
"encoding/base64"
|
||||
"math/rand"
|
||||
"strings"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
func New() string {
|
||||
id := uuid.New().ID()
|
||||
idBytes := uintToBytes(id)
|
||||
type ResourceType int
|
||||
|
||||
// first byte should be bigger than 0x80 for collection ids
|
||||
// clients classify this id as "user" otherwise
|
||||
if (idBytes[0] & 0x80) <= 0 {
|
||||
idBytes[0] = byte(rand.Intn(0x80) + 0x80)
|
||||
const (
|
||||
ResourceTypeDatabase ResourceType = iota
|
||||
ResourceTypeCollection
|
||||
ResourceTypeDocument
|
||||
ResourceTypeStoredProcedure
|
||||
ResourceTypeTrigger
|
||||
ResourceTypeUserDefinedFunction
|
||||
ResourceTypeConflict
|
||||
ResourceTypePartitionKeyRange
|
||||
ResourceTypeSchema
|
||||
)
|
||||
|
||||
func New(resourceType ResourceType) string {
|
||||
var idBytes []byte
|
||||
switch resourceType {
|
||||
case ResourceTypeDatabase:
|
||||
idBytes = randomBytes(4)
|
||||
case ResourceTypeCollection:
|
||||
idBytes = randomBytes(4)
|
||||
// first byte should be bigger than 0x80 for collection ids
|
||||
// clients classify this id as "user" otherwise
|
||||
if (idBytes[0] & 0x80) <= 0 {
|
||||
idBytes[0] = byte(rand.Intn(0x80) + 0x80)
|
||||
}
|
||||
case ResourceTypeDocument:
|
||||
idBytes = randomBytes(8)
|
||||
idBytes[7] = byte(rand.Intn(0x10)) // Upper 4 bits = 0
|
||||
case ResourceTypeStoredProcedure:
|
||||
idBytes = randomBytes(8)
|
||||
idBytes[7] = byte(rand.Intn(0x10)) | 0x08 // Upper 4 bits = 0x08
|
||||
case ResourceTypeTrigger:
|
||||
idBytes = randomBytes(8)
|
||||
idBytes[7] = byte(rand.Intn(0x10)) | 0x07 // Upper 4 bits = 0x07
|
||||
case ResourceTypeUserDefinedFunction:
|
||||
idBytes = randomBytes(8)
|
||||
idBytes[7] = byte(rand.Intn(0x10)) | 0x06 // Upper 4 bits = 0x06
|
||||
case ResourceTypeConflict:
|
||||
idBytes = randomBytes(8)
|
||||
idBytes[7] = byte(rand.Intn(0x10)) | 0x04 // Upper 4 bits = 0x04
|
||||
case ResourceTypePartitionKeyRange:
|
||||
// we don't do partitions yet, so just use a fixed id
|
||||
idBytes = []byte{0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x50}
|
||||
case ResourceTypeSchema:
|
||||
idBytes = randomBytes(8)
|
||||
idBytes[7] = byte(rand.Intn(0x10)) | 0x09 // Upper 4 bits = 0x09
|
||||
default:
|
||||
idBytes = randomBytes(4)
|
||||
}
|
||||
|
||||
return base64.StdEncoding.EncodeToString(idBytes)
|
||||
encoded := base64.StdEncoding.EncodeToString(idBytes)
|
||||
return strings.ReplaceAll(encoded, "/", "-")
|
||||
}
|
||||
|
||||
func NewCombined(ids ...string) string {
|
||||
combinedIdBytes := make([]byte, 0)
|
||||
|
||||
for _, id := range ids {
|
||||
idBytes, _ := base64.StdEncoding.DecodeString(id)
|
||||
idBytes, _ := base64.StdEncoding.DecodeString(strings.ReplaceAll(id, "-", "/"))
|
||||
combinedIdBytes = append(combinedIdBytes, idBytes...)
|
||||
}
|
||||
|
||||
return base64.StdEncoding.EncodeToString(combinedIdBytes)
|
||||
encoded := base64.StdEncoding.EncodeToString(combinedIdBytes)
|
||||
return strings.ReplaceAll(encoded, "/", "-")
|
||||
}
|
||||
|
||||
func uintToBytes(id uint32) []byte {
|
||||
@@ -39,3 +83,13 @@ func uintToBytes(id uint32) []byte {
|
||||
|
||||
return buf
|
||||
}
|
||||
|
||||
func randomBytes(count int) []byte {
|
||||
buf := make([]byte, count)
|
||||
for i := 0; i < count; i += 4 {
|
||||
id := uuid.New().ID()
|
||||
idBytes := uintToBytes(id)
|
||||
copy(buf[i:], idBytes)
|
||||
}
|
||||
return buf
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user