1/*
2 * Licensed under the Apache License, Version 2.0 (the "License");
3 * you may not use this file except in compliance with the License.
4 * You may obtain a copy of the License at
5 *
6 * http://www.apache.org/licenses/LICENSE-2.0
7 *
8 * Unless required by applicable law or agreed to in writing, software
9 * distributed under the License is distributed on an "AS IS" BASIS,
10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 * See the License for the specific language governing permissions and
12 * limitations under the License.
13 */
14
15package utils
16
17import (
18	"crypto/md5"
19	"crypto/rand"
20	"encoding/base64"
21	"encoding/hex"
22	"hash"
23	rand2 "math/rand"
24	"net/url"
25	"reflect"
26	"strconv"
27	"time"
28)
29
30type UUID [16]byte
31
32const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
33
34func GetUUID() (uuidHex string) {
35	uuid := NewUUID()
36	uuidHex = hex.EncodeToString(uuid[:])
37	return
38}
39
40func RandStringBytes(n int) string {
41	b := make([]byte, n)
42	for i := range b {
43		b[i] = letterBytes[rand2.Intn(len(letterBytes))]
44	}
45	return string(b)
46}
47
48func GetMD5Base64(bytes []byte) (base64Value string) {
49	md5Ctx := md5.New()
50	md5Ctx.Write(bytes)
51	md5Value := md5Ctx.Sum(nil)
52	base64Value = base64.StdEncoding.EncodeToString(md5Value)
53	return
54}
55
56func GetTimeInFormatISO8601() (timeStr string) {
57	gmt := time.FixedZone("GMT", 0)
58
59	return time.Now().In(gmt).Format("2006-01-02T15:04:05Z")
60}
61
62func GetTimeInFormatRFC2616() (timeStr string) {
63	gmt := time.FixedZone("GMT", 0)
64
65	return time.Now().In(gmt).Format("Mon, 02 Jan 2006 15:04:05 GMT")
66}
67
68func GetUrlFormedMap(source map[string]string) (urlEncoded string) {
69	urlEncoder := url.Values{}
70	for key, value := range source {
71		urlEncoder.Add(key, value)
72	}
73	urlEncoded = urlEncoder.Encode()
74	return
75}
76
77func InitStructWithDefaultTag(bean interface{}) {
78	configType := reflect.TypeOf(bean)
79	for i := 0; i < configType.Elem().NumField(); i++ {
80		field := configType.Elem().Field(i)
81		defaultValue := field.Tag.Get("default")
82		if defaultValue == "" {
83			continue
84		}
85		setter := reflect.ValueOf(bean).Elem().Field(i)
86		switch field.Type.String() {
87		case "int":
88			intValue, _ := strconv.ParseInt(defaultValue, 10, 64)
89			setter.SetInt(intValue)
90		case "time.Duration":
91			intValue, _ := strconv.ParseInt(defaultValue, 10, 64)
92			setter.SetInt(intValue)
93		case "string":
94			setter.SetString(defaultValue)
95		case "bool":
96			boolValue, _ := strconv.ParseBool(defaultValue)
97			setter.SetBool(boolValue)
98		}
99	}
100}
101
102func NewUUID() UUID {
103	ns := UUID{}
104	safeRandom(ns[:])
105	u := newFromHash(md5.New(), ns, RandStringBytes(16))
106	u[6] = (u[6] & 0x0f) | (byte(2) << 4)
107	u[8] = (u[8]&(0xff>>2) | (0x02 << 6))
108
109	return u
110}
111
112func newFromHash(h hash.Hash, ns UUID, name string) UUID {
113	u := UUID{}
114	h.Write(ns[:])
115	h.Write([]byte(name))
116	copy(u[:], h.Sum(nil))
117
118	return u
119}
120
121func safeRandom(dest []byte) {
122	if _, err := rand.Read(dest); err != nil {
123		panic(err)
124	}
125}
126
127func (u UUID) String() string {
128	buf := make([]byte, 36)
129
130	hex.Encode(buf[0:8], u[0:4])
131	buf[8] = '-'
132	hex.Encode(buf[9:13], u[4:6])
133	buf[13] = '-'
134	hex.Encode(buf[14:18], u[6:8])
135	buf[18] = '-'
136	hex.Encode(buf[19:23], u[8:10])
137	buf[23] = '-'
138	hex.Encode(buf[24:], u[10:])
139
140	return string(buf)
141}
142