Plan stuff. Log stuff.
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.

40 lines
824 B

4 years ago
  1. package generate
  2. import (
  3. "crypto/rand"
  4. "encoding/binary"
  5. mrand "math/rand"
  6. "strconv"
  7. "strings"
  8. )
  9. // ID generates an ID using crypto-random, falling back to math random when that fails
  10. // to avoid disrupting operation because of a faulty RNG. Database implementations does
  11. // not need to use this if some other scheme improves storage.
  12. func ID(prefix string, length int) string {
  13. var data [32]byte
  14. result := strings.Builder{}
  15. result.Grow(length + 32)
  16. result.WriteString(prefix)
  17. pos := 0
  18. for result.Len() < length {
  19. if pos == 0 {
  20. randRead(data[:])
  21. }
  22. result.WriteString(strconv.FormatUint(binary.BigEndian.Uint64(data[pos:pos+8]), 36))
  23. pos = (pos + 8) % 32
  24. }
  25. return result.String()[:length]
  26. }
  27. func randRead(data []byte) {
  28. n, err := rand.Read(data)
  29. if err != nil {
  30. mrand.Read(data[n:])
  31. }
  32. }