github.com/jonasnick/go-ethereum@v0.7.12-0.20150216215225-22176f05d387/ethutil/bytes.go (about) 1 package ethutil 2 3 import ( 4 "bytes" 5 "encoding/binary" 6 "encoding/hex" 7 "fmt" 8 "math/big" 9 "strings" 10 ) 11 12 type Bytes []byte 13 14 func (self Bytes) String() string { 15 return string(self) 16 } 17 18 func DeleteFromByteSlice(s [][]byte, hash []byte) [][]byte { 19 for i, h := range s { 20 if bytes.Compare(h, hash) == 0 { 21 return append(s[:i:i], s[i+1:]...) 22 } 23 } 24 25 return s 26 } 27 28 // Number to bytes 29 // 30 // Returns the number in bytes with the specified base 31 func NumberToBytes(num interface{}, bits int) []byte { 32 buf := new(bytes.Buffer) 33 err := binary.Write(buf, binary.BigEndian, num) 34 if err != nil { 35 fmt.Println("NumberToBytes failed:", err) 36 } 37 38 return buf.Bytes()[buf.Len()-(bits/8):] 39 } 40 41 // Bytes to number 42 // 43 // Attempts to cast a byte slice to a unsigned integer 44 func BytesToNumber(b []byte) uint64 { 45 var number uint64 46 47 // Make sure the buffer is 64bits 48 data := make([]byte, 8) 49 data = append(data[:len(b)], b...) 50 51 buf := bytes.NewReader(data) 52 err := binary.Read(buf, binary.BigEndian, &number) 53 if err != nil { 54 fmt.Println("BytesToNumber failed:", err) 55 } 56 57 return number 58 } 59 60 // Read variable int 61 // 62 // Read a variable length number in big endian byte order 63 func ReadVarInt(buff []byte) (ret uint64) { 64 switch l := len(buff); { 65 case l > 4: 66 d := LeftPadBytes(buff, 8) 67 binary.Read(bytes.NewReader(d), binary.BigEndian, &ret) 68 case l > 2: 69 var num uint32 70 d := LeftPadBytes(buff, 4) 71 binary.Read(bytes.NewReader(d), binary.BigEndian, &num) 72 ret = uint64(num) 73 case l > 1: 74 var num uint16 75 d := LeftPadBytes(buff, 2) 76 binary.Read(bytes.NewReader(d), binary.BigEndian, &num) 77 ret = uint64(num) 78 default: 79 var num uint8 80 binary.Read(bytes.NewReader(buff), binary.BigEndian, &num) 81 ret = uint64(num) 82 } 83 84 return 85 } 86 87 // Binary length 88 // 89 // Returns the true binary length of the given number 90 func BinaryLength(num int) int { 91 if num == 0 { 92 return 0 93 } 94 95 return 1 + BinaryLength(num>>8) 96 } 97 98 // Copy bytes 99 // 100 // Returns an exact copy of the provided bytes 101 func CopyBytes(b []byte) (copiedBytes []byte) { 102 copiedBytes = make([]byte, len(b)) 103 copy(copiedBytes, b) 104 105 return 106 } 107 108 func IsHex(str string) bool { 109 l := len(str) 110 return l >= 4 && l%2 == 0 && str[0:2] == "0x" 111 } 112 113 func Bytes2Hex(d []byte) string { 114 return hex.EncodeToString(d) 115 } 116 117 func Hex2Bytes(str string) []byte { 118 h, _ := hex.DecodeString(str) 119 120 return h 121 } 122 123 func StringToByteFunc(str string, cb func(str string) []byte) (ret []byte) { 124 if len(str) > 1 && str[0:2] == "0x" && !strings.Contains(str, "\n") { 125 ret = Hex2Bytes(str[2:]) 126 } else { 127 ret = cb(str) 128 } 129 130 return 131 } 132 133 func FormatData(data string) []byte { 134 if len(data) == 0 { 135 return nil 136 } 137 // Simple stupid 138 d := new(big.Int) 139 if data[0:1] == "\"" && data[len(data)-1:] == "\"" { 140 return RightPadBytes([]byte(data[1:len(data)-1]), 32) 141 } else if len(data) > 1 && data[:2] == "0x" { 142 d.SetBytes(Hex2Bytes(data[2:])) 143 } else { 144 d.SetString(data, 0) 145 } 146 147 return BigToBytes(d, 256) 148 } 149 150 func ParseData(data ...interface{}) (ret []byte) { 151 for _, item := range data { 152 switch t := item.(type) { 153 case string: 154 var str []byte 155 if IsHex(t) { 156 str = Hex2Bytes(t[2:]) 157 } else { 158 str = []byte(t) 159 } 160 161 ret = append(ret, RightPadBytes(str, 32)...) 162 case []byte: 163 ret = append(ret, LeftPadBytes(t, 32)...) 164 } 165 } 166 167 return 168 } 169 170 func RightPadBytes(slice []byte, l int) []byte { 171 if l < len(slice) { 172 return slice 173 } 174 175 padded := make([]byte, l) 176 copy(padded[0:len(slice)], slice) 177 178 return padded 179 } 180 181 func LeftPadBytes(slice []byte, l int) []byte { 182 if l < len(slice) { 183 return slice 184 } 185 186 padded := make([]byte, l) 187 copy(padded[l-len(slice):], slice) 188 189 return padded 190 } 191 192 func LeftPadString(str string, l int) string { 193 if l < len(str) { 194 return str 195 } 196 197 zeros := Bytes2Hex(make([]byte, (l-len(str))/2)) 198 199 return zeros + str 200 201 } 202 203 func RightPadString(str string, l int) string { 204 if l < len(str) { 205 return str 206 } 207 208 zeros := Bytes2Hex(make([]byte, (l-len(str))/2)) 209 210 return str + zeros 211 212 } 213 214 func Address(slice []byte) (addr []byte) { 215 if len(slice) < 20 { 216 addr = LeftPadBytes(slice, 20) 217 } else if len(slice) > 20 { 218 addr = slice[len(slice)-20:] 219 } else { 220 addr = slice 221 } 222 223 addr = CopyBytes(addr) 224 225 return 226 } 227 228 func ByteSliceToInterface(slice [][]byte) (ret []interface{}) { 229 for _, i := range slice { 230 ret = append(ret, i) 231 } 232 233 return 234 }