github.com/stafiprotocol/go-substrate-rpc-client@v1.4.7/xxhash/xxhash.go (about)

     1  // Go Substrate RPC Client (GSRPC) provides APIs and types around Polkadot and any Substrate-based chain RPC calls
     2  //
     3  // Copyright 2020 Stafi Protocol
     4  //
     5  // Licensed under the Apache License, Version 2.0 (the "License");
     6  // you may not use this file except in compliance with the License.
     7  // You may obtain a copy of the License at
     8  //
     9  //     http://www.apache.org/licenses/LICENSE-2.0
    10  //
    11  // Unless required by applicable law or agreed to in writing, software
    12  // distributed under the License is distributed on an "AS IS" BASIS,
    13  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14  // See the License for the specific language governing permissions and
    15  // limitations under the License.
    16  
    17  package xxhash
    18  
    19  import (
    20  	"hash"
    21  
    22  	"github.com/pierrec/xxHash/xxHash64"
    23  )
    24  
    25  const (
    26  	Typ64 int = iota
    27  	Typ64Concat
    28  	Typ128
    29  	Typ256
    30  )
    31  
    32  type state struct {
    33  	data   []byte
    34  	typ    int
    35  	rounds int
    36  }
    37  
    38  // New64 returns a new hash.Hash computing the xxhash checksum with 1 iteration
    39  func New64(b []byte) hash.Hash {
    40  	return &state{
    41  		data:   b,
    42  		typ:    Typ64,
    43  		rounds: 1,
    44  	}
    45  }
    46  
    47  // New64Concat returns a new hash.Hash computing the xxhash checksum with 1 iteration and appending the data
    48  func New64Concat(b []byte) hash.Hash {
    49  	return &state{
    50  		data:   b,
    51  		typ:    Typ64Concat,
    52  		rounds: 1,
    53  	}
    54  }
    55  
    56  // New128 returns a new hash.Hash computing the xxhash checksum with 2 iterations
    57  func New128(b []byte) hash.Hash {
    58  	return &state{
    59  		data:   b,
    60  		typ:    Typ128,
    61  		rounds: 2,
    62  	}
    63  }
    64  
    65  // New256 returns a new hash.Hash computing the xxhash checksum with 4 iterations
    66  func New256(b []byte) hash.Hash {
    67  	return &state{
    68  		data:   b,
    69  		typ:    Typ256,
    70  		rounds: 4,
    71  	}
    72  }
    73  
    74  // Write (via the embedded io.Writer interface) adds more data to the running hash.
    75  // It never returns an error.
    76  func (s *state) Write(p []byte) (n int, err error) {
    77  	s.data = append(s.data, p...)
    78  	return len(p), nil
    79  }
    80  
    81  // Sum appends the current hash to b and returns the resulting slice.
    82  // It does not change the underlying hash state.
    83  func (s *state) Sum(b []byte) []byte {
    84  	res := make([]byte, 0, s.rounds*8)
    85  
    86  	for i := 0; i < s.rounds; i++ {
    87  		h := xxHash64.New(uint64(i))
    88  		_, err := h.Write(s.data)
    89  		if err != nil {
    90  			panic(err)
    91  		}
    92  		res = append(res, h.Sum(nil)...)
    93  	}
    94  
    95  	if s.typ == Typ64Concat {
    96  		res = append(res, s.data...)
    97  	}
    98  	return append(b, res...)
    99  }
   100  
   101  // Reset resets the Hash to its initial state.
   102  func (s *state) Reset() {
   103  	s.data = make([]byte, 0)
   104  }
   105  
   106  // Size returns the number of bytes Sum will return.
   107  func (s *state) Size() int {
   108  	return len(s.Sum(nil))
   109  }
   110  
   111  // BlockSize returns the hash's underlying block size.
   112  // The Write method must be able to accept any amount
   113  // of data, but it may operate more efficiently if all writes
   114  // are a multiple of the block size.
   115  func (s *state) BlockSize() int {
   116  	return 64
   117  }