github.com/ledgerwatch/erigon-lib@v1.0.0/common/hexutility/hex.go (about)

     1  /*
     2     Copyright 2021 Erigon contributors
     3  
     4     Licensed under the Apache License, Version 2.0 (the "License");
     5     you may not use this file except in compliance with the License.
     6     You may obtain a copy of the License at
     7  
     8         http://www.apache.org/licenses/LICENSE-2.0
     9  
    10     Unless required by applicable law or agreed to in writing, software
    11     distributed under the License is distributed on an "AS IS" BASIS,
    12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13     See the License for the specific language governing permissions and
    14     limitations under the License.
    15  */
    16  
    17  package hexutility
    18  
    19  import (
    20  	"encoding/binary"
    21  	"encoding/hex"
    22  )
    23  
    24  func MustDecodeHex(in string) []byte {
    25  	in = strip0x(in)
    26  	if len(in)%2 == 1 {
    27  		in = "0" + in
    28  	}
    29  	payload, err := hex.DecodeString(in)
    30  	if err != nil {
    31  		panic(err)
    32  	}
    33  	return payload
    34  }
    35  
    36  func strip0x(str string) string {
    37  	if len(str) >= 2 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X') {
    38  		return str[2:]
    39  	}
    40  	return str
    41  }
    42  
    43  // EncodeTs encodes a TimeStamp (BlockNumber or TxNumber or other uin64) as big endian
    44  func EncodeTs(number uint64) []byte {
    45  	enc := make([]byte, 8)
    46  	binary.BigEndian.PutUint64(enc, number)
    47  	return enc
    48  }
    49  
    50  // Encode encodes b as a hex string with 0x prefix.
    51  func Encode(b []byte) string {
    52  	enc := make([]byte, len(b)*2+2)
    53  	copy(enc, "0x")
    54  	hex.Encode(enc[2:], b)
    55  	return string(enc)
    56  }
    57  
    58  func FromHex(s string) []byte {
    59  	if Has0xPrefix(s) {
    60  		s = s[2:]
    61  	}
    62  	if len(s)%2 == 1 {
    63  		s = "0" + s
    64  	}
    65  	return Hex2Bytes(s)
    66  }
    67  
    68  // Has0xPrefix validates str begins with '0x' or '0X'.
    69  func Has0xPrefix(str string) bool {
    70  	return len(str) >= 2 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X')
    71  }
    72  
    73  // Hex2Bytes returns the bytes represented by the hexadecimal string str.
    74  func Hex2Bytes(str string) []byte {
    75  	h, _ := hex.DecodeString(str)
    76  	return h
    77  }
    78  
    79  // IsHex validates whether each byte is valid hexadecimal string.
    80  func IsHex(str string) bool {
    81  	if len(str)%2 != 0 {
    82  		return false
    83  	}
    84  	for _, c := range []byte(str) {
    85  		if !isHexCharacter(c) {
    86  			return false
    87  		}
    88  	}
    89  	return true
    90  }
    91  
    92  // isHexCharacter returns bool of c being a valid hexadecimal.
    93  func isHexCharacter(c byte) bool {
    94  	return ('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F')
    95  }
    96  
    97  func MustDecodeString(s string) []byte {
    98  	r, err := hex.DecodeString(s)
    99  	if err != nil {
   100  		panic(err)
   101  	}
   102  	return r
   103  }