github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/swarm/multihash/multihash.go (about)

     1  
     2  //此源码被清华学神尹成大魔王专业翻译分析并修改
     3  //尹成QQ77025077
     4  //尹成微信18510341407
     5  //尹成所在QQ群721929980
     6  //尹成邮箱 yinc13@mails.tsinghua.edu.cn
     7  //尹成毕业于清华大学,微软区块链领域全球最有价值专家
     8  //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620
     9  //
    10  //
    11  //
    12  //
    13  //
    14  //
    15  //
    16  //
    17  //
    18  //
    19  //
    20  //
    21  //
    22  //
    23  //
    24  
    25  package multihash
    26  
    27  import (
    28  	"bytes"
    29  	"encoding/binary"
    30  	"errors"
    31  	"fmt"
    32  )
    33  
    34  const (
    35  	defaultMultihashLength   = 32
    36  	defaultMultihashTypeCode = 0x1b
    37  )
    38  
    39  var (
    40  	multihashTypeCode uint8
    41  	MultihashLength   = defaultMultihashLength
    42  )
    43  
    44  func init() {
    45  	multihashTypeCode = defaultMultihashTypeCode
    46  	MultihashLength = defaultMultihashLength
    47  }
    48  
    49  //
    50  func isSwarmMultihashType(code uint8) bool {
    51  	return code == multihashTypeCode
    52  }
    53  
    54  //
    55  //
    56  func GetMultihashLength(data []byte) (int, int, error) {
    57  	cursor := 0
    58  	typ, c := binary.Uvarint(data)
    59  	if c <= 0 {
    60  		return 0, 0, errors.New("unreadable hashtype field")
    61  	}
    62  	if !isSwarmMultihashType(uint8(typ)) {
    63  		return 0, 0, fmt.Errorf("hash code %x is not a swarm hashtype", typ)
    64  	}
    65  	cursor += c
    66  	hashlength, c := binary.Uvarint(data[cursor:])
    67  	if c <= 0 {
    68  		return 0, 0, errors.New("unreadable length field")
    69  	}
    70  	cursor += c
    71  
    72  //
    73  	inthashlength := int(hashlength)
    74  	if len(data[c:]) < inthashlength {
    75  		return 0, 0, errors.New("length mismatch")
    76  	}
    77  	return inthashlength, cursor, nil
    78  }
    79  
    80  //
    81  //
    82  func FromMultihash(data []byte) ([]byte, error) {
    83  	hashLength, _, err := GetMultihashLength(data)
    84  	if err != nil {
    85  		return nil, err
    86  	}
    87  	return data[len(data)-hashLength:], nil
    88  }
    89  
    90  //
    91  func ToMultihash(hashData []byte) []byte {
    92  	buf := bytes.NewBuffer(nil)
    93  	b := make([]byte, 8)
    94  	c := binary.PutUvarint(b, uint64(multihashTypeCode))
    95  	buf.Write(b[:c])
    96  	c = binary.PutUvarint(b, uint64(len(hashData)))
    97  	buf.Write(b[:c])
    98  	buf.Write(hashData)
    99  	return buf.Bytes()
   100  }