github.com/jincm/wesharechain@v0.0.0-20210122032815-1537409ce26a/chain/swarm/chunk/chunk.go (about)

     1  package chunk
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  
     7  	"github.com/ethereum/go-ethereum/common"
     8  )
     9  
    10  const (
    11  	DefaultSize   = 4096
    12  	MaxPO         = 16
    13  	AddressLength = 32
    14  )
    15  
    16  var (
    17  	ErrChunkNotFound = errors.New("chunk not found")
    18  	ErrChunkInvalid  = errors.New("invalid chunk")
    19  )
    20  
    21  type Chunk interface {
    22  	Address() Address
    23  	Data() []byte
    24  }
    25  
    26  type chunk struct {
    27  	addr  Address
    28  	sdata []byte
    29  }
    30  
    31  func NewChunk(addr Address, data []byte) *chunk {
    32  	return &chunk{
    33  		addr:  addr,
    34  		sdata: data,
    35  	}
    36  }
    37  
    38  func (c *chunk) Address() Address {
    39  	return c.addr
    40  }
    41  
    42  func (c *chunk) Data() []byte {
    43  	return c.sdata
    44  }
    45  
    46  func (self *chunk) String() string {
    47  	return fmt.Sprintf("Address: %v Chunksize: %v", self.addr.Log(), len(self.sdata))
    48  }
    49  
    50  type Address []byte
    51  
    52  var ZeroAddr = Address(common.Hash{}.Bytes())
    53  
    54  func (a Address) Hex() string {
    55  	return fmt.Sprintf("%064x", []byte(a[:]))
    56  }
    57  
    58  func (a Address) Log() string {
    59  	if len(a[:]) < 8 {
    60  		return fmt.Sprintf("%x", []byte(a[:]))
    61  	}
    62  	return fmt.Sprintf("%016x", []byte(a[:8]))
    63  }
    64  
    65  func (a Address) String() string {
    66  	return fmt.Sprintf("%064x", []byte(a))
    67  }
    68  
    69  func (a Address) MarshalJSON() (out []byte, err error) {
    70  	return []byte(`"` + a.String() + `"`), nil
    71  }
    72  
    73  func (a *Address) UnmarshalJSON(value []byte) error {
    74  	s := string(value)
    75  	*a = make([]byte, 32)
    76  	h := common.Hex2Bytes(s[1 : len(s)-1])
    77  	copy(*a, h)
    78  	return nil
    79  }
    80  
    81  // Proximity returns the proximity order of the MSB distance between x and y
    82  //
    83  // The distance metric MSB(x, y) of two equal length byte sequences x an y is the
    84  // value of the binary integer cast of the x^y, ie., x and y bitwise xor-ed.
    85  // the binary cast is big endian: most significant bit first (=MSB).
    86  //
    87  // Proximity(x, y) is a discrete logarithmic scaling of the MSB distance.
    88  // It is defined as the reverse rank of the integer part of the base 2
    89  // logarithm of the distance.
    90  // It is calculated by counting the number of common leading zeros in the (MSB)
    91  // binary representation of the x^y.
    92  //
    93  // (0 farthest, 255 closest, 256 self)
    94  func Proximity(one, other []byte) (ret int) {
    95  	b := (MaxPO-1)/8 + 1
    96  	if b > len(one) {
    97  		b = len(one)
    98  	}
    99  	m := 8
   100  	for i := 0; i < b; i++ {
   101  		oxo := one[i] ^ other[i]
   102  		for j := 0; j < m; j++ {
   103  			if (oxo>>uint8(7-j))&0x01 != 0 {
   104  				return i*8 + j
   105  			}
   106  		}
   107  	}
   108  	return MaxPO
   109  }