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(&quot) // 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}