common/util.go

72 lines
1.7 KiB
Go

package common
import (
crip "crypto/rand"
"encoding/binary"
"fmt"
"io"
"math/rand"
"time"
"github.com/rs/zerolog/log"
"golang.org/x/crypto/blake2b"
)
const charset = "abcdefghijklmnopqrstuvwxyz1234567890"
// Fprint is fmt.Fprint with error handling.
func Fprint(w io.Writer, s string) {
_, err := fmt.Fprint(w, s)
if err != nil {
log.Error().Str("data", s).Err(err).Msg("Fprint failed!")
}
}
// BytesToBlake2b ignores all errors and gives you a blakae2b 64 hash value as a byte slice. (or panics somehow)
func BytesToBlake2b(b []byte) []byte {
Hasha, _ := blake2b.New(64, nil)
Hasha.Write(b)
return Hasha.Sum(nil)
}
// CompareChecksums will take in two byte slices, hash them with blake2b, and tell you if the resulting checksums match.
func CompareChecksums(a []byte, b []byte) bool {
ahash := BytesToBlake2b(a)
bhash := BytesToBlake2b(b)
return string(ahash) == string(bhash)
}
// RNG is a Random Number Generator
func RNG(n int) int {
var seed int64
err := binary.Read(crip.Reader, binary.BigEndian, &seed)
if err != nil {
panic(err)
}
rng := rand.New(rand.NewSource(seed))
return rng.Intn(n)
}
// RandStr generates a random alphanumeric string with a max length of size.
func RandStr(size int) string {
buf := make([]byte, size)
for i := 0; i != size; i++ {
buf[i] = charset[uint32(RNG(32))%uint32(len(charset))]
}
return string(buf)
}
// RandSleepMS sleeps for a random period of time with a maximum of n milliseconds.
func RandSleepMS(n int) {
time.Sleep(time.Duration(RNG(n)) * time.Millisecond)
}
// Abs will give you the positive version of a negative integer, quickly.
func Abs(n int) int {
// ayyee smash 6ros
n64 := int64(n)
y := n64 >> 63
n64 = (n64 ^ y) - y
return int(n64)
}