forked from pactus-project/pactus
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutils.go
162 lines (134 loc) · 3.57 KB
/
utils.go
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
package util
import (
crand "crypto/rand"
"fmt"
"math/big"
"math/bits"
"golang.org/x/exp/constraints"
)
const (
MaxUint16 = ^uint16(0)
MinUint16 = 0
MaxInt16 = int16(MaxUint16 >> 1)
MinInt16 = -MaxInt16 - 1
)
const (
MaxUint32 = ^uint32(0)
MinUint32 = 0
MaxInt32 = int32(MaxUint32 >> 1)
MinInt32 = -MaxInt32 - 1
)
const (
MaxUint64 = ^uint64(0)
MinUint64 = 0
MaxInt64 = int64(MaxUint64 >> 1)
MinInt64 = -MaxInt64 - 1
)
// Max returns the biggest of two integer numbers.
func Max[T constraints.Integer](a, b T) T {
if a > b {
return a
}
return b
}
// Min returns the smallest of two integer numbers.
func Min[T constraints.Integer](a, b T) T {
if a < b {
return a
}
return b
}
// RandInt16 returns a random int16 in between 0 and max.
// If max set to zero or negative, the max will set to MaxInt16.
func RandInt16(max int16) int16 {
return int16(RandUint64(uint64(max)))
}
// RandUint16 returns a random uint16 in between 0 and max.
// If max set to zero or negative, the max will set to MaxUint16.
func RandUint16(max uint32) uint16 {
return uint16(RandUint64(uint64(max)))
}
// RandInt32 returns a random int32 in between 0 and max.
// If max set to zero or negative, the max will set to MaxInt32.
func RandInt32(max int32) int32 {
return int32(RandUint64(uint64(max)))
}
// RandUint32 returns a random uint32 in between 0 and max.
// If max set to zero or negative, the max will set to MaxUint32.
func RandUint32(max uint32) uint32 {
return uint32(RandUint64(uint64(max)))
}
// RandInt64 returns a random int64 in between 0 and max.
// If max set to zero or negative, the max will set to MaxInt64.
func RandInt64(max int64) int64 {
return int64(RandUint64(uint64(max)))
}
// RandUint64 returns a random uint64 in between 0 and max.
// If max set to zero or negative, the max will set to MaxUint64.
func RandUint64(max uint64) uint64 {
if max <= 0 {
max = MaxUint64
}
bigMax := &big.Int{}
bigMax.SetUint64(max)
bigRnd, _ := crand.Int(crand.Reader, bigMax)
return bigRnd.Uint64()
}
// SetFlag applies mask to the flags.
func SetFlag[T constraints.Integer](flags, mask T) T {
return flags | mask
}
// UnsetFlag removes mask from the flags.
func UnsetFlag[T constraints.Integer](flags, mask T) T {
return flags & ^mask
}
// IsFlagSet checks if the mask is set for the given flags.
func IsFlagSet[T constraints.Integer](flags, mask T) bool {
return flags&mask == mask
}
// OS2IP converts an octet string to a nonnegative integer.
// OS2IP: https://datatracker.ietf.org/doc/html/rfc8017#section-4.2
func OS2IP(x []byte) *big.Int {
return new(big.Int).SetBytes(x)
}
// I2OSP converts a nonnegative integer to an octet string of a specified length.
// https://datatracker.ietf.org/doc/html/rfc8017#section-4.1
func I2OSP(num *big.Int, len int) []byte {
if num.Sign() == -1 {
return nil
}
buf := make([]byte, len)
return num.FillBytes(buf)
}
// LogScale computes 2^⌈log₂(val)⌉, where ⌈x⌉ represents the ceiling of x.
// For more information, refer to: https://en.wikipedia.org/wiki/Logarithmic_scale
func LogScale(val int) int {
bitlen := bits.Len(uint(val - 1))
return 1 << bitlen
}
func FormatBytesToHumanReadable(bytes uint64) string {
const (
_ = iota
KiloBYte = 1 << (10 * iota)
MegaBYte
GigaByte
TeraByte
)
unit := "Bytes"
value := float64(bytes)
switch {
case bytes >= TeraByte:
unit = "TB"
value /= TeraByte
case bytes >= GigaByte:
unit = "GB"
value /= GigaByte
case bytes >= MegaBYte:
unit = "MB"
value /= MegaBYte
case bytes >= KiloBYte:
unit = "KB"
value /= KiloBYte
}
return fmt.Sprintf("%.2f %s", value, unit)
}