podman

Форк
0
614 строк · 18.9 Кб
1
// Copyright 2016 The Oklog Authors
2
// Licensed under the Apache License, Version 2.0 (the "License");
3
// you may not use this file except in compliance with the License.
4
// You may obtain a copy of the License at
5
//
6
// http://www.apache.org/licenses/LICENSE-2.0
7
//
8
// Unless required by applicable law or agreed to in writing, software
9
// distributed under the License is distributed on an "AS IS" BASIS,
10
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
// See the License for the specific language governing permissions and
12
// limitations under the License.
13

14
package ulid
15

16
import (
17
	"bufio"
18
	"bytes"
19
	"database/sql/driver"
20
	"encoding/binary"
21
	"errors"
22
	"io"
23
	"math"
24
	"math/bits"
25
	"math/rand"
26
	"time"
27
)
28

29
/*
30
An ULID is a 16 byte Universally Unique Lexicographically Sortable Identifier
31

32
	The components are encoded as 16 octets.
33
	Each component is encoded with the MSB first (network byte order).
34

35
	0                   1                   2                   3
36
	0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
37
	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
38
	|                      32_bit_uint_time_high                    |
39
	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
40
	|     16_bit_uint_time_low      |       16_bit_uint_random      |
41
	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
42
	|                       32_bit_uint_random                      |
43
	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
44
	|                       32_bit_uint_random                      |
45
	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
46
*/
47
type ULID [16]byte
48

49
var (
50
	// ErrDataSize is returned when parsing or unmarshaling ULIDs with the wrong
51
	// data size.
52
	ErrDataSize = errors.New("ulid: bad data size when unmarshaling")
53

54
	// ErrInvalidCharacters is returned when parsing or unmarshaling ULIDs with
55
	// invalid Base32 encodings.
56
	ErrInvalidCharacters = errors.New("ulid: bad data characters when unmarshaling")
57

58
	// ErrBufferSize is returned when marshalling ULIDs to a buffer of insufficient
59
	// size.
60
	ErrBufferSize = errors.New("ulid: bad buffer size when marshaling")
61

62
	// ErrBigTime is returned when constructing an ULID with a time that is larger
63
	// than MaxTime.
64
	ErrBigTime = errors.New("ulid: time too big")
65

66
	// ErrOverflow is returned when unmarshaling a ULID whose first character is
67
	// larger than 7, thereby exceeding the valid bit depth of 128.
68
	ErrOverflow = errors.New("ulid: overflow when unmarshaling")
69

70
	// ErrMonotonicOverflow is returned by a Monotonic entropy source when
71
	// incrementing the previous ULID's entropy bytes would result in overflow.
72
	ErrMonotonicOverflow = errors.New("ulid: monotonic entropy overflow")
73

74
	// ErrScanValue is returned when the value passed to scan cannot be unmarshaled
75
	// into the ULID.
76
	ErrScanValue = errors.New("ulid: source value must be a string or byte slice")
77
)
78

79
// New returns an ULID with the given Unix milliseconds timestamp and an
80
// optional entropy source. Use the Timestamp function to convert
81
// a time.Time to Unix milliseconds.
82
//
83
// ErrBigTime is returned when passing a timestamp bigger than MaxTime.
84
// Reading from the entropy source may also return an error.
85
func New(ms uint64, entropy io.Reader) (id ULID, err error) {
86
	if err = id.SetTime(ms); err != nil {
87
		return id, err
88
	}
89

90
	switch e := entropy.(type) {
91
	case nil:
92
		return id, err
93
	case *monotonic:
94
		err = e.MonotonicRead(ms, id[6:])
95
	default:
96
		_, err = io.ReadFull(e, id[6:])
97
	}
98

99
	return id, err
100
}
101

102
// MustNew is a convenience function equivalent to New that panics on failure
103
// instead of returning an error.
104
func MustNew(ms uint64, entropy io.Reader) ULID {
105
	id, err := New(ms, entropy)
106
	if err != nil {
107
		panic(err)
108
	}
109
	return id
110
}
111

