Files
opencloud/vendor/github.com/gookit/goutil/byteutil/byteutil.go
dependabot[bot] 89a7d171ee build(deps): bump github.com/gookit/config/v2 from 2.2.6 to 2.2.7
Bumps [github.com/gookit/config/v2](https://github.com/gookit/config) from 2.2.6 to 2.2.7.
- [Release notes](https://github.com/gookit/config/releases)
- [Commits](https://github.com/gookit/config/compare/v2.2.6...v2.2.7)

---
updated-dependencies:
- dependency-name: github.com/gookit/config/v2
  dependency-version: 2.2.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-15 14:15:33 +00:00

126 lines
2.9 KiB
Go

// Package byteutil provides some useful functions for byte slice.
package byteutil
import (
"bytes"
"crypto/md5"
"encoding/hex"
"fmt"
"math/rand"
"strconv"
"time"
)
// Md5 Generate a 32-bit md5 bytes
func Md5(src any) []byte {
bs := Md5Sum(src)
dst := make([]byte, hex.EncodedLen(len(bs)))
hex.Encode(dst, bs)
return dst
}
// Md5Sum Generate a md5 bytes
func Md5Sum(src any) []byte {
h := md5.New()
switch val := src.(type) {
case []byte:
h.Write(val)
case string:
h.Write([]byte(val))
default:
h.Write([]byte(fmt.Sprint(src)))
}
return h.Sum(nil) // cap(bs) == 16
}
// ShortMd5 Generate a 16-bit md5 bytes. remove the first 8 and last 8 bytes from 32-bit md5.
func ShortMd5(src any) []byte { return Md5(src)[8:24] }
// Random bytes generate
func Random(length int) ([]byte, error) {
b := make([]byte, length)
// Note that err == nil only if we read len(b) bytes.
if _, err := rand.Read(b); err != nil {
return nil, err
}
return b, nil
}
// FirstLine from command output
func FirstLine(bs []byte) []byte {
if i := bytes.IndexByte(bs, '\n'); i >= 0 {
return bs[0:i]
}
return bs
}
// AppendAny append any value to byte slice
func AppendAny(dst []byte, v any) []byte {
if v == nil {
return append(dst, "<nil>"...)
}
switch val := v.(type) {
case []byte:
dst = append(dst, val...)
case string:
dst = append(dst, val...)
case int:
dst = strconv.AppendInt(dst, int64(val), 10)
case int8:
dst = strconv.AppendInt(dst, int64(val), 10)
case int16:
dst = strconv.AppendInt(dst, int64(val), 10)
case int32:
dst = strconv.AppendInt(dst, int64(val), 10)
case int64:
dst = strconv.AppendInt(dst, val, 10)
case uint:
dst = strconv.AppendUint(dst, uint64(val), 10)
case uint8:
dst = strconv.AppendUint(dst, uint64(val), 10)
case uint16:
dst = strconv.AppendUint(dst, uint64(val), 10)
case uint32:
dst = strconv.AppendUint(dst, uint64(val), 10)
case uint64:
dst = strconv.AppendUint(dst, val, 10)
case float32:
dst = strconv.AppendFloat(dst, float64(val), 'f', -1, 32)
case float64:
dst = strconv.AppendFloat(dst, val, 'f', -1, 64)
case bool:
dst = strconv.AppendBool(dst, val)
case time.Time:
dst = val.AppendFormat(dst, time.RFC3339)
case time.Duration:
dst = strconv.AppendInt(dst, int64(val), 10)
case error:
dst = append(dst, val.Error()...)
case fmt.Stringer:
dst = append(dst, val.String()...)
default:
dst = append(dst, fmt.Sprint(v)...)
}
return dst
}
// Cut bytes by one byte char. like bytes.Cut(), but sep is byte.
func Cut(bs []byte, sep byte) (before, after []byte, found bool) {
return bytes.Cut(bs, []byte{sep})
}
// SafeCut bytes by one byte char. always return before and after
func SafeCut(bs []byte, sep byte) (before, after []byte) {
before, after, _ = bytes.Cut(bs, []byte{sep})
return
}
// SafeCuts bytes by sub bytes. like the bytes.Cut(), but always return before and after
func SafeCuts(bs []byte, sep []byte) (before, after []byte) {
before, after, _ = bytes.Cut(bs, sep)
return
}