~samwhited/xmpp

ref: ae670e1d6448899cc7cd1d2279d256222d0f42ff xmpp/internal/idgen.go -rw-r--r-- 978 bytes
ae670e1dSam Whited Add a TODO for later 5 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// Copyright 2016 Sam Whited.
// Use of this source code is governed by the BSD 2-clause license that can be
// found in the LICENSE file.

package internal

import (
	"crypto/rand"
	"fmt"
	"io"
)

// IDLen is the standard length of stanza identifiers in bytes.
const IDLen = 16

// TODO: This will be called a lot, and probably needs to be faster than we can
//       get when reading from getrandom(2). Should we use a fast userspace
//       CSPRNG and just seed with data from the OS?

// RandomID generates a new random identifier of the given length. If the OS's
// entropy pool isn't initialized, or we can't generate random numbers for some
// other reason, panic.
func RandomID(n int) string {
	return randomID(n, rand.Reader)
}

func randomID(n int, r io.Reader) string {
	b := make([]byte, (n/2)+(n&1))
	switch n, err := r.Read(b); {
	case err != nil:
		panic(err)
	case n != len(b):
		panic("Could not read enough randomness")
	}

	return fmt.Sprintf("%x", b)[:n]
}