github.com/aliyun/credentials-go@v1.4.7/credentials/internal/utils/utils.go (about) 1 package utils 2 3 import ( 4 "bytes" 5 "crypto" 6 "crypto/hmac" 7 "crypto/md5" 8 "crypto/rand" 9 "crypto/rsa" 10 "crypto/sha1" 11 "crypto/x509" 12 "encoding/base64" 13 "encoding/hex" 14 "fmt" 15 "hash" 16 "io" 17 mathrand "math/rand" 18 "net/url" 19 "os" 20 "runtime" 21 "strconv" 22 "sync/atomic" 23 "time" 24 ) 25 26 type uuid [16]byte 27 28 const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" 29 30 var hookRead = func(fn func(p []byte) (n int, err error)) func(p []byte) (n int, err error) { 31 return fn 32 } 33 34 var hookRSA = func(fn func(rand io.Reader, priv *rsa.PrivateKey, hash crypto.Hash, hashed []byte) ([]byte, error)) func(rand io.Reader, priv *rsa.PrivateKey, hash crypto.Hash, hashed []byte) ([]byte, error) { 35 return fn 36 } 37 38 // GetUUID returns a uuid 39 func GetUUID() (uuidHex string) { 40 uuid := newUUID() 41 uuidHex = hex.EncodeToString(uuid[:]) 42 return 43 } 44 45 // RandStringBytes returns a rand string 46 func RandStringBytes(n int) string { 47 b := make([]byte, n) 48 for i := range b { 49 b[i] = letterBytes[mathrand.Intn(len(letterBytes))] 50 } 51 return string(b) 52 } 53 54 // ShaHmac1 return a string which has been hashed 55 func ShaHmac1(source, secret string) string { 56 key := []byte(secret) 57 hmac := hmac.New(sha1.New, key) 58 hmac.Write([]byte(source)) 59 signedBytes := hmac.Sum(nil) 60 signedString := base64.StdEncoding.EncodeToString(signedBytes) 61 return signedString 62 } 63 64 // Sha256WithRsa return a string which has been hashed with Rsa 65 func Sha256WithRsa(source, secret string) string { 66 decodeString, err := base64.StdEncoding.DecodeString(secret) 67 if err != nil { 68 panic(err) 69 } 70 private, err := x509.ParsePKCS8PrivateKey(decodeString) 71 if err != nil { 72 panic(err) 73 } 74 75 h := crypto.Hash.New(crypto.SHA256) 76 h.Write([]byte(source)) 77 hashed := h.Sum(nil) 78 signature, err := hookRSA(rsa.SignPKCS1v15)(rand.Reader, private.(*rsa.PrivateKey), 79 crypto.SHA256, hashed) 80 if err != nil { 81 panic(err) 82 } 83 84 return base64.StdEncoding.EncodeToString(signature) 85 } 86 87 // GetMD5Base64 returns a string which has been base64 88 func GetMD5Base64(bytes []byte) (base64Value string) { 89 md5Ctx := md5.New() 90 md5Ctx.Write(bytes) 91 md5Value := md5Ctx.Sum(nil) 92 base64Value = base64.StdEncoding.EncodeToString(md5Value) 93 return 94 } 95 96 // GetTimeInFormatISO8601 returns a time string 97 func GetTimeInFormatISO8601() (timeStr string) { 98 gmt := time.FixedZone("GMT", 0) 99 100 return time.Now().In(gmt).Format("2006-01-02T15:04:05Z") 101 } 102 103 // GetURLFormedMap returns a url encoded string 104 func GetURLFormedMap(source map[string]string) (urlEncoded string) { 105 urlEncoder := url.Values{} 106 for key, value := range source { 107 urlEncoder.Add(key, value) 108 } 109 urlEncoded = urlEncoder.Encode() 110 return 111 } 112 113 func newUUID() uuid { 114 ns := uuid{} 115 safeRandom(ns[:]) 116 u := newFromHash(md5.New(), ns, RandStringBytes(16)) 117 u[6] = (u[6] & 0x0f) | (byte(2) << 4) 118 u[8] = (u[8]&(0xff>>2) | (0x02 << 6)) 119 120 return u 121 } 122 123 func newFromHash(h hash.Hash, ns uuid, name string) uuid { 124 u := uuid{} 125 h.Write(ns[:]) 126 h.Write([]byte(name)) 127 copy(u[:], h.Sum(nil)) 128 129 return u 130 } 131 132 func safeRandom(dest []byte) { 133 if _, err := hookRead(rand.Read)(dest); err != nil { 134 panic(err) 135 } 136 } 137 138 func (u uuid) String() string { 139 buf := make([]byte, 36) 140 141 hex.Encode(buf[0:8], u[0:4]) 142 buf[8] = '-' 143 hex.Encode(buf[9:13], u[4:6]) 144 buf[13] = '-' 145 hex.Encode(buf[14:18], u[6:8]) 146 buf[18] = '-' 147 hex.Encode(buf[19:23], u[8:10]) 148 buf[23] = '-' 149 hex.Encode(buf[24:], u[10:]) 150 151 return string(buf) 152 } 153 154 var processStartTime int64 = time.Now().UnixNano() / 1e6 155 var seqId int64 = 0 156 157 func getGID() uint64 { 158 // https://blog.sgmansfield.com/2015/12/goroutine-ids/ 159 b := make([]byte, 64) 160 b = b[:runtime.Stack(b, false)] 161 b = bytes.TrimPrefix(b, []byte("goroutine ")) 162 b = b[:bytes.IndexByte(b, ' ')] 163 n, _ := strconv.ParseUint(string(b), 10, 64) 164 return n 165 } 166 167 func GetNonce() (uuidHex string) { 168 routineId := getGID() 169 currentTime := time.Now().UnixNano() / 1e6 170 seq := atomic.AddInt64(&seqId, 1) 171 randNum := mathrand.Int63() 172 msg := fmt.Sprintf("%d-%d-%d-%d-%d", processStartTime, routineId, currentTime, seq, randNum) 173 h := md5.New() 174 h.Write([]byte(msg)) 175 return hex.EncodeToString(h.Sum(nil)) 176 } 177 178 // Get first non-empty value 179 func GetDefaultString(values ...string) string { 180 for _, v := range values { 181 if v != "" { 182 return v 183 } 184 } 185 186 return "" 187 } 188 189 // set back the memoried enviroment variables 190 type Rollback func() 191 192 func Memory(keys ...string) Rollback { 193 // remenber enviroment variables 194 m := make(map[string]string) 195 for _, key := range keys { 196 m[key] = os.Getenv(key) 197 } 198 199 return func() { 200 for _, key := range keys { 201 os.Setenv(key, m[key]) 202 } 203 } 204 }