112
// Parse parses an encoded ULID, returning an error in case of failure.
113
//
114
// ErrDataSize is returned if the len(ulid) is different from an encoded
115
// ULID's length. Invalid encodings produce undefined ULIDs. For a version that
116
// returns an error instead, see ParseStrict.
117
func Parse(ulid string) (id ULID, err error) {
118
	return id, parse([]byte(ulid), false, &id)
119
}
120

121
// ParseStrict parses an encoded ULID, returning an error in case of failure.
122
//
123
// It is like Parse, but additionally validates that the parsed ULID consists
124
// only of valid base32 characters. It is slightly slower than Parse.
125
//
126
// ErrDataSize is returned if the len(ulid) is different from an encoded
127
// ULID's length. Invalid encodings return ErrInvalidCharacters.
128
func ParseStrict(ulid string) (id ULID, err error) {
129
	return id, parse([]byte(ulid), true, &id)
130
}
131

132
func parse(v []byte, strict bool, id *ULID) error {
133
	// Check if a base32 encoded ULID is the right length.
134
	if len(v) != EncodedSize {
135
		return ErrDataSize
136
	}
137

138
	// Check if all the characters in a base32 encoded ULID are part of the
139
	// expected base32 character set.
140
	if strict &&
141
		(dec[v[0]] == 0xFF ||
142
			dec[v[1]] == 0xFF ||
143
			dec[v[2]] == 0xFF ||
144
			dec[v[3]] == 0xFF ||
145
			dec[v[4]] == 0xFF ||
146
			dec[v[5]] == 0xFF ||
147
			dec[v[6]] == 0xFF ||
148
			dec[v[7]] == 0xFF ||
149
			dec[v[8]] == 0xFF ||
150
			dec[v[9]] == 0xFF ||
151
			dec[v[10]] == 0xFF ||
152
			dec[v[11]] == 0xFF ||
153
			dec[v[12]] == 0xFF ||
154
			dec[v[13]] == 0xFF ||
155
			dec[v[14]] == 0xFF ||
156
			dec[v[15]] == 0xFF ||
157
			dec[v[16]] == 0xFF ||
158
			dec[v[17]] == 0xFF ||
159
			dec[v[18]] == 0xFF ||
160
			dec[v[19]] == 0xFF ||
161
			dec[v[20]] == 0xFF ||
162
			dec[v[21]] == 0xFF ||
163
			dec[v[22]] == 0xFF ||
164
			dec[v[23]] == 0xFF ||
165
			dec[v[24]] == 0xFF ||
166
			dec[v[25]] == 0xFF) {
167
		return ErrInvalidCharacters
168
	}
169

170
	// Check if the first character in a base32 encoded ULID will overflow. This
171
	// happens because the base32 representation encodes 130 bits, while the
172
	// ULID is only 128 bits.
173
	//
174
	// See https://github.com/oklog/ulid/issues/9 for details.
175
	if v[0] > '7' {
176
		return ErrOverflow
177
	}
178

179
	// Use an optimized unrolled loop (from https://github.com/RobThree/NUlid)
180
	// to decode a base32 ULID.
181

182
	// 6 bytes timestamp (48 bits)
183
	(*id)[0] = ((dec[v[0]] << 5) | dec[v[1]])
184
	(*id)[1] = ((dec[v[2]] << 3) | (dec[v[3]] >> 2))
185
	(*id)[2] = ((dec[v[3]] << 6) | (dec[v[4]] << 1) | (dec[v[5]] >> 4))
186
	(*id)[3] = ((dec[v[5]] << 4) | (dec[v[6]] >> 1))
187
	(*id)[4] = ((dec[v[6]] << 7) | (dec[v[7]] << 2) | (dec[v[8]] >> 3))
188
	(*id)[5] = ((dec[v[8]] << 5) | dec[v[9]])
189

190
	// 10 bytes of entropy (80 bits)
191
	(*id)[6] = ((dec[v[10]] << 3) | (dec[v[11]] >> 2))
192
	(*id)[7] = ((dec[v[11]] << 6) | (dec[v[12]] << 1) | (dec[v[13]] >> 4))
193
	(*id)[8] = ((dec[v[13]] << 4) | (dec[v[14]] >> 1))
194
	(*id)[9] = ((dec[v[14]] << 7) | (dec[v[15]] << 2) | (dec[v[16]] >> 3))
195
	(*id)[10] = ((dec[v[16]] << 5) | dec[v[17]])
196
	(*id)[11] = ((dec[v[18]] << 3) | dec[v[19]]>>2)
197
	(*id)[12] = ((dec[v[19]] << 6) | (dec[v[20]] << 1) | (dec[v[21]] >> 4))
198
	(*id)[13] = ((dec[v[21]] << 4) | (dec[v[22]] >> 1))
199
	(*id)[14] = ((dec[v[22]] << 7) | (dec[v[23]] << 2) | (dec[v[24]] >> 3))
200
	(*id)[15] = ((dec[v[24]] << 5) | dec[v[25]])
201

202
	return nil
203
}
204

