1package securerandom
2
3import (
4	"bytes"
5	"crypto/rand"
6	"encoding/base64"
7	"encoding/binary"
8	"encoding/hex"
9	"fmt"
10	"strings"
11)
12
13func RandomBytes(n int) ([]byte, error) {
14	bytes := make([]byte, n)
15	_, err := rand.Read(bytes)
16	if err != nil {
17		return nil, err
18	}
19	return bytes, nil
20}
21
22func Base64(n int, padded bool) (string, error) {
23	bytes, err := RandomBytes(n)
24	if err != nil {
25		return "", err
26	}
27	result := base64.StdEncoding.EncodeToString(bytes)
28	result = strings.Replace(result, "\n", "", -1)
29	if !padded {
30		result = strings.Replace(result, "=", "", -1)
31	}
32	return result, nil
33}
34
35func UrlSafeBase64(n int, padded bool) (string, error) {
36	result, err := Base64(n, padded)
37	if err != nil {
38		return "", err
39	}
40	result = strings.Replace(result, "+", "-", -1)
41	result = strings.Replace(result, "/", "_", -1)
42	return result, nil
43}
44
45func Hex(n int) (string, error) {
46	bytes, err := RandomBytes(n)
47	if err != nil {
48		return "", err
49	}
50	return hex.EncodeToString(bytes), nil
51}
52
53func Uuid() (string, error) {
54	var first, last uint32
55	var middle [4]uint16
56	randomBytes, err := RandomBytes(16)
57	if err != nil {
58		return "", err
59	}
60	buffer := bytes.NewBuffer(randomBytes)
61	binary.Read(buffer, binary.BigEndian, &first)
62	for i := 0; i < 4; i++ {
63		binary.Read(buffer, binary.BigEndian, &middle[i])
64	}
65	binary.Read(buffer, binary.BigEndian, &last)
66	middle[1] = (middle[1] & 0x0fff) | 0x4000
67	middle[2] = (middle[2] & 0x3fff) | 0x8000
68	return fmt.Sprintf("%08x-%04x-%04x-%04x-%04x%08x",
69		first, middle[0], middle[1], middle[2], middle[3], last), nil
70}
71