hexutil.go 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  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. // Errors
  35. var (
  36. ErrEmptyString = &decError{"empty hex string"}
  37. ErrSyntax = &decError{"invalid hex string"}
  38. ErrMissingPrefix = &decError{"hex string without 0x prefix"}
  39. ErrOddLength = &decError{"hex string of odd length"}
  40. ErrEmptyNumber = &decError{"hex string \"0x\""}
  41. ErrLeadingZero = &decError{"hex number with leading zero digits"}
  42. ErrUint64Range = &decError{"hex number > 64 bits"}
  43. ErrUintRange = &decError{fmt.Sprintf("hex number > %d bits", uintBits)}
  44. ErrBig256Range = &decError{"hex number > 256 bits"}
  45. )
  46. type decError struct{ msg string }
  47. func (err decError) Error() string { return err.msg }
  48. // Decode decodes a hex string with 0x prefix.
  49. func Decode(input string) ([]byte, error) {
  50. if len(input) == 0 {
  51. return nil, ErrEmptyString
  52. }
  53. if !has0xPrefix(input) {
  54. return nil, ErrMissingPrefix
  55. }
  56. b, err := hex.DecodeString(input[2:])
  57. if err != nil {
  58. err = mapError(err)
  59. }
  60. return b, err
  61. }
  62. // MustDecode decodes a hex string with 0x prefix. It panics for invalid input.
  63. func MustDecode(input string) []byte {
  64. dec, err := Decode(input)
  65. if err != nil {
  66. panic(err)
  67. }
  68. return dec
  69. }
  70. // Encode encodes b as a hex string with 0x prefix.
  71. func Encode(b []byte) string {
  72. enc := make([]byte, len(b)*2+2)
  73. copy(enc, "0x")
  74. hex.Encode(enc[2:], b)
  75. return string(enc)
  76. }
  77. // DecodeUint64 decodes a hex string with 0x prefix as a quantity.
  78. func DecodeUint64(input string) (uint64, error) {
  79. raw, err := checkNumber(input)
  80. if err != nil {
  81. return 0, err
  82. }
  83. dec, err := strconv.ParseUint(raw, 16, 64)
  84. if err != nil {
  85. err = mapError(err)
  86. }
  87. return dec, err
  88. }
  89. // MustDecodeUint64 decodes a hex string with 0x prefix as a quantity.
  90. // It panics for invalid input.
  91. func MustDecodeUint64(input string) uint64 {
  92. dec, err := DecodeUint64(input)
  93. if err != nil {
  94. panic(err)
  95. }
  96. return dec
  97. }
  98. // EncodeUint64 encodes i as a hex string with 0x prefix.
  99. func EncodeUint64(i uint64) string {
  100. enc := make([]byte, 2, 10)
  101. copy(enc, "0x")
  102. return string(strconv.AppendUint(enc, i, 16))
  103. }
  104. var bigWordNibbles int
  105. func init() {
  106. // This is a weird way to compute the number of nibbles required for big.Word.
  107. // The usual way would be to use constant arithmetic but go vet can't handle that.
  108. b, _ := new(big.Int).SetString("FFFFFFFFFF", 16)
  109. switch len(b.Bits()) {
  110. case 1:
  111. bigWordNibbles = 16
  112. case 2:
  113. bigWordNibbles = 8
  114. default:
  115. panic("weird big.Word size")
  116. }
  117. }
  118. // DecodeBig decodes a hex string with 0x prefix as a quantity.
  119. // Numbers larger than 256 bits are not accepted.
  120. func DecodeBig(input string) (*big.Int, error) {
  121. raw, err := checkNumber(input)
  122. if err != nil {
  123. return nil, err
  124. }
  125. if len(raw) > 64 {
  126. return nil, ErrBig256Range
  127. }
  128. words := make([]big.Word, len(raw)/bigWordNibbles+1)
  129. end := len(raw)
  130. for i := range words {
  131. start := end - bigWordNibbles
  132. if start < 0 {
  133. start = 0
  134. }
  135. for ri := start; ri < end; ri++ {
  136. nib := decodeNibble(raw[ri])
  137. if nib == badNibble {
  138. return nil, ErrSyntax
  139. }
  140. words[i] *= 16
  141. words[i] += big.Word(nib)
  142. }
  143. end = start
  144. }
  145. dec := new(big.Int).SetBits(words)
  146. return dec, nil
  147. }
  148. // MustDecodeBig decodes a hex string with 0x prefix as a quantity.
  149. // It panics for invalid input.
  150. func MustDecodeBig(input string) *big.Int {
  151. dec, err := DecodeBig(input)
  152. if err != nil {
  153. panic(err)
  154. }
  155. return dec
  156. }
  157. // EncodeBig encodes bigint as a hex string with 0x prefix.
  158. // The sign of the integer is ignored.
  159. func EncodeBig(bigint *big.Int) string {
  160. nbits := bigint.BitLen()
  161. if nbits == 0 {
  162. return "0x0"
  163. }
  164. return fmt.Sprintf("%#x", bigint)
  165. }
  166. func has0xPrefix(input string) bool {
  167. return len(input) >= 2 && input[0] == '0' && (input[1] == 'x' || input[1] == 'X')
  168. }
  169. func checkNumber(input string) (raw string, err error) {
  170. if len(input) == 0 {
  171. return "", ErrEmptyString
  172. }
  173. if !has0xPrefix(input) {
  174. return "", ErrMissingPrefix
  175. }
  176. input = input[2:]
  177. if len(input) == 0 {
  178. return "", ErrEmptyNumber
  179. }
  180. if len(input) > 1 && input[0] == '0' {
  181. return "", ErrLeadingZero
  182. }
  183. return input, nil
  184. }
  185. const badNibble = ^uint64(0)
  186. func decodeNibble(in byte) uint64 {
  187. switch {
  188. case in >= '0' && in <= '9':
  189. return uint64(in - '0')
  190. case in >= 'A' && in <= 'F':
  191. return uint64(in - 'A' + 10)
  192. case in >= 'a' && in <= 'f':
  193. return uint64(in - 'a' + 10)
  194. default:
  195. return badNibble
  196. }
  197. }
  198. func mapError(err error) error {
  199. if err, ok := err.(*strconv.NumError); ok {
  200. switch err.Err {
  201. case strconv.ErrRange:
  202. return ErrUint64Range
  203. case strconv.ErrSyntax:
  204. return ErrSyntax
  205. }
  206. }
  207. if _, ok := err.(hex.InvalidByteError); ok {
  208. return ErrSyntax
  209. }
  210. if err == hex.ErrLength {
  211. return ErrOddLength
  212. }
  213. return err
  214. }