205
// MustParse is a convenience function equivalent to Parse that panics on failure
206
// instead of returning an error.
207
func MustParse(ulid string) ULID {
208
	id, err := Parse(ulid)
209
	if err != nil {
210
		panic(err)
211
	}
212
	return id
213
}
214

215
// MustParseStrict is a convenience function equivalent to ParseStrict that
216
// panics on failure instead of returning an error.
217
func MustParseStrict(ulid string) ULID {
218
	id, err := ParseStrict(ulid)
219
	if err != nil {
220
		panic(err)
221
	}
222
	return id
223
}
224

225
// String returns a lexicographically sortable string encoded ULID
226
// (26 characters, non-standard base 32) e.g. 01AN4Z07BY79KA1307SR9X4MV3
227
// Format: tttttttttteeeeeeeeeeeeeeee where t is time and e is entropy
228
func (id ULID) String() string {
229
	ulid := make([]byte, EncodedSize)
230
	_ = id.MarshalTextTo(ulid)
231
	return string(ulid)
232
}
233

234
// MarshalBinary implements the encoding.BinaryMarshaler interface by
235
// returning the ULID as a byte slice.
236
func (id ULID) MarshalBinary() ([]byte, error) {
237
	ulid := make([]byte, len(id))
238
	return ulid, id.MarshalBinaryTo(ulid)
239
}
240

241
// MarshalBinaryTo writes the binary encoding of the ULID to the given buffer.
242
// ErrBufferSize is returned when the len(dst) != 16.
243
func (id ULID) MarshalBinaryTo(dst []byte) error {
244
	if len(dst) != len(id) {
245
		return ErrBufferSize
246
	}
247

248
	copy(dst, id[:])
249
	return nil
250
}
251

252
// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface by
253
// copying the passed data and converting it to an ULID. ErrDataSize is
254
// returned if the data length is different from ULID length.
255
func (id *ULID) UnmarshalBinary(data []byte) error {
256
	if len(data) != len(*id) {
257
		return ErrDataSize
258
	}
259

260
	copy((*id)[:], data)
261
	return nil
262
}
263

264
// Encoding is the base 32 encoding alphabet used in ULID strings.
265
const Encoding = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"
266

267
// MarshalText implements the encoding.TextMarshaler interface by
268
// returning the string encoded ULID.
269
func (id ULID) MarshalText() ([]byte, error) {
270
	ulid := make([]byte, EncodedSize)
271
	return ulid, id.MarshalTextTo(ulid)
272
}
273

