github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/common/hexutil/hexutil.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  //版权所有2016 Go Ethereum作者
    10  //此文件是Go以太坊库的一部分。
    11  //
    12  //Go-Ethereum库是免费软件:您可以重新分发它和/或修改
    13  //根据GNU发布的较低通用公共许可证的条款
    14  //自由软件基金会,或者许可证的第3版,或者
    15  //(由您选择)任何更高版本。
    16  //
    17  //Go以太坊图书馆的发行目的是希望它会有用,
    18  //但没有任何保证;甚至没有
    19  //适销性或特定用途的适用性。见
    20  //GNU较低的通用公共许可证,了解更多详细信息。
    21  //
    22  //你应该收到一份GNU较低级别的公共许可证副本
    23  //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。
    24  
    25  /*
    26  包HexUtil使用0x前缀实现十六进制编码。
    27  Ethereum RPC API使用此编码在JSON有效负载中传输二进制数据。
    28  
    29  编码规则
    30  
    31  所有十六进制数据必须有前缀“0x”。
    32  
    33  对于字节片,十六进制数据的长度必须是偶数。空字节片
    34  编码为“0x”。
    35  
    36  整数使用最少的位数(没有前导零位数)进行编码。他们
    37  编码长度可能不均匀。数字0编码为“0x0”。
    38  **/
    39  
    40  package hexutil
    41  
    42  import (
    43  	"encoding/hex"
    44  	"fmt"
    45  	"math/big"
    46  	"strconv"
    47  )
    48  
    49  const uintBits = 32 << (uint64(^uint(0)) >> 63)
    50  
    51  //错误
    52  var (
    53  	ErrEmptyString   = &decError{"empty hex string"}
    54  	ErrSyntax        = &decError{"invalid hex string"}
    55  	ErrMissingPrefix = &decError{"hex string without 0x prefix"}
    56  	ErrOddLength     = &decError{"hex string of odd length"}
    57  	ErrEmptyNumber   = &decError{"hex string \"0x\""}
    58  	ErrLeadingZero   = &decError{"hex number with leading zero digits"}
    59  	ErrUint64Range   = &decError{"hex number > 64 bits"}
    60  	ErrUintRange     = &decError{fmt.Sprintf("hex number > %d bits", uintBits)}
    61  	ErrBig256Range   = &decError{"hex number > 256 bits"}
    62  )
    63  
    64  type decError struct{ msg string }
    65  
    66  func (err decError) Error() string { return err.msg }
    67  
    68  //decode解码带0x前缀的十六进制字符串。
    69  func Decode(input string) ([]byte, error) {
    70  	if len(input) == 0 {
    71  		return nil, ErrEmptyString
    72  	}
    73  	if !has0xPrefix(input) {
    74  		return nil, ErrMissingPrefix
    75  	}
    76  	b, err := hex.DecodeString(input[2:])
    77  	if err != nil {
    78  		err = mapError(err)
    79  	}
    80  	return b, err
    81  }
    82  
    83  //must decode解码带0x前缀的十六进制字符串。它会因输入无效而恐慌。
    84  func MustDecode(input string) []byte {
    85  	dec, err := Decode(input)
    86  	if err != nil {
    87  		panic(err)
    88  	}
    89  	return dec
    90  }
    91  
    92  //将B编码为带0x前缀的十六进制字符串。
    93  func Encode(b []byte) string {
    94  	enc := make([]byte, len(b)*2+2)
    95  	copy(enc, "0x")
    96  	hex.Encode(enc[2:], b)
    97  	return string(enc)
    98  }
    99  
   100  //decodeuint64将前缀为0x的十六进制字符串解码为一个数量。
   101  func DecodeUint64(input string) (uint64, error) {
   102  	raw, err := checkNumber(input)
   103  	if err != nil {
   104  		return 0, err
   105  	}
   106  	dec, err := strconv.ParseUint(raw, 16, 64)
   107  	if err != nil {
   108  		err = mapError(err)
   109  	}
   110  	return dec, err
   111  }
   112  
   113  //mustdecodeuint64将前缀为0x的十六进制字符串解码为一个数量。
   114  //它会因输入无效而恐慌。
   115  func MustDecodeUint64(input string) uint64 {
   116  	dec, err := DecodeUint64(input)
   117  	if err != nil {
   118  		panic(err)
   119  	}
   120  	return dec
   121  }
   122  
   123  //encodeuint64将i编码为带0x前缀的十六进制字符串。
   124  func EncodeUint64(i uint64) string {
   125  	enc := make([]byte, 2, 10)
   126  	copy(enc, "0x")
   127  	return string(strconv.AppendUint(enc, i, 16))
   128  }
   129  
   130  var bigWordNibbles int
   131  
   132  func init() {
   133  //这是一种计算big.word所需的半字节数的奇怪方法。
   134  //通常的方法是使用常量算术,但是Go-Vet不能处理这个问题。
   135  	b, _ := new(big.Int).SetString("FFFFFFFFFF", 16)
   136  	switch len(b.Bits()) {
   137  	case 1:
   138  		bigWordNibbles = 16
   139  	case 2:
   140  		bigWordNibbles = 8
   141  	default:
   142  		panic("weird big.Word size")
   143  	}
   144  }
   145  
   146  //decodebig将前缀为0x的十六进制字符串解码为一个数量。
   147  //不接受大于256位的数字。
   148  func DecodeBig(input string) (*big.Int, error) {
   149  	raw, err := checkNumber(input)
   150  	if err != nil {
   151  		return nil, err
   152  	}
   153  	if len(raw) > 64 {
   154  		return nil, ErrBig256Range
   155  	}
   156  	words := make([]big.Word, len(raw)/bigWordNibbles+1)
   157  	end := len(raw)
   158  	for i := range words {
   159  		start := end - bigWordNibbles
   160  		if start < 0 {
   161  			start = 0
   162  		}
   163  		for ri := start; ri < end; ri++ {
   164  			nib := decodeNibble(raw[ri])
   165  			if nib == badNibble {
   166  				return nil, ErrSyntax
   167  			}
   168  			words[i] *= 16
   169  			words[i] += big.Word(nib)
   170  		}
   171  		end = start
   172  	}
   173  	dec := new(big.Int).SetBits(words)
   174  	return dec, nil
   175  }
   176  
   177  //mustdecodebig将前缀为0x的十六进制字符串解码为一个数量。
   178  //它会因输入无效而恐慌。
   179  func MustDecodeBig(input string) *big.Int {
   180  	dec, err := DecodeBig(input)
   181  	if err != nil {
   182  		panic(err)
   183  	}
   184  	return dec
   185  }
   186  
   187  //encodebig将bigint编码为带0x前缀的十六进制字符串。
   188  //整数的符号被忽略。
   189  func EncodeBig(bigint *big.Int) string {
   190  	nbits := bigint.BitLen()
   191  	if nbits == 0 {
   192  		return "0x0"
   193  	}
   194  	return fmt.Sprintf("%#x", bigint)
   195  }
   196  
   197  func has0xPrefix(input string) bool {
   198  	return len(input) >= 2 && input[0] == '0' && (input[1] == 'x' || input[1] == 'X')
   199  }
   200  
   201  func checkNumber(input string) (raw string, err error) {
   202  	if len(input) == 0 {
   203  		return "", ErrEmptyString
   204  	}
   205  	if !has0xPrefix(input) {
   206  		return "", ErrMissingPrefix
   207  	}
   208  	input = input[2:]
   209  	if len(input) == 0 {
   210  		return "", ErrEmptyNumber
   211  	}
   212  	if len(input) > 1 && input[0] == '0' {
   213  		return "", ErrLeadingZero
   214  	}
   215  	return input, nil
   216  }
   217  
   218  const badNibble = ^uint64(0)
   219  
   220  func decodeNibble(in byte) uint64 {
   221  	switch {
   222  	case in >= '0' && in <= '9':
   223  		return uint64(in - '0')
   224  	case in >= 'A' && in <= 'F':
   225  		return uint64(in - 'A' + 10)
   226  	case in >= 'a' && in <= 'f':
   227  		return uint64(in - 'a' + 10)
   228  	default:
   229  		return badNibble
   230  	}
   231  }
   232  
   233  func mapError(err error) error {
   234  	if err, ok := err.(*strconv.NumError); ok {
   235  		switch err.Err {
   236  		case strconv.ErrRange:
   237  			return ErrUint64Range
   238  		case strconv.ErrSyntax:
   239  			return ErrSyntax
   240  		}
   241  	}
   242  	if _, ok := err.(hex.InvalidByteError); ok {
   243  		return ErrSyntax
   244  	}
   245  	if err == hex.ErrLength {
   246  		return ErrOddLength
   247  	}
   248  	return err
   249  }