hexutil.go 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. // Copyright 2016 The go-ethereum Authors
  2. // This file is part of the go-ethereum library.
  3. //
  4. // The go-ethereum library is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU Lesser General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // The go-ethereum library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU Lesser General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Lesser General Public License
  15. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
  16. /*
  17. Package hexutil implements hex encoding with 0x prefix.
  18. This encoding is used by the Ethereum RPC API to transport binary data in JSON payloads.
  19. Encoding Rules
  20. All hex data must have prefix "0x".
  21. For byte slices, the hex data must be of even length. An empty byte slice
  22. encodes as "0x".
  23. Integers are encoded using the least amount of digits (no leading zero digits). Their
  24. encoding may be of uneven length. The number zero encodes as "0x0".
  25. */
  26. package hexutil
  27. import (
  28. "encoding/hex"
  29. "fmt"
  30. "math/big"
  31. "strconv"
  32. )
  33. const uintBits = 32 << (uint64(^uint(0)) >> 63)
  34. var (
  35. ErrEmptyString = &decError{"empty hex string"}
  36. ErrSyntax = &decError{"invalid hex string"}
  37. ErrMissingPrefix = &decError{"hex string without 0x prefix"}
  38. ErrOddLength = &decError{"hex string of odd length"}
  39. ErrEmptyNumber = &decError{"hex string \"0x\""}
  40. ErrLeadingZero = &decError{"hex number with leading zero digits"}
  41. ErrUint64Range = &decError{"hex number > 64 bits"}
  42. ErrUintRange = &decError{fmt.Sprintf("hex number > %d bits", uintBits)}
  43. ErrBig256Range = &decError{"hex number > 256 bits"}
  44. )
  45. type decError struct{ msg string }
  46. func (err decError) Error() string { return err.msg }
  47. // Decode decodes a hex string with 0x prefix.
  48. func Decode(input string) ([]byte, error) {
  49. if len(input) == 0 {
  50. return nil, ErrEmptyString
  51. }
  52. if !has0xPrefix(input) {
  53. return nil, ErrMissingPrefix
  54. }
  55. b, err := hex.DecodeString(input[2:])
  56. if err != nil {
  57. err = mapError(err)
  58. }
  59. return b, err
  60. }
  61. // MustDecode decodes a hex string with 0x prefix. It panics for invalid input.
  62. func MustDecode(input string) []byte {
  63. dec, err := Decode(input)
  64. if err != nil {
  65. panic(err)
  66. }
  67. return dec
  68. }
  69. // Encode encodes b as a hex string with 0x prefix.
  70. func Encode(b []byte) string {
  71. enc := make([]byte, len(b)*2+2)
  72. copy(enc, "0x")
  73. hex.Encode(enc[2:], b)
  74. return string(enc)
  75. }
  76. // DecodeUint64 decodes a hex string with 0x prefix as a quantity.
  77. func DecodeUint64(input string) (uint64, error) {
  78. raw, err := checkNumber(input)
  79. if err != nil {
  80. return 0, err
  81. }
  82. dec, err := strconv.ParseUint(raw, 16, 64)
  83. if err != nil {
  84. err = mapError(err)
  85. }
  86. return dec, err
  87. }
  88. // MustDecodeUint64 decodes a hex string with 0x prefix as a quantity.
  89. // It panics for invalid input.
  90. func MustDecodeUint64(input string) uint64 {
  91. dec, err := DecodeUint64(input)
  92. if err != nil {
  93. panic(err)
  94. }
  95. return dec
  96. }
  97. // EncodeUint64 encodes i as a hex string with 0x prefix.
  98. func EncodeUint64(i uint64) string {
  99. enc := make([]byte, 2, 10)
  100. copy(enc, "0x")
  101. return string(strconv.AppendUint(enc, i, 16))
  102. }
  103. var bigWordNibbles int
  104. func init() {
  105. // This is a weird way to compute the number of nibbles required for big.Word.
  106. // The usual way would be to use constant arithmetic but go vet can't handle that.
  107. b, _ := new(big.Int).SetString("FFFFFFFFFF", 16)
  108. switch len(b.Bits()) {
  109. case 1:
  110. bigWordNibbles = 16
  111. case 2:
  112. bigWordNibbles = 8
  113. default:
  114. panic("weird big.Word size")
  115. }
  116. }
  117. // DecodeBig decodes a hex string with 0x prefix as a quantity.
  118. // Numbers larger than 256 bits are not accepted.
  119. func DecodeBig(input string) (*big.Int, error) {
  120. raw, err := checkNumber(input)
  121. if err != nil {
  122. return nil, err
  123. }
  124. if len(raw) > 64 {
  125. return nil, ErrBig256Range
  126. }
  127. words := make([]big.Word, len(raw)/bigWordNibbles+1)
  128. end := len(raw)
  129. for i := range words {
  130. start := end - bigWordNibbles
  131. if start < 0 {
  132. start = 0
  133. }
  134. for ri := start; ri < end; ri++ {
  135. nib := decodeNibble(raw[ri])
  136. if nib == badNibble {
  137. return nil, ErrSyntax
  138. }
  139. words[i] *= 16
  140. words[i] += big.Word(nib)
  141. }
  142. end = start
  143. }
  144. dec := new(big.Int).SetBits(words)
  145. return dec, nil
  146. }
  147. // MustDecodeBig decodes a hex string with 0x prefix as a quantity.
  148. // It panics for invalid input.
  149. func MustDecodeBig(input string) *big.Int {
  150. dec, err := DecodeBig(input)
  151. if err != nil {
  152. panic(err)
  153. }
  154. return dec
  155. }
  156. // EncodeBig encodes bigint as a hex string with 0x prefix.
  157. // The sign of the integer is ignored.
  158. func EncodeBig(bigint *big.Int) string {
  159. nbits := bigint.BitLen()
  160. if nbits == 0 {
  161. return "0x0"
  162. }
  163. return fmt.Sprintf("%#x", bigint)
  164. }
  165. func has0xPrefix(input string) bool {
  166. return len(input) >= 2 && input[0] == '0' && (input[1] == 'x' || input[1] == 'X')
  167. }
  168. func checkNumber(input string) (raw string, err error) {
  169. if len(input) == 0 {
  170. return "", ErrEmptyString
  171. }
  172. if !has0xPrefix(input) {
  173. return "", ErrMissingPrefix
  174. }
  175. input = input[2:]
  176. if len(input) == 0 {
  177. return "", ErrEmptyNumber
  178. }
  179. if len(input) > 1 && input[0] == '0' {
  180. return "", ErrLeadingZero
  181. }
  182. return input, nil
  183. }
  184. const badNibble = ^uint64(0)
  185. func decodeNibble(in byte) uint64 {
  186. switch {
  187. case in >= '0' && in <= '9':
  188. return uint64(in - '0')
  189. case in >= 'A' && in <= 'F':
  190. return uint64(in - 'A' + 10)
  191. case in >= 'a' && in <= 'f':
  192. return uint64(in - 'a' + 10)
  193. default:
  194. return badNibble
  195. }
  196. }
  197. func mapError(err error) error {
  198. if err, ok := err.(*strconv.NumError); ok {
  199. switch err.Err {
  200. case strconv.ErrRange:
  201. return ErrUint64Range
  202. case strconv.ErrSyntax:
  203. return ErrSyntax
  204. }
  205. }
  206. if _, ok := err.(hex.InvalidByteError); ok {
  207. return ErrSyntax
  208. }
  209. if err == hex.ErrLength {
  210. return ErrOddLength
  211. }
  212. return err
  213. }