274
// MarshalTextTo writes the ULID as a string to the given buffer.
275
// ErrBufferSize is returned when the len(dst) != 26.
276
func (id ULID) MarshalTextTo(dst []byte) error {
277
	// Optimized unrolled loop ahead.
278
	// From https://github.com/RobThree/NUlid
279

280
	if len(dst) != EncodedSize {
281
		return ErrBufferSize
282
	}
283

284
	// 10 byte timestamp
285
	dst[0] = Encoding[(id[0]&224)>>5]
286
	dst[1] = Encoding[id[0]&31]
287
	dst[2] = Encoding[(id[1]&248)>>3]
288
	dst[3] = Encoding[((id[1]&7)<<2)|((id[2]&192)>>6)]
289
	dst[4] = Encoding[(id[2]&62)>>1]
290
	dst[5] = Encoding[((id[2]&1)<<4)|((id[3]&240)>>4)]
291
	dst[6] = Encoding[((id[3]&15)<<1)|((id[4]&128)>>7)]
292
	dst[7] = Encoding[(id[4]&124)>>2]
293
	dst[8] = Encoding[((id[4]&3)<<3)|((id[5]&224)>>5)]
294
	dst[9] = Encoding[id[5]&31]
295

296
	// 16 bytes of entropy
297
	dst[10] = Encoding[(id[6]&248)>>3]
298
	dst[11] = Encoding[((id[6]&7)<<2)|((id[7]&192)>>6)]
299
	dst[12] = Encoding[(id[7]&62)>>1]
300
	dst[13] = Encoding[((id[7]&1)<<4)|((id[8]&240)>>4)]
301
	dst[14] = Encoding[((id[8]&15)<<1)|((id[9]&128)>>7)]
302
	dst[15] = Encoding[(id[9]&124)>>2]
303
	dst[16] = Encoding[((id[9]&3)<<3)|((id[10]&224)>>5)]
304
	dst[17] = Encoding[id[10]&31]
305
	dst[18] = Encoding[(id[11]&248)>>3]
306
	dst[19] = Encoding[((id[11]&7)<<2)|((id[12]&192)>>6)]
307
	dst[20] = Encoding[(id[12]&62)>>1]
308
	dst[21] = Encoding[((id[12]&1)<<4)|((id[13]&240)>>4)]
309
	dst[22] = Encoding[((id[13]&15)<<1)|((id[14]&128)>>7)]
310
	dst[23] = Encoding[(id[14]&124)>>2]
311
	dst[24] = Encoding[((id[14]&3)<<3)|((id[15]&224)>>5)]
312
	dst[25] = Encoding[id[15]&31]
313

314
	return nil
315
}
316

317
// Byte to index table for O(1) lookups when unmarshaling.
318
// We use 0xFF as sentinel value for invalid indexes.
319
var dec = [...]byte{
320
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
321
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
322
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
323
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
324
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01,
325
	0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xFF, 0xFF,
326
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
327
	0x0F, 0x10, 0x11, 0xFF, 0x12, 0x13, 0xFF, 0x14, 0x15, 0xFF,
328
	0x16, 0x17, 0x18, 0x19, 0x1A, 0xFF, 0x1B, 0x1C, 0x1D, 0x1E,
329
	0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x0B, 0x0C,
330
	0x0D, 0x0E, 0x0F, 0x10, 0x11, 0xFF, 0x12, 0x13, 0xFF, 0x14,
331
	0x15, 0xFF, 0x16, 0x17, 0x18, 0x19, 0x1A, 0xFF, 0x1B, 0x1C,
332
	0x1D, 0x1E, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
333
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
334
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
335
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
336
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
337
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
338
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
339
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
340
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
341
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
342
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
343
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
344
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
345
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
346
}
347

348
// EncodedSize is the length of a text encoded ULID.
349
const EncodedSize = 26
350

351
// UnmarshalText implements the encoding.TextUnmarshaler interface by
352
// parsing the data as string encoded ULID.
353
//
354
// ErrDataSize is returned if the len(v) is different from an encoded
355
// ULID's length. Invalid encodings produce undefined ULIDs.
356
func (id *ULID) UnmarshalText(v []byte) error {
357
	return parse(v, false, id)
358
}
359

360
// Time returns the Unix time in milliseconds encoded in the ULID.
361
// Use the top level Time function to convert the returned value to
362
// a time.Time.
363
func (id ULID) Time() uint64 {
364
	return uint64(id[5]) | uint64(id[4])<<8 |
365
		uint64(id[3])<<16 | uint64(id[2])<<24 |
366
		uint64(id[1])<<32 | uint64(id[0])<<40
367
}
368

369
// maxTime is the maximum Unix time in milliseconds that can be
370
// represented in an ULID.
371
var maxTime = ULID{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}.Time()
372

373
// MaxTime returns the maximum Unix time in milliseconds that
374
// can be encoded in an ULID.
375
func MaxTime() uint64 { return maxTime }
376

377
// Now is a convenience function that returns the current
378
// UTC time in Unix milliseconds. Equivalent to:
379
//   Timestamp(time.Now().UTC())
380
func Now() uint64 { return Timestamp(time.Now().UTC()) }
381

