github.com/gofiber/fiber/v2@v2.47.0/utils/common.go (about) 1 // ⚡️ Fiber is an Express inspired web framework written in Go with ☕️ 2 // 🤖 Github Repository: https://github.com/gofiber/fiber 3 // 📌 API Documentation: https://docs.gofiber.io 4 5 package utils 6 7 import ( 8 "bytes" 9 "crypto/rand" 10 "encoding/binary" 11 "encoding/hex" 12 "math" 13 "net" 14 "os" 15 "reflect" 16 "runtime" 17 "strconv" 18 "sync" 19 "sync/atomic" 20 "unicode" 21 22 googleuuid "github.com/google/uuid" 23 ) 24 25 const ( 26 toLowerTable = "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u007f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff" 27 toUpperTable = "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~\u007f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff" 28 ) 29 30 // Copyright © 2014, Roger Peppe 31 // github.com/rogpeppe/fastuuid 32 // All rights reserved. 33 34 const ( 35 emptyUUID = "00000000-0000-0000-0000-000000000000" 36 ) 37 38 var ( 39 uuidSeed [24]byte 40 uuidCounter uint64 41 uuidSetup sync.Once 42 unitsSlice = []byte("kmgtp") 43 ) 44 45 // UUID generates an universally unique identifier (UUID) 46 func UUID() string { 47 // Setup seed & counter once 48 uuidSetup.Do(func() { 49 if _, err := rand.Read(uuidSeed[:]); err != nil { 50 return 51 } 52 uuidCounter = binary.LittleEndian.Uint64(uuidSeed[:8]) 53 }) 54 if atomic.LoadUint64(&uuidCounter) <= 0 { 55 return emptyUUID 56 } 57 // first 8 bytes differ, taking a slice of the first 16 bytes 58 x := atomic.AddUint64(&uuidCounter, 1) 59 uuid := uuidSeed 60 binary.LittleEndian.PutUint64(uuid[:8], x) 61 uuid[6], uuid[9] = uuid[9], uuid[6] 62 63 // RFC4122 v4 64 uuid[6] = (uuid[6] & 0x0f) | 0x40 65 uuid[8] = uuid[8]&0x3f | 0x80 66 67 // create UUID representation of the first 128 bits 68 b := make([]byte, 36) 69 hex.Encode(b[0:8], uuid[0:4]) 70 b[8] = '-' 71 hex.Encode(b[9:13], uuid[4:6]) 72 b[13] = '-' 73 hex.Encode(b[14:18], uuid[6:8]) 74 b[18] = '-' 75 hex.Encode(b[19:23], uuid[8:10]) 76 b[23] = '-' 77 hex.Encode(b[24:], uuid[10:16]) 78 79 return UnsafeString(b) 80 } 81 82 // UUIDv4 returns a Random (Version 4) UUID. 83 // The strength of the UUIDs is based on the strength of the crypto/rand package. 84 func UUIDv4() string { 85 token, err := googleuuid.NewRandom() 86 if err != nil { 87 return UUID() 88 } 89 return token.String() 90 } 91 92 // FunctionName returns function name 93 func FunctionName(fn interface{}) string { 94 t := reflect.ValueOf(fn).Type() 95 if t.Kind() == reflect.Func { 96 return runtime.FuncForPC(reflect.ValueOf(fn).Pointer()).Name() 97 } 98 return t.String() 99 } 100 101 // GetArgument check if key is in arguments 102 func GetArgument(arg string) bool { 103 for i := range os.Args[1:] { 104 if os.Args[1:][i] == arg { 105 return true 106 } 107 } 108 return false 109 } 110 111 // IncrementIPRange Find available next IP address 112 func IncrementIPRange(ip net.IP) { 113 for j := len(ip) - 1; j >= 0; j-- { 114 ip[j]++ 115 if ip[j] > 0 { 116 break 117 } 118 } 119 } 120 121 // ConvertToBytes returns integer size of bytes from human-readable string, ex. 42kb, 42M 122 // Returns 0 if string is unrecognized 123 func ConvertToBytes(humanReadableString string) int { 124 strLen := len(humanReadableString) 125 if strLen == 0 { 126 return 0 127 } 128 var unitPrefixPos, lastNumberPos int 129 // loop the string 130 for i := strLen - 1; i >= 0; i-- { 131 // check if the char is a number 132 if unicode.IsDigit(rune(humanReadableString[i])) { 133 lastNumberPos = i 134 break 135 } else if humanReadableString[i] != ' ' { 136 unitPrefixPos = i 137 } 138 } 139 140 if lastNumberPos < 0 { 141 return 0 142 } 143 // fetch the number part and parse it to float 144 size, err := strconv.ParseFloat(humanReadableString[:lastNumberPos+1], 64) 145 if err != nil { 146 return 0 147 } 148 149 // check the multiplier from the string and use it 150 if unitPrefixPos > 0 { 151 // convert multiplier char to lowercase and check if exists in units slice 152 index := bytes.IndexByte(unitsSlice, toLowerTable[humanReadableString[unitPrefixPos]]) 153 if index != -1 { 154 const bytesPerKB = 1000 155 size *= math.Pow(bytesPerKB, float64(index+1)) 156 } 157 } 158 159 return int(size) 160 }