github.com/gogf/gf@v1.16.9/encoding/gbinary/gbinary_be.go (about) 1 // Copyright GoFrame Author(https://goframe.org). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/gogf/gf. 6 7 package gbinary 8 9 import ( 10 "bytes" 11 "encoding/binary" 12 "fmt" 13 "math" 14 ) 15 16 // BeEncode encodes one or multiple <values> into bytes using BigEndian. 17 // It uses type asserting checking the type of each value of <values> and internally 18 // calls corresponding converting function do the bytes converting. 19 // 20 // It supports common variable type asserting, and finally it uses fmt.Sprintf converting 21 // value to string and then to bytes. 22 func BeEncode(values ...interface{}) []byte { 23 buf := new(bytes.Buffer) 24 for i := 0; i < len(values); i++ { 25 if values[i] == nil { 26 return buf.Bytes() 27 } 28 29 switch value := values[i].(type) { 30 case int: 31 buf.Write(BeEncodeInt(value)) 32 case int8: 33 buf.Write(BeEncodeInt8(value)) 34 case int16: 35 buf.Write(BeEncodeInt16(value)) 36 case int32: 37 buf.Write(BeEncodeInt32(value)) 38 case int64: 39 buf.Write(BeEncodeInt64(value)) 40 case uint: 41 buf.Write(BeEncodeUint(value)) 42 case uint8: 43 buf.Write(BeEncodeUint8(value)) 44 case uint16: 45 buf.Write(BeEncodeUint16(value)) 46 case uint32: 47 buf.Write(BeEncodeUint32(value)) 48 case uint64: 49 buf.Write(BeEncodeUint64(value)) 50 case bool: 51 buf.Write(BeEncodeBool(value)) 52 case string: 53 buf.Write(BeEncodeString(value)) 54 case []byte: 55 buf.Write(value) 56 case float32: 57 buf.Write(BeEncodeFloat32(value)) 58 case float64: 59 buf.Write(BeEncodeFloat64(value)) 60 default: 61 if err := binary.Write(buf, binary.BigEndian, value); err != nil { 62 buf.Write(BeEncodeString(fmt.Sprintf("%v", value))) 63 } 64 } 65 } 66 return buf.Bytes() 67 } 68 69 // 将变量转换为二进制[]byte,并指定固定的[]byte长度返回,长度单位为字节(byte); 70 // 如果转换的二进制长度超过指定长度,那么进行截断处理 71 func BeEncodeByLength(length int, values ...interface{}) []byte { 72 b := BeEncode(values...) 73 if len(b) < length { 74 b = append(b, make([]byte, length-len(b))...) 75 } else if len(b) > length { 76 b = b[0:length] 77 } 78 return b 79 } 80 81 // 整形二进制解包,注意第二个及其后参数为字长确定的整形变量的指针地址,以便确定解析的[]byte长度, 82 // 例如:int8/16/32/64、uint8/16/32/64、float32/64等等 83 func BeDecode(b []byte, values ...interface{}) error { 84 buf := bytes.NewBuffer(b) 85 for i := 0; i < len(values); i++ { 86 err := binary.Read(buf, binary.BigEndian, values[i]) 87 if err != nil { 88 return err 89 } 90 } 91 return nil 92 } 93 94 func BeEncodeString(s string) []byte { 95 return []byte(s) 96 } 97 98 func BeDecodeToString(b []byte) string { 99 return string(b) 100 } 101 102 func BeEncodeBool(b bool) []byte { 103 if b == true { 104 return []byte{1} 105 } else { 106 return []byte{0} 107 } 108 } 109 110 // 自动识别int类型长度,转换为[]byte 111 func BeEncodeInt(i int) []byte { 112 if i <= math.MaxInt8 { 113 return BeEncodeInt8(int8(i)) 114 } else if i <= math.MaxInt16 { 115 return BeEncodeInt16(int16(i)) 116 } else if i <= math.MaxInt32 { 117 return BeEncodeInt32(int32(i)) 118 } else { 119 return BeEncodeInt64(int64(i)) 120 } 121 } 122 123 // 自动识别uint类型长度,转换为[]byte 124 func BeEncodeUint(i uint) []byte { 125 if i <= math.MaxUint8 { 126 return BeEncodeUint8(uint8(i)) 127 } else if i <= math.MaxUint16 { 128 return BeEncodeUint16(uint16(i)) 129 } else if i <= math.MaxUint32 { 130 return BeEncodeUint32(uint32(i)) 131 } else { 132 return BeEncodeUint64(uint64(i)) 133 } 134 } 135 136 func BeEncodeInt8(i int8) []byte { 137 return []byte{byte(i)} 138 } 139 140 func BeEncodeUint8(i uint8) []byte { 141 return []byte{i} 142 } 143 144 func BeEncodeInt16(i int16) []byte { 145 b := make([]byte, 2) 146 binary.BigEndian.PutUint16(b, uint16(i)) 147 return b 148 } 149 150 func BeEncodeUint16(i uint16) []byte { 151 b := make([]byte, 2) 152 binary.BigEndian.PutUint16(b, i) 153 return b 154 } 155 156 func BeEncodeInt32(i int32) []byte { 157 b := make([]byte, 4) 158 binary.BigEndian.PutUint32(b, uint32(i)) 159 return b 160 } 161 162 func BeEncodeUint32(i uint32) []byte { 163 b := make([]byte, 4) 164 binary.BigEndian.PutUint32(b, i) 165 return b 166 } 167 168 func BeEncodeInt64(i int64) []byte { 169 b := make([]byte, 8) 170 binary.BigEndian.PutUint64(b, uint64(i)) 171 return b 172 } 173 174 func BeEncodeUint64(i uint64) []byte { 175 b := make([]byte, 8) 176 binary.BigEndian.PutUint64(b, i) 177 return b 178 } 179 180 func BeEncodeFloat32(f float32) []byte { 181 bits := math.Float32bits(f) 182 b := make([]byte, 4) 183 binary.BigEndian.PutUint32(b, bits) 184 return b 185 } 186 187 func BeEncodeFloat64(f float64) []byte { 188 bits := math.Float64bits(f) 189 b := make([]byte, 8) 190 binary.BigEndian.PutUint64(b, bits) 191 return b 192 } 193 194 // 将二进制解析为int类型,根据[]byte的长度进行自动转换. 195 // 注意内部使用的是uint*,使用int会造成位丢失。 196 func BeDecodeToInt(b []byte) int { 197 if len(b) < 2 { 198 return int(BeDecodeToUint8(b)) 199 } else if len(b) < 3 { 200 return int(BeDecodeToUint16(b)) 201 } else if len(b) < 5 { 202 return int(BeDecodeToUint32(b)) 203 } else { 204 return int(BeDecodeToUint64(b)) 205 } 206 } 207 208 // 将二进制解析为uint类型,根据[]byte的长度进行自动转换 209 func BeDecodeToUint(b []byte) uint { 210 if len(b) < 2 { 211 return uint(BeDecodeToUint8(b)) 212 } else if len(b) < 3 { 213 return uint(BeDecodeToUint16(b)) 214 } else if len(b) < 5 { 215 return uint(BeDecodeToUint32(b)) 216 } else { 217 return uint(BeDecodeToUint64(b)) 218 } 219 } 220 221 // 将二进制解析为bool类型,识别标准是判断二进制中数值是否都为0,或者为空。 222 func BeDecodeToBool(b []byte) bool { 223 if len(b) == 0 { 224 return false 225 } 226 if bytes.Compare(b, make([]byte, len(b))) == 0 { 227 return false 228 } 229 return true 230 } 231 232 func BeDecodeToInt8(b []byte) int8 { 233 return int8(b[0]) 234 } 235 236 func BeDecodeToUint8(b []byte) uint8 { 237 return uint8(b[0]) 238 } 239 240 func BeDecodeToInt16(b []byte) int16 { 241 return int16(binary.BigEndian.Uint16(BeFillUpSize(b, 2))) 242 } 243 244 func BeDecodeToUint16(b []byte) uint16 { 245 return binary.BigEndian.Uint16(BeFillUpSize(b, 2)) 246 } 247 248 func BeDecodeToInt32(b []byte) int32 { 249 return int32(binary.BigEndian.Uint32(BeFillUpSize(b, 4))) 250 } 251 252 func BeDecodeToUint32(b []byte) uint32 { 253 return binary.BigEndian.Uint32(BeFillUpSize(b, 4)) 254 } 255 256 func BeDecodeToInt64(b []byte) int64 { 257 return int64(binary.BigEndian.Uint64(BeFillUpSize(b, 8))) 258 } 259 260 func BeDecodeToUint64(b []byte) uint64 { 261 return binary.BigEndian.Uint64(BeFillUpSize(b, 8)) 262 } 263 264 func BeDecodeToFloat32(b []byte) float32 { 265 return math.Float32frombits(binary.BigEndian.Uint32(BeFillUpSize(b, 4))) 266 } 267 268 func BeDecodeToFloat64(b []byte) float64 { 269 return math.Float64frombits(binary.BigEndian.Uint64(BeFillUpSize(b, 8))) 270 } 271 272 // BeFillUpSize fills up the bytes <b> to given length <l> using big BigEndian. 273 // 274 // Note that it creates a new bytes slice by copying the original one to avoid changing 275 // the original parameter bytes. 276 func BeFillUpSize(b []byte, l int) []byte { 277 if len(b) >= l { 278 return b[:l] 279 } 280 c := make([]byte, l) 281 copy(c[l-len(b):], b) 282 return c 283 }