382
// Timestamp converts a time.Time to Unix milliseconds.
383
//
384
// Because of the way ULID stores time, times from the year
385
// 10889 produces undefined results.
386
func Timestamp(t time.Time) uint64 {
387
	return uint64(t.Unix())*1000 +
388
		uint64(t.Nanosecond()/int(time.Millisecond))
389
}
390

391
// Time converts Unix milliseconds in the format
392
// returned by the Timestamp function to a time.Time.
393
func Time(ms uint64) time.Time {
394
	s := int64(ms / 1e3)
395
	ns := int64((ms % 1e3) * 1e6)
396
	return time.Unix(s, ns)
397
}
398

399
// SetTime sets the time component of the ULID to the given Unix time
400
// in milliseconds.
401
func (id *ULID) SetTime(ms uint64) error {
402
	if ms > maxTime {
403
		return ErrBigTime
404
	}
405

406
	(*id)[0] = byte(ms >> 40)
407
	(*id)[1] = byte(ms >> 32)
408
	(*id)[2] = byte(ms >> 24)
409
	(*id)[3] = byte(ms >> 16)
410
	(*id)[4] = byte(ms >> 8)
411
	(*id)[5] = byte(ms)
412

413
	return nil
414
}
415

416
// Entropy returns the entropy from the ULID.
417
func (id ULID) Entropy() []byte {
418
	e := make([]byte, 10)
419
	copy(e, id[6:])
420
	return e
421
}
422

423
// SetEntropy sets the ULID entropy to the passed byte slice.
424
// ErrDataSize is returned if len(e) != 10.
425
func (id *ULID) SetEntropy(e []byte) error {
426
	if len(e) != 10 {
427
		return ErrDataSize
428
	}
429

430
	copy((*id)[6:], e)
431
	return nil
432
}
433

434
// Compare returns an integer comparing id and other lexicographically.
435
// The result will be 0 if id==other, -1 if id < other, and +1 if id > other.
436
func (id ULID) Compare(other ULID) int {
437
	return bytes.Compare(id[:], other[:])
438
}
439

440
// Scan implements the sql.Scanner interface. It supports scanning
441
// a string or byte slice.
442
func (id *ULID) Scan(src interface{}) error {
443
	switch x := src.(type) {
444
	case nil:
445
		return nil
446
	case string:
447
		return id.UnmarshalText([]byte(x))
448
	case []byte:
449
		return id.UnmarshalBinary(x)
450
	}
451

452
	return ErrScanValue
453
}
454

455
// Value implements the sql/driver.Valuer interface. This returns the value
456
// represented as a byte slice. If instead a string is desirable, a wrapper
457
// type can be created that calls String().
458
//
459
//	// stringValuer wraps a ULID as a string-based driver.Valuer.
460
// 	type stringValuer ULID
461
//
462
//	func (id stringValuer) Value() (driver.Value, error) {
463
//		return ULID(id).String(), nil
464
//	}
465
//
466
//	// Example usage.
467
//	db.Exec("...", stringValuer(id))
468
func (id ULID) Value() (driver.Value, error) {
469
	return id.MarshalBinary()
470
}
471

472
// Monotonic returns an entropy source that is guaranteed to yield
473
// strictly increasing entropy bytes for the same ULID timestamp.
474
// On conflicts, the previous ULID entropy is incremented with a
475
// random number between 1 and `inc` (inclusive).
476
//
477
// The provided entropy source must actually yield random bytes or else
478
// monotonic reads are not guaranteed to terminate, since there isn't
479
// enough randomness to compute an increment number.
480
//
481
// When `inc == 0`, it'll be set to a secure default of `math.MaxUint32`.
482
// The lower the value of `inc`, the easier the next ULID within the
483
// same millisecond is to guess. If your code depends on ULIDs having
484
// secure entropy bytes, then don't go under this default unless you know
485
// what you're doing.
486
//
487
// The returned io.Reader isn't safe for concurrent use.
488
func Monotonic(entropy io.Reader, inc uint64) io.Reader {
489
	m := monotonic{
490
		Reader: bufio.NewReader(entropy),
491
		inc:    inc,
492
	}
493

494
	if m.inc == 0 {
495
		m.inc = math.MaxUint32
496
	}
497

498
	if rng, ok := entropy.(*rand.Rand); ok {
499
		m.rng = rng
500
	}
501

502
	return &m
503
}
504

