conversion.gno
18.33 Kb ยท 570 lines
1// conversions contains methods for converting Uint instances to other types and vice versa.
2// This includes conversions to and from basic types such as uint64 and int32, as well as string representations
3// and byte slices. Additionally, it covers marshaling and unmarshaling for JSON and other text formats.
4package uint256
5
6import (
7 "encoding/binary"
8 "errors"
9 "strconv"
10 "strings"
11)
12
13// Uint64 returns the lower 64-bits of z
14func (z *Uint) Uint64() uint64 {
15 return z.arr[0]
16}
17
18// Uint64WithOverflow returns the lower 64-bits of z and bool whether overflow occurred
19func (z *Uint) Uint64WithOverflow() (uint64, bool) {
20 return z.arr[0], (z.arr[1] | z.arr[2] | z.arr[3]) != 0
21}
22
23// SetUint64 sets z to the value x
24func (z *Uint) SetUint64(x uint64) *Uint {
25 z.arr[3], z.arr[2], z.arr[1], z.arr[0] = 0, 0, 0, x
26 return z
27}
28
29// IsUint64 reports whether z can be represented as a uint64.
30func (z *Uint) IsUint64() bool {
31 return (z.arr[1] | z.arr[2] | z.arr[3]) == 0
32}
33
34// Dec returns the decimal representation of z.
35func (z *Uint) Dec() string {
36 if z.IsZero() {
37 return "0"
38 }
39 if z.IsUint64() {
40 return strconv.FormatUint(z.Uint64(), 10)
41 }
42
43 // The max uint64 value being 18446744073709551615, the largest
44 // power-of-ten below that is 10000000000000000000.
45 // When we do a DivMod using that number, the remainder that we
46 // get back is the lower part of the output.
47 //
48 // The ascii-output of remainder will never exceed 19 bytes (since it will be
49 // below 10000000000000000000).
50 //
51 // Algorithm example using 100 as divisor
52 //
53 // 12345 % 100 = 45 (rem)
54 // 12345 / 100 = 123 (quo)
55 // -> output '45', continue iterate on 123
56 var (
57 // out is 98 bytes long: 78 (max size of a string without leading zeroes,
58 // plus slack so we can copy 19 bytes every iteration).
59 // We init it with zeroes, because when strconv appends the ascii representations,
60 // it will omit leading zeroes.
61 out = []byte("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
62 divisor = NewUint(10000000000000000000) // 20 digits
63 y = new(Uint).Set(z) // copy to avoid modifying z
64 pos = len(out) // position to write to
65 buf = make([]byte, 0, 19) // buffer to write uint64:s to
66 )
67 for {
68 // Obtain Q and R for divisor
69 var quot Uint
70 rem := udivrem(quot.arr[:], y.arr[:], divisor)
71 y.Set(") // Set Q for next loop
72 // Convert the R to ascii representation
73 buf = strconv.AppendUint(buf[:0], rem.Uint64(), 10)
74 // Copy in the ascii digits
75 copy(out[pos-len(buf):], buf)
76 if y.IsZero() {
77 break
78 }
79 // Move 19 digits left
80 pos -= 19
81 }
82 // skip leading zeroes by only using the 'used size' of buf
83 return string(out[pos-len(buf):])
84}
85
86func (z *Uint) Scan(src any) error {
87 if src == nil {
88 z.Clear()
89 return nil
90 }
91
92 switch src := src.(type) {
93 case string:
94 return z.scanScientificFromString(src)
95 case []byte:
96 return z.scanScientificFromString(string(src))
97 }
98 return errors.New("default // unsupported type: can't convert to uint256.Uint")
99}
100
101func (z *Uint) scanScientificFromString(src string) error {
102 if len(src) == 0 {
103 z.Clear()
104 return nil
105 }
106
107 idx := strings.IndexByte(src, 'e')
108 if idx == -1 {
109 return z.SetFromDecimal(src)
110 }
111 if err := z.SetFromDecimal(src[:idx]); err != nil {
112 return err
113 }
114 if src[(idx+1):] == "0" {
115 return nil
116 }
117 exp := new(Uint)
118 if err := exp.SetFromDecimal(src[(idx + 1):]); err != nil {
119 return err
120 }
121 if exp.GtUint64(77) { // 10**78 is larger than 2**256
122 return ErrBig256Range
123 }
124 exp.Exp(NewUint(10), exp)
125 if _, overflow := z.MulOverflow(z, exp); overflow {
126 return ErrBig256Range
127 }
128 return nil
129}
130
131// ToString returns the decimal string representation of z. It returns an empty string if z is nil.
132// OBS: doesn't exist from holiman's uint256
133func (z *Uint) String() string {
134 if z == nil {
135 return ""
136 }
137
138 return z.Dec()
139}
140
141// MarshalJSON implements json.Marshaler.
142// MarshalJSON marshals using the 'decimal string' representation. This is _not_ compatible
143// with big.Uint: big.Uint marshals into JSON 'native' numeric format.
144//
145// The JSON native format is, on some platforms, (e.g. javascript), limited to 53-bit large
146// integer space. Thus, U256 uses string-format, which is not compatible with
147// big.int (big.Uint refuses to unmarshal a string representation).
148func (z *Uint) MarshalJSON() ([]byte, error) {
149 return []byte(`"` + z.Dec() + `"`), nil
150}
151
152// UnmarshalJSON implements json.Unmarshaler. UnmarshalJSON accepts either
153// - Quoted string: either hexadecimal OR decimal
154// - Not quoted string: only decimal
155func (z *Uint) UnmarshalJSON(input []byte) error {
156 if len(input) < 2 || input[0] != '"' || input[len(input)-1] != '"' {
157 // if not quoted, it must be decimal
158 return z.fromDecimal(string(input))
159 }
160 return z.UnmarshalText(input[1 : len(input)-1])
161}
162
163// MarshalText implements encoding.TextMarshaler
164// MarshalText marshals using the decimal representation (compatible with big.Uint)
165func (z *Uint) MarshalText() ([]byte, error) {
166 return []byte(z.Dec()), nil
167}
168
169// UnmarshalText implements encoding.TextUnmarshaler. This method
170// can unmarshal either hexadecimal or decimal.
171// - For hexadecimal, the input _must_ be prefixed with 0x or 0X
172func (z *Uint) UnmarshalText(input []byte) error {
173 if len(input) >= 2 && input[0] == '0' && (input[1] == 'x' || input[1] == 'X') {
174 return z.fromHex(string(input))
175 }
176 return z.fromDecimal(string(input))
177}
178
179// SetBytes interprets buf as the bytes of a big-endian unsigned
180// integer, sets z to that value, and returns z.
181// If buf is larger than 32 bytes, the last 32 bytes is used.
182func (z *Uint) SetBytes(buf []byte) *Uint {
183 switch l := len(buf); l {
184 case 0:
185 z.Clear()
186 case 1:
187 z.SetBytes1(buf)
188 case 2:
189 z.SetBytes2(buf)
190 case 3:
191 z.SetBytes3(buf)
192 case 4:
193 z.SetBytes4(buf)
194 case 5:
195 z.SetBytes5(buf)
196 case 6:
197 z.SetBytes6(buf)
198 case 7:
199 z.SetBytes7(buf)
200 case 8:
201 z.SetBytes8(buf)
202 case 9:
203 z.SetBytes9(buf)
204 case 10:
205 z.SetBytes10(buf)
206 case 11:
207 z.SetBytes11(buf)
208 case 12:
209 z.SetBytes12(buf)
210 case 13:
211 z.SetBytes13(buf)
212 case 14:
213 z.SetBytes14(buf)
214 case 15:
215 z.SetBytes15(buf)
216 case 16:
217 z.SetBytes16(buf)
218 case 17:
219 z.SetBytes17(buf)
220 case 18:
221 z.SetBytes18(buf)
222 case 19:
223 z.SetBytes19(buf)
224 case 20:
225 z.SetBytes20(buf)
226 case 21:
227 z.SetBytes21(buf)
228 case 22:
229 z.SetBytes22(buf)
230 case 23:
231 z.SetBytes23(buf)
232 case 24:
233 z.SetBytes24(buf)
234 case 25:
235 z.SetBytes25(buf)
236 case 26:
237 z.SetBytes26(buf)
238 case 27:
239 z.SetBytes27(buf)
240 case 28:
241 z.SetBytes28(buf)
242 case 29:
243 z.SetBytes29(buf)
244 case 30:
245 z.SetBytes30(buf)
246 case 31:
247 z.SetBytes31(buf)
248 default:
249 z.SetBytes32(buf[l-32:])
250 }
251 return z
252}
253
254// SetBytes1 is identical to SetBytes(in[:1]), but panics is input is too short
255func (z *Uint) SetBytes1(in []byte) *Uint {
256 z.arr[3], z.arr[2], z.arr[1] = 0, 0, 0
257 z.arr[0] = uint64(in[0])
258 return z
259}
260
261// SetBytes2 is identical to SetBytes(in[:2]), but panics is input is too short
262func (z *Uint) SetBytes2(in []byte) *Uint {
263 _ = in[1] // bounds check hint to compiler; see golang.org/issue/14808
264 z.arr[3], z.arr[2], z.arr[1] = 0, 0, 0
265 z.arr[0] = uint64(binary.BigEndian.Uint16(in[0:2]))
266 return z
267}
268
269// SetBytes3 is identical to SetBytes(in[:3]), but panics is input is too short
270func (z *Uint) SetBytes3(in []byte) *Uint {
271 _ = in[2] // bounds check hint to compiler; see golang.org/issue/14808
272 z.arr[3], z.arr[2], z.arr[1] = 0, 0, 0
273 z.arr[0] = uint64(binary.BigEndian.Uint16(in[1:3])) | uint64(in[0])<<16
274 return z
275}
276
277// SetBytes4 is identical to SetBytes(in[:4]), but panics is input is too short
278func (z *Uint) SetBytes4(in []byte) *Uint {
279 _ = in[3] // bounds check hint to compiler; see golang.org/issue/14808
280 z.arr[3], z.arr[2], z.arr[1] = 0, 0, 0
281 z.arr[0] = uint64(binary.BigEndian.Uint32(in[0:4]))
282 return z
283}
284
285// SetBytes5 is identical to SetBytes(in[:5]), but panics is input is too short
286func (z *Uint) SetBytes5(in []byte) *Uint {
287 _ = in[4] // bounds check hint to compiler; see golang.org/issue/14808
288 z.arr[3], z.arr[2], z.arr[1] = 0, 0, 0
289 z.arr[0] = bigEndianUint40(in[0:5])
290 return z
291}
292
293// SetBytes6 is identical to SetBytes(in[:6]), but panics is input is too short
294func (z *Uint) SetBytes6(in []byte) *Uint {
295 _ = in[5] // bounds check hint to compiler; see golang.org/issue/14808
296 z.arr[3], z.arr[2], z.arr[1] = 0, 0, 0
297 z.arr[0] = bigEndianUint48(in[0:6])
298 return z
299}
300
301// SetBytes7 is identical to SetBytes(in[:7]), but panics is input is too short
302func (z *Uint) SetBytes7(in []byte) *Uint {
303 _ = in[6] // bounds check hint to compiler; see golang.org/issue/14808
304 z.arr[3], z.arr[2], z.arr[1] = 0, 0, 0
305 z.arr[0] = bigEndianUint56(in[0:7])
306 return z
307}
308
309// SetBytes8 is identical to SetBytes(in[:8]), but panics is input is too short
310func (z *Uint) SetBytes8(in []byte) *Uint {
311 _ = in[7] // bounds check hint to compiler; see golang.org/issue/14808
312 z.arr[3], z.arr[2], z.arr[1] = 0, 0, 0
313 z.arr[0] = binary.BigEndian.Uint64(in[0:8])
314 return z
315}
316
317// SetBytes9 is identical to SetBytes(in[:9]), but panics is input is too short
318func (z *Uint) SetBytes9(in []byte) *Uint {
319 _ = in[8] // bounds check hint to compiler; see golang.org/issue/14808
320 z.arr[3], z.arr[2] = 0, 0
321 z.arr[1] = uint64(in[0])
322 z.arr[0] = binary.BigEndian.Uint64(in[1:9])
323 return z
324}
325
326// SetBytes10 is identical to SetBytes(in[:10]), but panics is input is too short
327func (z *Uint) SetBytes10(in []byte) *Uint {
328 _ = in[9] // bounds check hint to compiler; see golang.org/issue/14808
329 z.arr[3], z.arr[2] = 0, 0
330 z.arr[1] = uint64(binary.BigEndian.Uint16(in[0:2]))
331 z.arr[0] = binary.BigEndian.Uint64(in[2:10])
332 return z
333}
334
335// SetBytes11 is identical to SetBytes(in[:11]), but panics is input is too short
336func (z *Uint) SetBytes11(in []byte) *Uint {
337 _ = in[10] // bounds check hint to compiler; see golang.org/issue/14808
338 z.arr[3], z.arr[2] = 0, 0
339 z.arr[1] = uint64(binary.BigEndian.Uint16(in[1:3])) | uint64(in[0])<<16
340 z.arr[0] = binary.BigEndian.Uint64(in[3:11])
341 return z
342}
343
344// SetBytes12 is identical to SetBytes(in[:12]), but panics is input is too short
345func (z *Uint) SetBytes12(in []byte) *Uint {
346 _ = in[11] // bounds check hint to compiler; see golang.org/issue/14808
347 z.arr[3], z.arr[2] = 0, 0
348 z.arr[1] = uint64(binary.BigEndian.Uint32(in[0:4]))
349 z.arr[0] = binary.BigEndian.Uint64(in[4:12])
350 return z
351}
352
353// SetBytes13 is identical to SetBytes(in[:13]), but panics is input is too short
354func (z *Uint) SetBytes13(in []byte) *Uint {
355 _ = in[12] // bounds check hint to compiler; see golang.org/issue/14808
356 z.arr[3], z.arr[2] = 0, 0
357 z.arr[1] = bigEndianUint40(in[0:5])
358 z.arr[0] = binary.BigEndian.Uint64(in[5:13])
359 return z
360}
361
362// SetBytes14 is identical to SetBytes(in[:14]), but panics is input is too short
363func (z *Uint) SetBytes14(in []byte) *Uint {
364 _ = in[13] // bounds check hint to compiler; see golang.org/issue/14808
365 z.arr[3], z.arr[2] = 0, 0
366 z.arr[1] = bigEndianUint48(in[0:6])
367 z.arr[0] = binary.BigEndian.Uint64(in[6:14])
368 return z
369}
370
371// SetBytes15 is identical to SetBytes(in[:15]), but panics is input is too short
372func (z *Uint) SetBytes15(in []byte) *Uint {
373 _ = in[14] // bounds check hint to compiler; see golang.org/issue/14808
374 z.arr[3], z.arr[2] = 0, 0
375 z.arr[1] = bigEndianUint56(in[0:7])
376 z.arr[0] = binary.BigEndian.Uint64(in[7:15])
377 return z
378}
379
380// SetBytes16 is identical to SetBytes(in[:16]), but panics is input is too short
381func (z *Uint) SetBytes16(in []byte) *Uint {
382 _ = in[15] // bounds check hint to compiler; see golang.org/issue/14808
383 z.arr[3], z.arr[2] = 0, 0
384 z.arr[1] = binary.BigEndian.Uint64(in[0:8])
385 z.arr[0] = binary.BigEndian.Uint64(in[8:16])
386 return z
387}
388
389// SetBytes17 is identical to SetBytes(in[:17]), but panics is input is too short
390func (z *Uint) SetBytes17(in []byte) *Uint {
391 _ = in[16] // bounds check hint to compiler; see golang.org/issue/14808
392 z.arr[3] = 0
393 z.arr[2] = uint64(in[0])
394 z.arr[1] = binary.BigEndian.Uint64(in[1:9])
395 z.arr[0] = binary.BigEndian.Uint64(in[9:17])
396 return z
397}
398
399// SetBytes18 is identical to SetBytes(in[:18]), but panics is input is too short
400func (z *Uint) SetBytes18(in []byte) *Uint {
401 _ = in[17] // bounds check hint to compiler; see golang.org/issue/14808
402 z.arr[3] = 0
403 z.arr[2] = uint64(binary.BigEndian.Uint16(in[0:2]))
404 z.arr[1] = binary.BigEndian.Uint64(in[2:10])
405 z.arr[0] = binary.BigEndian.Uint64(in[10:18])
406 return z
407}
408
409// SetBytes19 is identical to SetBytes(in[:19]), but panics is input is too short
410func (z *Uint) SetBytes19(in []byte) *Uint {
411 _ = in[18] // bounds check hint to compiler; see golang.org/issue/14808
412 z.arr[3] = 0
413 z.arr[2] = uint64(binary.BigEndian.Uint16(in[1:3])) | uint64(in[0])<<16
414 z.arr[1] = binary.BigEndian.Uint64(in[3:11])
415 z.arr[0] = binary.BigEndian.Uint64(in[11:19])
416 return z
417}
418
419// SetBytes20 is identical to SetBytes(in[:20]), but panics is input is too short
420func (z *Uint) SetBytes20(in []byte) *Uint {
421 _ = in[19] // bounds check hint to compiler; see golang.org/issue/14808
422 z.arr[3] = 0
423 z.arr[2] = uint64(binary.BigEndian.Uint32(in[0:4]))
424 z.arr[1] = binary.BigEndian.Uint64(in[4:12])
425 z.arr[0] = binary.BigEndian.Uint64(in[12:20])
426 return z
427}
428
429// SetBytes21 is identical to SetBytes(in[:21]), but panics is input is too short
430func (z *Uint) SetBytes21(in []byte) *Uint {
431 _ = in[20] // bounds check hint to compiler; see golang.org/issue/14808
432 z.arr[3] = 0
433 z.arr[2] = bigEndianUint40(in[0:5])
434 z.arr[1] = binary.BigEndian.Uint64(in[5:13])
435 z.arr[0] = binary.BigEndian.Uint64(in[13:21])
436 return z
437}
438
439// SetBytes22 is identical to SetBytes(in[:22]), but panics is input is too short
440func (z *Uint) SetBytes22(in []byte) *Uint {
441 _ = in[21] // bounds check hint to compiler; see golang.org/issue/14808
442 z.arr[3] = 0
443 z.arr[2] = bigEndianUint48(in[0:6])
444 z.arr[1] = binary.BigEndian.Uint64(in[6:14])
445 z.arr[0] = binary.BigEndian.Uint64(in[14:22])
446 return z
447}
448
449// SetBytes23 is identical to SetBytes(in[:23]), but panics is input is too short
450func (z *Uint) SetBytes23(in []byte) *Uint {
451 _ = in[22] // bounds check hint to compiler; see golang.org/issue/14808
452 z.arr[3] = 0
453 z.arr[2] = bigEndianUint56(in[0:7])
454 z.arr[1] = binary.BigEndian.Uint64(in[7:15])
455 z.arr[0] = binary.BigEndian.Uint64(in[15:23])
456 return z
457}
458
459// SetBytes24 is identical to SetBytes(in[:24]), but panics is input is too short
460func (z *Uint) SetBytes24(in []byte) *Uint {
461 _ = in[23] // bounds check hint to compiler; see golang.org/issue/14808
462 z.arr[3] = 0
463 z.arr[2] = binary.BigEndian.Uint64(in[0:8])
464 z.arr[1] = binary.BigEndian.Uint64(in[8:16])
465 z.arr[0] = binary.BigEndian.Uint64(in[16:24])
466 return z
467}
468
469// SetBytes25 is identical to SetBytes(in[:25]), but panics is input is too short
470func (z *Uint) SetBytes25(in []byte) *Uint {
471 _ = in[24] // bounds check hint to compiler; see golang.org/issue/14808
472 z.arr[3] = uint64(in[0])
473 z.arr[2] = binary.BigEndian.Uint64(in[1:9])
474 z.arr[1] = binary.BigEndian.Uint64(in[9:17])
475 z.arr[0] = binary.BigEndian.Uint64(in[17:25])
476 return z
477}
478
479// SetBytes26 is identical to SetBytes(in[:26]), but panics is input is too short
480func (z *Uint) SetBytes26(in []byte) *Uint {
481 _ = in[25] // bounds check hint to compiler; see golang.org/issue/14808
482 z.arr[3] = uint64(binary.BigEndian.Uint16(in[0:2]))
483 z.arr[2] = binary.BigEndian.Uint64(in[2:10])
484 z.arr[1] = binary.BigEndian.Uint64(in[10:18])
485 z.arr[0] = binary.BigEndian.Uint64(in[18:26])
486 return z
487}
488
489// SetBytes27 is identical to SetBytes(in[:27]), but panics is input is too short
490func (z *Uint) SetBytes27(in []byte) *Uint {
491 _ = in[26] // bounds check hint to compiler; see golang.org/issue/14808
492 z.arr[3] = uint64(binary.BigEndian.Uint16(in[1:3])) | uint64(in[0])<<16
493 z.arr[2] = binary.BigEndian.Uint64(in[3:11])
494 z.arr[1] = binary.BigEndian.Uint64(in[11:19])
495 z.arr[0] = binary.BigEndian.Uint64(in[19:27])
496 return z
497}
498
499// SetBytes28 is identical to SetBytes(in[:28]), but panics is input is too short
500func (z *Uint) SetBytes28(in []byte) *Uint {
501 _ = in[27] // bounds check hint to compiler; see golang.org/issue/14808
502 z.arr[3] = uint64(binary.BigEndian.Uint32(in[0:4]))
503 z.arr[2] = binary.BigEndian.Uint64(in[4:12])
504 z.arr[1] = binary.BigEndian.Uint64(in[12:20])
505 z.arr[0] = binary.BigEndian.Uint64(in[20:28])
506 return z
507}
508
509// SetBytes29 is identical to SetBytes(in[:29]), but panics is input is too short
510func (z *Uint) SetBytes29(in []byte) *Uint {
511 _ = in[23] // bounds check hint to compiler; see golang.org/issue/14808
512 z.arr[3] = bigEndianUint40(in[0:5])
513 z.arr[2] = binary.BigEndian.Uint64(in[5:13])
514 z.arr[1] = binary.BigEndian.Uint64(in[13:21])
515 z.arr[0] = binary.BigEndian.Uint64(in[21:29])
516 return z
517}
518
519// SetBytes30 is identical to SetBytes(in[:30]), but panics is input is too short
520func (z *Uint) SetBytes30(in []byte) *Uint {
521 _ = in[29] // bounds check hint to compiler; see golang.org/issue/14808
522 z.arr[3] = bigEndianUint48(in[0:6])
523 z.arr[2] = binary.BigEndian.Uint64(in[6:14])
524 z.arr[1] = binary.BigEndian.Uint64(in[14:22])
525 z.arr[0] = binary.BigEndian.Uint64(in[22:30])
526 return z
527}
528
529// SetBytes31 is identical to SetBytes(in[:31]), but panics is input is too short
530func (z *Uint) SetBytes31(in []byte) *Uint {
531 _ = in[30] // bounds check hint to compiler; see golang.org/issue/14808
532 z.arr[3] = bigEndianUint56(in[0:7])
533 z.arr[2] = binary.BigEndian.Uint64(in[7:15])
534 z.arr[1] = binary.BigEndian.Uint64(in[15:23])
535 z.arr[0] = binary.BigEndian.Uint64(in[23:31])
536 return z
537}
538
539// SetBytes32 sets z to the value of the big-endian 256-bit unsigned integer in.
540func (z *Uint) SetBytes32(in []byte) *Uint {
541 _ = in[31] // bounds check hint to compiler; see golang.org/issue/14808
542 z.arr[3] = binary.BigEndian.Uint64(in[0:8])
543 z.arr[2] = binary.BigEndian.Uint64(in[8:16])
544 z.arr[1] = binary.BigEndian.Uint64(in[16:24])
545 z.arr[0] = binary.BigEndian.Uint64(in[24:32])
546 return z
547}
548
549// Utility methods that are "missing" among the bigEndian.UintXX methods.
550
551// bigEndianUint40 returns the uint64 value represented by the 5 bytes in big-endian order.
552func bigEndianUint40(b []byte) uint64 {
553 _ = b[4] // bounds check hint to compiler; see golang.org/issue/14808
554 return uint64(b[4]) | uint64(b[3])<<8 | uint64(b[2])<<16 | uint64(b[1])<<24 |
555 uint64(b[0])<<32
556}
557
558// bigEndianUint56 returns the uint64 value represented by the 7 bytes in big-endian order.
559func bigEndianUint56(b []byte) uint64 {
560 _ = b[6] // bounds check hint to compiler; see golang.org/issue/14808
561 return uint64(b[6]) | uint64(b[5])<<8 | uint64(b[4])<<16 | uint64(b[3])<<24 |
562 uint64(b[2])<<32 | uint64(b[1])<<40 | uint64(b[0])<<48
563}
564
565// bigEndianUint48 returns the uint64 value represented by the 6 bytes in big-endian order.
566func bigEndianUint48(b []byte) uint64 {
567 _ = b[5] // bounds check hint to compiler; see golang.org/issue/14808
568 return uint64(b[5]) | uint64(b[4])<<8 | uint64(b[3])<<16 | uint64(b[2])<<24 |
569 uint64(b[1])<<32 | uint64(b[0])<<40
570}