mirror of
https://github.com/pomerium/pomerium.git
synced 2025-04-30 10:56:28 +02:00
206 lines
4.6 KiB
Go
206 lines
4.6 KiB
Go
// Package hashutil provides NON-CRYPTOGRAPHIC utility functions for hashing.
|
|
//
|
|
// http://cyan4973.github.io/xxHash/
|
|
//
|
|
//nolint:errcheck
|
|
package hashutil
|
|
|
|
import (
|
|
"encoding/binary"
|
|
|
|
"github.com/cespare/xxhash/v2"
|
|
"github.com/mitchellh/hashstructure/v2"
|
|
)
|
|
|
|
// MustHash returns the xxhash of an arbitrary value or struct. Returns 0
|
|
// on error.
|
|
// NOT SUITABLE FOR CRYTOGRAPHIC HASHING.
|
|
func MustHash(v any) uint64 {
|
|
hash, err := Hash(v)
|
|
if err != nil {
|
|
hash = 0
|
|
}
|
|
return hash
|
|
}
|
|
|
|
// Hash returns the xxhash of an arbitrary value or struct.
|
|
// NOT SUITABLE FOR CRYTOGRAPHIC HASHING.
|
|
func Hash(v any) (uint64, error) {
|
|
opts := &hashstructure.HashOptions{
|
|
Hasher: xxhash.New(),
|
|
}
|
|
return hashstructure.Hash(v, hashstructure.FormatV2, opts)
|
|
}
|
|
|
|
type Digest struct {
|
|
xxhash.Digest
|
|
}
|
|
|
|
func NewDigest() *Digest {
|
|
var d Digest
|
|
d.Reset()
|
|
return &d
|
|
}
|
|
|
|
// WriteStringWithLen writes the string's length, then its contents to the hash.
|
|
func (d *Digest) WriteStringWithLen(s string) {
|
|
d.WriteInt32(int32(len(s)))
|
|
d.WriteString(s)
|
|
}
|
|
|
|
// WriteStringWithLen writes the byte array's length, then its contents to
|
|
// the hash.
|
|
func (d *Digest) WriteWithLen(b []byte) {
|
|
d.WriteInt32(int32(len(b)))
|
|
d.Write(b)
|
|
}
|
|
|
|
// WriteBool writes a single byte (1 or 0) to the hash.
|
|
func (d *Digest) WriteBool(b bool) {
|
|
if b {
|
|
d.Write([]byte{1})
|
|
} else {
|
|
d.Write([]byte{0})
|
|
}
|
|
}
|
|
|
|
// WriteUint32 writes a uint16 to the hash.
|
|
func (d *Digest) WriteUint16(t uint16) {
|
|
var buf [2]byte
|
|
binary.LittleEndian.PutUint16(buf[:], t)
|
|
d.Write(buf[:])
|
|
}
|
|
|
|
// WriteUint32 writes a uint32 to the hash.
|
|
func (d *Digest) WriteUint32(t uint32) {
|
|
var buf [4]byte
|
|
binary.LittleEndian.PutUint32(buf[:], t)
|
|
d.Write(buf[:])
|
|
}
|
|
|
|
// WriteUint32 writes a uint64 to the hash.
|
|
func (d *Digest) WriteUint64(t uint64) {
|
|
var buf [8]byte
|
|
binary.LittleEndian.PutUint64(buf[:], t)
|
|
d.Write(buf[:])
|
|
}
|
|
|
|
// WriteInt16 writes an int16 to the hash.
|
|
func (d *Digest) WriteInt16(t int16) {
|
|
var buf [2]byte
|
|
binary.LittleEndian.PutUint16(buf[:], uint16(t))
|
|
d.Write(buf[:])
|
|
}
|
|
|
|
// WriteInt32 writes an int32 to the hash.
|
|
func (d *Digest) WriteInt32(t int32) {
|
|
var buf [4]byte
|
|
binary.LittleEndian.PutUint32(buf[:], uint32(t))
|
|
d.Write(buf[:])
|
|
}
|
|
|
|
// WriteInt64 writes an int64 to the hash.
|
|
func (d *Digest) WriteInt64(t int64) {
|
|
var buf [8]byte
|
|
binary.LittleEndian.PutUint64(buf[:], uint64(t))
|
|
d.Write(buf[:])
|
|
}
|
|
|
|
// WriteStringPtr writes one byte (1 or 0) indicating whether the pointer is non-nil,
|
|
// followed by the value if present.
|
|
func (d *Digest) WriteStringPtr(t *string) {
|
|
if t == nil {
|
|
d.Write([]byte{0})
|
|
} else {
|
|
d.Write([]byte{1})
|
|
d.WriteString(*t)
|
|
}
|
|
}
|
|
|
|
// WriteStringPtr writes one byte (1 or 0) indicating whether the pointer is non-nil,
|
|
// followed by the string's length and value, if present.
|
|
func (d *Digest) WriteStringPtrWithLen(t *string) {
|
|
if t == nil {
|
|
d.Write([]byte{0})
|
|
} else {
|
|
d.Write([]byte{1})
|
|
d.WriteStringWithLen(*t)
|
|
}
|
|
}
|
|
|
|
// WriteBoolPtr writes one byte (1 or 0) indicating whether the pointer is non-nil,
|
|
// followed by the value if present.
|
|
func (d *Digest) WriteBoolPtr(t *bool) {
|
|
if t == nil {
|
|
d.Write([]byte{0})
|
|
} else {
|
|
d.Write([]byte{1})
|
|
d.WriteBool(*t)
|
|
}
|
|
}
|
|
|
|
// WriteUint16Ptr writes one byte (1 or 0) indicating whether the pointer is non-nil,
|
|
// followed by the value if present.
|
|
func (d *Digest) WriteUint16Ptr(t *uint16) {
|
|
if t == nil {
|
|
d.Write([]byte{0})
|
|
} else {
|
|
d.Write([]byte{1})
|
|
d.WriteUint16(*t)
|
|
}
|
|
}
|
|
|
|
// WriteUint32Ptr writes one byte (1 or 0) indicating whether the pointer is non-nil,
|
|
// followed by the value if present.
|
|
func (d *Digest) WriteUint32Ptr(t *uint32) {
|
|
if t == nil {
|
|
d.Write([]byte{0})
|
|
} else {
|
|
d.Write([]byte{1})
|
|
d.WriteUint32(*t)
|
|
}
|
|
}
|
|
|
|
// WriteUint64Ptr writes one byte (1 or 0) indicating whether the pointer is non-nil,
|
|
// followed by the value if present.
|
|
func (d *Digest) WriteUint64Ptr(t *uint64) {
|
|
if t == nil {
|
|
d.Write([]byte{0})
|
|
} else {
|
|
d.Write([]byte{1})
|
|
d.WriteUint64(*t)
|
|
}
|
|
}
|
|
|
|
// WriteInt16Ptr writes one byte (1 or 0) indicating whether the pointer is non-nil,
|
|
// followed by the value if present.
|
|
func (d *Digest) WriteInt16Ptr(t *int16) {
|
|
if t == nil {
|
|
d.Write([]byte{0})
|
|
} else {
|
|
d.Write([]byte{1})
|
|
d.WriteInt16(*t)
|
|
}
|
|
}
|
|
|
|
// WriteInt32Ptr writes one byte (1 or 0) indicating whether the pointer is non-nil,
|
|
// followed by the value if present.
|
|
func (d *Digest) WriteInt32Ptr(t *int32) {
|
|
if t == nil {
|
|
d.Write([]byte{0})
|
|
} else {
|
|
d.Write([]byte{1})
|
|
d.WriteInt32(*t)
|
|
}
|
|
}
|
|
|
|
// WriteInt64Ptr writes one byte (1 or 0) indicating whether the pointer is non-nil,
|
|
// followed by the value if present.
|
|
func (d *Digest) WriteInt64Ptr(t *int64) {
|
|
if t == nil {
|
|
d.Write([]byte{0})
|
|
} else {
|
|
d.Write([]byte{1})
|
|
d.WriteInt64(*t)
|
|
}
|
|
}
|