505
type monotonic struct {
506
	io.Reader
507
	ms      uint64
508
	inc     uint64
509
	entropy uint80
510
	rand    [8]byte
511
	rng     *rand.Rand
512
}
513

514
func (m *monotonic) MonotonicRead(ms uint64, entropy []byte) (err error) {
515
	if !m.entropy.IsZero() && m.ms == ms {
516
		err = m.increment()
517
		m.entropy.AppendTo(entropy)
518
	} else if _, err = io.ReadFull(m.Reader, entropy); err == nil {
519
		m.ms = ms
520
		m.entropy.SetBytes(entropy)
521
	}
522
	return err
523
}
524

525
// increment the previous entropy number with a random number
526
// of up to m.inc (inclusive).
527
func (m *monotonic) increment() error {
528
	if inc, err := m.random(); err != nil {
529
		return err
530
	} else if m.entropy.Add(inc) {
531
		return ErrMonotonicOverflow
532
	}
533
	return nil
534
}
535

536
// random returns a uniform random value in [1, m.inc), reading entropy
537
// from m.Reader. When m.inc == 0 || m.inc == 1, it returns 1.
538
// Adapted from: https://golang.org/pkg/crypto/rand/#Int
539
func (m *monotonic) random() (inc uint64, err error) {
540
	if m.inc <= 1 {
541
		return 1, nil
542
	}
543

544
	// Fast path for using a underlying rand.Rand directly.
545
	if m.rng != nil {
546
		// Range: [1, m.inc)
547
		return 1 + uint64(m.rng.Int63n(int64(m.inc))), nil
548
	}
549

550
	// bitLen is the maximum bit length needed to encode a value < m.inc.
551
	bitLen := bits.Len64(m.inc)
552

553
	// byteLen is the maximum byte length needed to encode a value < m.inc.
554
	byteLen := uint(bitLen+7) / 8
555

556
	// msbitLen is the number of bits in the most significant byte of m.inc-1.
557
	msbitLen := uint(bitLen % 8)
558
	if msbitLen == 0 {
559
		msbitLen = 8
560
	}
561

562
	for inc == 0 || inc >= m.inc {
563
		if _, err = io.ReadFull(m.Reader, m.rand[:byteLen]); err != nil {
564
			return 0, err
565
		}
566

567
		// Clear bits in the first byte to increase the probability
568
		// that the candidate is < m.inc.
569
		m.rand[0] &= uint8(int(1<<msbitLen) - 1)
570

571
		// Convert the read bytes into an uint64 with byteLen
572
		// Optimized unrolled loop.
573
		switch byteLen {
574
		case 1:
575
			inc = uint64(m.rand[0])
576
		case 2:
577
			inc = uint64(binary.LittleEndian.Uint16(m.rand[:2]))
578
		case 3, 4:
579
			inc = uint64(binary.LittleEndian.Uint32(m.rand[:4]))
580
		case 5, 6, 7, 8:
581
			inc = uint64(binary.LittleEndian.Uint64(m.rand[:8]))
582
		}
583
	}
584

585
	// Range: [1, m.inc)
586
	return 1 + inc, nil
587
}
588

589
type uint80 struct {
590
	Hi uint16
591
	Lo uint64
592
}
593

594
func (u *uint80) SetBytes(bs []byte) {
595
	u.Hi = binary.BigEndian.Uint16(bs[:2])
596
	u.Lo = binary.BigEndian.Uint64(bs[2:])
597
}
598

599
func (u *uint80) AppendTo(bs []byte) {
600
	binary.BigEndian.PutUint16(bs[:2], u.Hi)
601
	binary.BigEndian.PutUint64(bs[2:], u.Lo)
602
}
603

604
func (u *uint80) Add(n uint64) (overflow bool) {
605
	lo, hi := u.Lo, u.Hi
606
	if u.Lo += n; u.Lo < lo {
607
		u.Hi++
608
	}
609
	return u.Hi < hi
610
}
611

612
func (u uint80) IsZero() bool {
613
	return u.Hi == 0 && u.Lo == 0
614
}
615

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.