GraphQL API and utilities for the rpdata project
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

73 lines
1.2 KiB

package generate
import (
"crypto/rand"
"encoding/binary"
mrand "math/rand"
"strconv"
"strings"
)
// ID generates an ID using crypto-random, falling back to math random when that fails
// to avoid disrupting operation because of a faulty RNG.
func ID(prefix string, length int) string {
var data [32]byte
result := strings.Builder{}
result.Grow(length + 32)
result.WriteString(prefix)
pos := 0
for result.Len() < length {
if pos == 0 {
randRead(data[:])
}
result.WriteString(strconv.FormatUint(binary.BigEndian.Uint64(data[pos:pos+8]), 36))
pos = (pos + 8) % 32
}
return result.String()[:length]
}
func randRead(data []byte) {
n, err := rand.Read(data)
if err != nil {
mrand.Read(data[n:])
}
}
// PostID generates a post ID.
func PostID() string {
return ID("P", 16)
}
// StoryID generates a post ID.
func StoryID() string {
return ID("S", 16)
}
// ChapterID generates a post ID.
func ChapterID() string {
return ID("SC", 24)
}
// CommentID generates a post ID.
func CommentID() string {
return ID("SCC", 32)
}
// FileID generates a file ID.
func FileID() string {
return ID("F", 16)
}
// FileID generates a file ID.
func FileUploadID() string {
return ID("U", 24)
}
func KeyID() string {
return ID("K", 32)
}