示例#1
0
        /// <summary>
        /// Creates and returns random bytes based on internal <see cref="IUlidRng"/>.
        /// </summary>
        /// <param name="dateTime">
        /// DateTime for which the random bytes need to be generated; this value is used to determine wether a sequence
        /// needs to be incremented (same timestamp with millisecond resolution) or reset to a new random value.
        /// </param>
        /// <returns>Random bytes.</returns>
        /// <exception cref="InvalidOperationException">
        /// Thrown when the specified <paramref name="dateTime"/> is before the last time this method was called.
        /// </exception>
        public override byte[] GetRandomBytes(DateTimeOffset dateTime)
        {
            lock (_genlock)
            {
                // Get unix time for given datetime
                var timestamp = Ulid.ToUnixTimeMilliseconds(dateTime);

                if (timestamp <= _lastgen)  // Same or earlier timestamp as last time we generated random values?
                {
                    // Increment our random value by one.
                    var i = RANDLEN;
                    while (--i >= 0 && ++_lastvalue[i] == 0)
                    {
                        ;
                    }
                    // If i made it all the way to -1 we have an overflow and we throw
                    if (i < 0)
                    {
                        throw new OverflowException();
                    }
                }
                else // New(er) timestamp, so generate a new random value and store the new(er) timestamp
                {
                    _lastvalue    = _rng.GetRandomBytes(dateTime);              // Use internal RNG to get bytes from
                    _lastvalue[0] = (byte)(_lastvalue[0] & 0x7F); // Mask out bit 0 of the random part

                    _lastgen = timestamp;                         // Store last timestamp
                }
                return(_lastvalue);
            }
        }
示例#2
0
 /// <summary>
 /// Creates and returns a new <see cref="Ulid"/> based on the specified time and using the specified RNG.
 /// </summary>
 /// <param name="time">
 /// The <see cref="DateTimeOffset"/> to use for the time-part of the <see cref="Ulid"/>.
 /// </param>
 /// <param name="rng">The <see cref="IUlidRng"/> to use for random number generation.</param>
 /// <returns>Returns a new <see cref="Ulid"/>.</returns>
 /// <exception cref="ArgumentNullException">Thrown when <paramref name="rng"/> is <see langword="null"/>.</exception>
 public static Ulid NewUlid(DateTimeOffset time, IUlidRng rng)
 {
     if (rng == null)
     {
         throw new ArgumentNullException(nameof(rng));
     }
     return(new Ulid(time, rng.GetRandomBytes(time)));
 }
        public static Guid NewGuid()
        {
            var timePart   = DateTime.Now;
            var randomPart = DEFAULTRNG.GetRandomBytes(10);
            var d          = DateTimeOffsetToByteArray(timePart);

            byte[] bytes = new byte[] { d[3], d[2], d[1], d[0], d[5], d[4], d[7], d[6],
                                        randomPart[0], randomPart[1], randomPart[2], randomPart[3],
                                        randomPart[4], randomPart[5], randomPart[6], randomPart[7] };
            return(new Guid(bytes));
            //return new byte[] { _d, _c, _b, _a, _f, _e, _h, _g, _i, _j, _k, _l, _m, _n, _o, _p };
        }
示例#4
0
        /// <summary>
        /// Creates and returns random bytes based on internal <see cref="IUlidRng"/>.
        /// </summary>
        /// <param name="dateTime">
        /// DateTime for which the random bytes need to be generated; this value is used to determine wether a sequence
        /// needs to be incremented (same timestamp with millisecond resolution) or reset to a new random value.
        /// </param>
        /// <returns>Random bytes.</returns>
        /// <exception cref="InvalidOperationException">
        /// Thrown when the specified <paramref name="dateTime"/> is before the last time this method was called.
        /// </exception>
        public override byte[] GetRandomBytes(DateTimeOffset dateTime)
        {
            lock (_genlock)
            {
                // Get unix time for given datetime
                var timestamp = Ulid.ToUnixTimeMilliseconds(dateTime);

                if (timestamp < _lastgen)
                {
                    throw new InvalidOperationException("Clock moved backwards; this is not supported.");
                }

                if (timestamp == _lastgen)  // Same timestamp as last time we generated random values?
                {
                    // Increment our random value by one.
                    var i = RANDLEN;
                    while (--i >= 0 && ++_lastvalue[i] == 0)
                    {
                        ;
                    }
                    // If i made it all the way to -1 we have an overflow and we throw
                    if (i < 0)
                    {
                        throw new OverflowException();
                    }
                }
                else // New(er) timestamp, so generate a new random value and store the new(er) timestamp
                {
                    _lastvalue = _rng.GetRandomBytes(dateTime);                 // Use internal RNG to get bytes from
                    for (var i = 0; i < _mask.Length && _mask[i] < 255; i++)    // Mask out desired number of MSB's
                    {
                        _lastvalue[i] = (byte)(_lastvalue[i] & _mask[i]);
                    }

                    _lastgen = timestamp;   // Store last timestamp
                }
                return(_lastvalue);
            }
        }
示例#5
0
 /// <summary>
 /// Creates and returns a new <see cref="Ulid"/> based on the specified time and using the specified RNG.
 /// </summary>
 /// <param name="time">
 /// The <see cref="DateTimeOffset"/> to use for the time-part of the <see cref="Ulid"/>.
 /// </param>
 /// <param name="rng">The <see cref="IUlidRng"/> to use for random number generation.</param>
 /// <returns>Returns a new <see cref="Ulid"/>.</returns>
 public static Ulid NewUlid(DateTimeOffset time, IUlidRng rng)
 {
     return(new Ulid(time, rng.GetRandomBytes(10)));
 }