github.com/cheng762/platon-go@v1.8.17-0.20190529111256-7deff2d7be26/common/bytes.go (about)

     1  // Copyright 2014 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 common contains various helper functions.
    18  package common
    19  
    20  import (
    21  	"bytes"
    22  	"encoding/binary"
    23  	"encoding/hex"
    24  	"math"
    25  )
    26  
    27  // ToHex returns the hex representation of b, prefixed with '0x'.
    28  // For empty slices, the return value is "0x0".
    29  //
    30  // Deprecated: use hexutil.Encode instead.
    31  func ToHex(b []byte) string {
    32  	hex := Bytes2Hex(b)
    33  	if len(hex) == 0 {
    34  		hex = "0"
    35  	}
    36  	return "0x" + hex
    37  }
    38  
    39  // FromHex returns the bytes represented by the hexadecimal string s.
    40  // s may be prefixed with "0x".
    41  func FromHex(s string) []byte {
    42  	if len(s) > 1 {
    43  		if s[0:2] == "0x" || s[0:2] == "0X" {
    44  			s = s[2:]
    45  		}
    46  	}
    47  	if len(s)%2 == 1 {
    48  		s = "0" + s
    49  	}
    50  	return Hex2Bytes(s)
    51  }
    52  
    53  // CopyBytes returns an exact copy of the provided bytes.
    54  func CopyBytes(b []byte) (copiedBytes []byte) {
    55  	if b == nil {
    56  		return nil
    57  	}
    58  	copiedBytes = make([]byte, len(b))
    59  	copy(copiedBytes, b)
    60  
    61  	return
    62  }
    63  
    64  // hasHexPrefix validates str begins with '0x' or '0X'.
    65  func hasHexPrefix(str string) bool {
    66  	return len(str) >= 2 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X')
    67  }
    68  
    69  // isHexCharacter returns bool of c being a valid hexadecimal.
    70  func isHexCharacter(c byte) bool {
    71  	return ('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F')
    72  }
    73  
    74  // isHex validates whether each byte is valid hexadecimal string.
    75  func isHex(str string) bool {
    76  	if len(str)%2 != 0 {
    77  		return false
    78  	}
    79  	for _, c := range []byte(str) {
    80  		if !isHexCharacter(c) {
    81  			return false
    82  		}
    83  	}
    84  	return true
    85  }
    86  
    87  // Bytes2Hex returns the hexadecimal encoding of d.
    88  func Bytes2Hex(d []byte) string {
    89  	return hex.EncodeToString(d)
    90  }
    91  
    92  // Hex2Bytes returns the bytes represented by the hexadecimal string str.
    93  func Hex2Bytes(str string) []byte {
    94  	h, _ := hex.DecodeString(str)
    95  	return h
    96  }
    97  
    98  // Hex2BytesFixed returns bytes of a specified fixed length flen.
    99  func Hex2BytesFixed(str string, flen int) []byte {
   100  	h, _ := hex.DecodeString(str)
   101  	if len(h) == flen {
   102  		return h
   103  	}
   104  	if len(h) > flen {
   105  		return h[len(h)-flen:]
   106  	}
   107  	hh := make([]byte, flen)
   108  	copy(hh[flen-len(h):flen], h)
   109  	return hh
   110  }
   111  
   112  // RightPadBytes zero-pads slice to the right up to length l.
   113  func RightPadBytes(slice []byte, l int) []byte {
   114  	if l <= len(slice) {
   115  		return slice
   116  	}
   117  
   118  	padded := make([]byte, l)
   119  	copy(padded, slice)
   120  
   121  	return padded
   122  }
   123  
   124  // LeftPadBytes zero-pads slice to the left up to length l.
   125  func LeftPadBytes(slice []byte, l int) []byte {
   126  	if l <= len(slice) {
   127  		return slice
   128  	}
   129  
   130  	padded := make([]byte, l)
   131  	copy(padded[l-len(slice):], slice)
   132  
   133  	return padded
   134  }
   135  
   136  func BytesCombine(pBytes ...[]byte) []byte {
   137  	return bytes.Join(pBytes, []byte(""))
   138  }
   139  
   140  func Int32ToBytes(n int32) []byte {
   141  	tmp := int32(n)
   142  	bytesBuffer := bytes.NewBuffer([]byte{})
   143  	binary.Write(bytesBuffer, binary.BigEndian, tmp)
   144  	return bytesBuffer.Bytes()
   145  }
   146  
   147  func BytesToInt32(b []byte) int32 {
   148  	bytesBuffer := bytes.NewBuffer(b)
   149  	var tmp int32
   150  	binary.Read(bytesBuffer, binary.BigEndian, &tmp)
   151  	return int32(tmp)
   152  }
   153  
   154  func Int64ToBytes(n int64) []byte {
   155  	tmp := int64(n)
   156  	bytesBuffer := bytes.NewBuffer([]byte{})
   157  	binary.Write(bytesBuffer, binary.BigEndian, tmp)
   158  	return bytesBuffer.Bytes()
   159  }
   160  
   161  func BytesToInt64(b []byte) int64 {
   162  	bytesBuffer := bytes.NewBuffer(b)
   163  	var tmp int64
   164  	binary.Read(bytesBuffer, binary.BigEndian, &tmp)
   165  	return int64(tmp)
   166  }
   167  
   168  func Float32ToBytes(float float32) []byte {
   169  	bits := math.Float32bits(float)
   170  	bytes := make([]byte, 4)
   171  	binary.LittleEndian.PutUint32(bytes, bits)
   172  	return bytes
   173  }
   174  
   175  func BytesToFloat32(bytes []byte) float32 {
   176  	bits := binary.LittleEndian.Uint32(bytes)
   177  	return math.Float32frombits(bits)
   178  }
   179  
   180  func Float64ToBytes(float float64) []byte {
   181  	bits := math.Float64bits(float)
   182  	bytes := make([]byte, 8)
   183  	binary.LittleEndian.PutUint64(bytes, bits)
   184  	return bytes
   185  }
   186  
   187  func BytesToFloat64(bytes []byte) float64 {
   188  	bits := binary.LittleEndian.Uint64(bytes)
   189  	return math.Float64frombits(bits)
   190  }
   191  
   192  func PaddingLeft(src []byte, bytes int) []byte {
   193  	if len(src) >= bytes {
   194  		return src
   195  	}
   196  	dst := make([]byte, bytes)
   197  	copy(dst, src)
   198  	return reverse(dst)
   199  }
   200  
   201  func reverse(s []byte) []byte {
   202  	for i, j := 0, len(s) - 1; i < j; i, j = i + 1, j - 1 {
   203  		s[i], s[j] = s[j], s[i]
   204  	}
   205  	return s
   206  }