コード例 #1
0
ファイル: Guid.cs プロジェクト: 812169562/sandcore
        /// <summary>
        /// 生产唯一识别号
        /// </summary>
        /// <param name="guidType"></param>
        /// <returns></returns>
        public static string Next(SequentialGuidType guidType = SequentialGuidType.SequentialAsString)
        {
            byte[] randomBytes = new byte[10];
            _rng.GetBytes(randomBytes);
            long timestamp = DateTime.UtcNow.Ticks / 10000L;

            byte[] timestampBytes = BitConverter.GetBytes(timestamp);
            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(timestampBytes);
            }
            byte[] guidBytes = new byte[16];
            switch (guidType)
            {
            case SequentialGuidType.SequentialAsString:
            case SequentialGuidType.SequentialAsBinary:
                Buffer.BlockCopy(timestampBytes, 2, guidBytes, 0, 6);
                Buffer.BlockCopy(randomBytes, 0, guidBytes, 6, 10);

                if (guidType == SequentialGuidType.SequentialAsString && BitConverter.IsLittleEndian)
                {
                    Array.Reverse(guidBytes, 0, 4);
                    Array.Reverse(guidBytes, 4, 2);
                }
                break;

            case SequentialGuidType.SequentialAtEnd:
                Buffer.BlockCopy(randomBytes, 0, guidBytes, 0, 10);
                Buffer.BlockCopy(timestampBytes, 2, guidBytes, 10, 6);
                break;
            }

            return(new Guid(guidBytes).ToString("N"));
        }
コード例 #2
0
        private static Guid New(SequentialGuidType guidType)
        {
            var randomBytes = new byte[10];

            Rng.GetBytes(randomBytes);

            var timestamp      = DateTime.UtcNow.Ticks / 10000L;
            var timestampBytes = BitConverter.GetBytes(timestamp);

            if(BitConverter.IsLittleEndian)
                Array.Reverse(timestampBytes);

            var guidBytes = new byte[16];

            switch(guidType) {
                case SequentialGuidType.SequentialAsString:
                case SequentialGuidType.SequentialAsBinary:
                    Buffer.BlockCopy(timestampBytes, 2, guidBytes, 0, 6);
                    Buffer.BlockCopy(randomBytes, 0, guidBytes, 6, 10);
                    // If formatting as a string, we have to reverse the order
                    // of the Data1 and Data2 blocks on little-endian systems.
                    if(guidType == SequentialGuidType.SequentialAsString && BitConverter.IsLittleEndian) {
                        Array.Reverse(guidBytes, 0, 4);
                        Array.Reverse(guidBytes, 4, 2);
                    }
                    break;
                case SequentialGuidType.SequentialAtEnd:
                    Buffer.BlockCopy(randomBytes, 0, guidBytes, 0, 10);
                    Buffer.BlockCopy(timestampBytes, 2, guidBytes, 10, 6);
                    break;
            }

            return new Guid(guidBytes);
        }
コード例 #3
0
ファイル: SequentialGuid.cs プロジェクト: fengweijp/higlabo
        /// <summary>
        /// 
        /// </summary>
        /// <param name="guidType"></param>
        /// <returns></returns>
        public static Guid NewGuid(SequentialGuidType guidType)
        {
            byte[] randomBytes = new byte[10];
            _rng.GetBytes(randomBytes);

            long timestamp = DateTime.Now.Ticks / 10000L;
            byte[] timestampBytes = BitConverter.GetBytes(timestamp);

            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(timestampBytes);
            }
            byte[] guidBytes = new byte[16];
            switch (guidType)
            {

                case SequentialGuidType.String:
                case SequentialGuidType.Binary:
                    Buffer.BlockCopy(timestampBytes, 2, guidBytes, 0, 6);
                    Buffer.BlockCopy(randomBytes, 0, guidBytes, 6, 10);
                    if (guidType == SequentialGuidType.String && BitConverter.IsLittleEndian)
                    {
                        Array.Reverse(guidBytes, 0, 4);
                        Array.Reverse(guidBytes, 4, 2);
                    }
                    break;
                case SequentialGuidType.AtEnd:
                    Buffer.BlockCopy(randomBytes, 0, guidBytes, 0, 10);
                    Buffer.BlockCopy(timestampBytes, 2, guidBytes, 10, 6);
                    break;
            }
            return new Guid(guidBytes);
        }
コード例 #4
0
        /// <summary>
        /// Base implementation of IPocoPersistor using Entity Framework 6
        /// </summary>
        /// <param name="connectionName">Connection name in .config files (default is 'Ractor', it
        /// is also used as a prefix for zero-based distributed connections, e.g. Ractor.0 )</param>
        /// <param name="readOnlyShards"></param>
        /// <param name="guidType">Use AtEnd only for MS SQL Server, for MySQL and others DBMS without
        /// native GUID types use binary</param>
        /// <param name="migrationDataLossAllowed"></param>
        public DatabasePersistor(string connectionName = "Ractor",
                                 DbMigrationsConfiguration <DataContext> migrationConfig = null,
                                 DbMigrationsConfiguration <DistributedDataContext> distributedMigrationConfig = null,
                                 IEnumerable <byte> readOnlyShards = null,
                                 SequentialGuidType guidType       = SequentialGuidType.SequentialAsBinary)
        {
            // Validate name presence
            _connectionName = Config.DataConnectionName(connectionName);
            // TODO delete this line when migrations are tested
            DataContext.UpdateAutoMigrations(_connectionName, migrationConfig);

            _guidType = guidType;
            if (readOnlyShards != null)
            {
                foreach (var readOnlyShard in readOnlyShards)
                {
                    _readOnlyShards.Add(readOnlyShard);
                }
            }
            _shards = Config.DistibutedDataConnectionNames(_connectionName).ToDictionary(x => x.Key, y => y.Value);
            if (_readOnlyShards.Count >= _shards.Count)
            {
                throw new ArgumentException("Too few writable shards!");
            }
            // check and register shards
            using (var ctx = GetContext()) {
                var two = ctx.Database.SqlQuery <int>("SELECT 1+1").SingleOrDefault(); // check DB engine is working
                if (two != 2)
                {
                    throw new ApplicationException("Connection string is not working: " + connectionName);
                }
            }

            CheckShardsAndSetEpoch(distributedMigrationConfig);
        }
コード例 #5
0
        /// <summary>
        /// 生成连续 GUID
        /// </summary>
        /// <param name="guidType"></param>
        /// <param name="serviceProvider"></param>
        /// <returns></returns>
        public static Guid NextID(SequentialGuidType guidType = SequentialGuidType.SequentialAsString, IServiceProvider serviceProvider = default)
        {
            var sequentialGuid = (App.GetService(typeof(SequentialGuidIDGenerator), serviceProvider) as IDistributedIDGenerator);

            return((Guid)sequentialGuid.Create(new SequentialGuidSettings {
                GuidType = guidType
            }));
        }
コード例 #6
0
        private const int NumberOfBytesInData2 = 2;                                            // Size of Data2 block of GUID

        /// <summary>
        /// Initializes a new instance of the <see cref="SequentialGuidFactory"/> class, which will generate keys as specified by <paramref name="sequentialGuidType"/>.
        /// </summary>
        /// <param name="sequentialGuidType">The type of sequential GUID values generated by the current instance.</param>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="sequentialGuidType"/> is not set to a recognized value.</exception>
        public SequentialGuidFactory(SequentialGuidType sequentialGuidType)
        {
            if (!Enum.IsDefined(typeof(SequentialGuidType), sequentialGuidType))
            {
                throw new ArgumentOutOfRangeException(nameof(sequentialGuidType));
            }

            SequentialGuidType = sequentialGuidType;
        }
コード例 #7
0
        /// <summary>
        /// Gets the next sequential guid, depending on where you are storing will dictate which type you want
        /// Note: When called within the same millisecond there is no guarntee it will be in sequence but it will be unique
        /// </summary>
        /// <param name="guidType"></param>
        /// <returns></returns>
        public static Guid Next(SequentialGuidType? guidType = null)
        {
            if (_random == null)
            {
                _random = new Random(_globalRandom.Next());
                _count = (ushort)_random.Next();
            }

            byte[] countBytes = BitConverter.GetBytes(_count++);

            byte[] randomBytes = new byte[10 - countBytes.Length];

            _random.NextBytes(randomBytes);

            long timestamp = DateTime.UtcNow.Ticks / 10000L;
            byte[] timestampBytes = BitConverter.GetBytes(timestamp);

            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(timestampBytes);
            }

            byte[] guidBytes = new byte[16];

            if (!guidType.HasValue)
            {
                guidType = DefaultType;
            }

            switch (guidType)
            {
                case SequentialGuidType.SequentialAsString:
                case SequentialGuidType.SequentialAsBinary:
                    Buffer.BlockCopy(timestampBytes, 2, guidBytes, 0, 6);
                    Buffer.BlockCopy(countBytes, 0, guidBytes, 6, countBytes.Length);
                    Buffer.BlockCopy(randomBytes, 0, guidBytes, 6 + countBytes.Length, randomBytes.Length);

                    // If formatting as a string, we have to reverse the order
                    // of the Data1 and Data2 blocks on little-endian systems.
                    if (guidType == SequentialGuidType.SequentialAsString && BitConverter.IsLittleEndian)
                    {
                        Array.Reverse(guidBytes, 0, 4);
                        Array.Reverse(guidBytes, 4, 2);
                    }
                    break;

                case SequentialGuidType.SequentialAtEnd:
                    Buffer.BlockCopy(countBytes, 0, guidBytes, 0, countBytes.Length);
                    Buffer.BlockCopy(randomBytes, 0, guidBytes, countBytes.Length, randomBytes.Length);
                    Buffer.BlockCopy(timestampBytes, 2, guidBytes, 10, 6);
                    break;
            }

            return new Guid(guidBytes);
        }
コード例 #8
0
        /// <summary>
        /// 全局唯一Guid
        /// 参考abp中生成连续的guid改编而成
        /// </summary>
        public static Guid Create(SequentialGuidType guidType)
        {
            var provider = GlobalConfigurations.Instance.GetGuidGeneratorProvider(guidType);

            if (provider == null)
            {
                throw new NotImplementedException("不支持的guidType");
            }

            return(provider.Create());
        }
コード例 #9
0
ファイル: GuidGenerator.cs プロジェクト: yonglehou/Ractor.CLR
        public static Guid NewRandomBucketGuid(SequentialGuidType guidType = SequentialGuidType.SequentialAsString, DateTime?utcDateTime = null)
        {
            var bs = new byte[1];

            bs[0] = 0;
            while (bs[0] == 0)
            {
                Rng.GetBytes(bs);
            }                                        // 1-255
            return(new Guid(GuidSequentialArray(bs[0], guidType, utcDateTime)));
        }
コード例 #10
0
        /// <summary>
        /// Returns a new GUID value which is sequentially ordered when formatted as
        /// a string, a byte array, or ordered by the least significant six bytes of the
        /// Data4 block, as specified by <paramref name="guidType" />.
        /// </summary>
        /// <param name="guidType">
        /// Specifies the type of sequential GUID (i.e. whether sequential as a string,
        /// as a byte array, or according to the Data4 block.  This can affect
        /// performance under various database types; see below.
        /// </param>
        /// <returns>
        /// A <see cref="Guid" /> structure whose value is created by replacing
        /// certain randomly-generated bytes with a sequential timestamp.
        /// </returns>

        public static Guid Create(SequentialGuidType guidType)
        {
            // We start with 16 bytes of cryptographically strong random data.
            byte[] randomBytes = new byte[10];
            SequentialGuidGenerator.RandomGenerator.GetBytes(randomBytes);


            long timestamp = timestampProvider.GetTimestamp().Ticks / 10000L;

            // Then get the bytes
            byte[] timestampBytes = BitConverter.GetBytes(timestamp);

            // Since we're converting from an Int64, we have to reverse on
            // little-endian systems.
            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(timestampBytes);
            }

            byte[] guidBytes = new byte[16];

            switch (guidType)
            {
            case SequentialGuidType.SequentialAsString:
            case SequentialGuidType.SequentialAsBinary:

                // For string and byte-array version, we copy the timestamp first, followed
                // by the random data.
                Buffer.BlockCopy(timestampBytes, 2, guidBytes, 0, 6);
                Buffer.BlockCopy(randomBytes, 0, guidBytes, 6, 10);

                // If formatting as a string, we have to compensate for the fact
                // that .NET regards the Data1 and Data2 block as an Int32 and an Int16,
                // respectively.  That means that it switches the order on little-endian
                // systems.  So again, we have to reverse.
                if (guidType == SequentialGuidType.SequentialAsString && BitConverter.IsLittleEndian)
                {
                    Array.Reverse(guidBytes, 0, 4);
                    Array.Reverse(guidBytes, 4, 2);
                }

                break;

            case SequentialGuidType.SequentialAtEnd:

                // For sequential-at-the-end versions, we copy the random data first,
                // followed by the timestamp.
                Buffer.BlockCopy(randomBytes, 0, guidBytes, 0, 10);
                Buffer.BlockCopy(timestampBytes, 2, guidBytes, 10, 6);
                break;
            }

            return(new Guid(guidBytes));
        }
コード例 #11
0
ファイル: TestGuidUtil.cs プロジェクト: jangocheng/Lucky.Core
        /// <summary>
        /// Generates a new GUID value which is sequentially ordered when formatted as a string, a byte array, or ordered by the least significant six bytes of the Data4 block, as specified by <paramref name="guidType" />.
        /// </summary>
        /// <param name="guidType">Specifies the type of sequential GUID (i.e. whether sequential as a string, as a byte array, or according to the Data4 block). This can affect performance under various database types.</param>
        /// <returns>A <see cref="Guid" /> structure whose value is created by replacing certain randomly-generated bytes with a sequential timestamp.</returns>
        private static Guid NewSequentialGuid(SequentialGuidType guidType)
        {
            // slower but more random
            byte[] randomBytes = new byte[10];
            RandomGenerator.GetBytes(randomBytes);

            ////// faster but less random
            ////byte[] randomBytes = Guid.NewGuid().ToByteArray();

            long timestamp = DateTime.UtcNow.Ticks / TicksFactor;

            byte[] timestampBytes = BitConverter.GetBytes(timestamp);

            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(timestampBytes);
            }

            byte[] guidBytes = new byte[16];

            switch (guidType)
            {
            case SequentialGuidType.SequentialAsString:

                Buffer.BlockCopy(timestampBytes, 2, guidBytes, 0, 6);
                Buffer.BlockCopy(randomBytes, 0, guidBytes, 6, 10);

                if (BitConverter.IsLittleEndian)
                {
                    Array.Reverse(guidBytes, 0, 4);
                    Array.Reverse(guidBytes, 4, 2);
                }

                break;

            case SequentialGuidType.SequentialAsBinary:

                Buffer.BlockCopy(timestampBytes, 2, guidBytes, 0, 6);
                Buffer.BlockCopy(randomBytes, 0, guidBytes, 6, 10);
                break;

            case SequentialGuidType.SequentialAtEnd:

                Buffer.BlockCopy(randomBytes, 0, guidBytes, 0, 10);
                Buffer.BlockCopy(timestampBytes, 2, guidBytes, 10, 6);
                break;
            }

            return(new Guid(guidBytes));
        }
コード例 #12
0
        /// <summary>
        /// Generates the GUIDs and displays them in the form.
        /// </summary>
        /// <param name="sender">The Generate button.</param>
        /// <param name="e">Additional information related to the event.</param>
        private void GenerateButton_Click(object sender, EventArgs e)
        {
            int count = 100;
            SequentialGuidType method = (SequentialGuidType)this.methodComboBox.SelectedItem;

            // Initialize the RTF text to enable color highlighting
            StringBuilder text = new StringBuilder();

            text.Append("{\\rtf1\\ansi\\deff0\n{\\colortbl;\\red0\\green0\\blue0;\\red128\\green0\\blue0;}\n");

            for (int i = 0; i < count; i++)
            {
                Guid   guid   = SequentialGuid.Create(method);
                string output = string.Empty;

                switch (method)
                {
                case SequentialGuidType.SequentialAsBinary:
                    byte[] bytes = guid.ToByteArray();

                    foreach (byte b in bytes)
                    {
                        output += string.Format("{0:x2}", b);
                    }

                    output = "\\cf2\n" + output.Substring(0, 12) + "\n\\cf1\n" + output.Substring(12) + "\n\\line\n";
                    break;

                case SequentialGuidType.SequentialAsString:
                    output = guid.ToString();
                    output = "\\cf2\n" + output.Substring(0, 13) + "\n\\cf1\n" + output.Substring(13) + "\n\\line\n";
                    break;

                case SequentialGuidType.SequentialAtEnd:
                    output = guid.ToString();
                    output = "\\cf1\n" + output.Substring(0, 24) + "\n\\cf2\n" + output.Substring(24) + "\n\\line\n";
                    break;

                default:
                    output = guid.ToString();
                    break;
                }

                text.Append(output);
                System.Threading.Thread.Sleep(1);
            }

            this.resultsTextBox.Rtf = text.ToString();
        }
コード例 #13
0
        public Guid NewSequentialGuid(SequentialGuidType guidType)
        {
            byte[] randomBytes = new byte[10];
            _rng.GetBytes(randomBytes);

            long timestamp = DateTime.UtcNow.Ticks / 10000L;

            byte[] timestampBytes = BitConverter.GetBytes(timestamp);

            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(timestampBytes);
            }

            byte[] guidBytes = new byte[16];

            switch (guidType)
            {
            case SequentialGuidType.SequentialAsString:
            case SequentialGuidType.SequentialAsBinary:

                // For string and byte-array version, we copy the timestamp first, followed
                // by the random data.
                Buffer.BlockCopy(timestampBytes, 2, guidBytes, 0, 6);
                Buffer.BlockCopy(randomBytes, 0, guidBytes, 6, 10);

                // If formatting as a string, we have to compensate for the fact
                // that .NET regards the Data1 and Data2 block as an Int32 and an Int16,
                // respectively.  That means that it switches the order on little-endian
                // systems.  So again, we have to reverse.
                if (guidType == SequentialGuidType.SequentialAsString && BitConverter.IsLittleEndian)
                {
                    Array.Reverse(guidBytes, 0, 4);
                    Array.Reverse(guidBytes, 4, 2);
                }

                break;

            case SequentialGuidType.SequentialAtEnd:

                // For sequential-at-the-end versions, we copy the random data first,
                // followed by the timestamp.
                Buffer.BlockCopy(randomBytes, 0, guidBytes, 0, 10);
                Buffer.BlockCopy(timestampBytes, 2, guidBytes, 10, 6);
                break;
            }

            return(new Guid(guidBytes));
        }
コード例 #14
0
ファイル: SGuid.cs プロジェクト: pavl0v/Ogam3
        public static Guid NewSequentialGuid(SequentialGuidType guidType)
        {
            var randomBytes = new byte[10];

            Rng.GetBytes(randomBytes);

            lock (Rng) {
                counter++;
                randomBytes[0] = (byte)counter;
                randomBytes[1] = (byte)(counter >> 8);
            }

            var timestamp      = DateTime.Now.Ticks / 10000L;
            var timestampBytes = BitConverter.GetBytes(timestamp);

            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(timestampBytes);
            }

            var guidBytes = new byte[16];

            switch (guidType)
            {
            case SequentialGuidType.SequentialAsString:
            case SequentialGuidType.SequentialAsBinary:

                Buffer.BlockCopy(timestampBytes, 2, guidBytes, 0, 6);
                Buffer.BlockCopy(randomBytes, 0, guidBytes, 6, 10);

                // If formatting as a string, we have to reverse the order
                // of the Data1 and Data2 blocks on little-endian systems.
                if (guidType == SequentialGuidType.SequentialAsString == BitConverter.IsLittleEndian)
                {
                    Array.Reverse(guidBytes, 0, 4);
                    Array.Reverse(guidBytes, 4, 2);
                }
                break;

            case SequentialGuidType.SequentialAtEnd:

                Buffer.BlockCopy(randomBytes, 0, guidBytes, 0, 10);
                Buffer.BlockCopy(timestampBytes, 2, guidBytes, 10, 6);
                break;
            }

            return(new Guid(guidBytes));
        }
コード例 #15
0
        public static long ExtractDateTimeTicks(byte[] guidBytes, SequentialGuidType guidType = SequentialGuidType.SequentialAsString)
        {
            byte[] timestampBytes = new byte[8];
            switch (guidType)
            {
            case SequentialGuidType.SequentialAsString:
            case SequentialGuidType.SequentialAsBinary:
                Buffer.BlockCopy(guidBytes, 0, timestampBytes, 2, 4);
                break;

            case SequentialGuidType.SequentialAtEnd:
                Buffer.BlockCopy(guidBytes, 2, timestampBytes, 12, 4);
                break;
            }
            return(BitConverter.ToInt64(timestampBytes, 0));
        }
コード例 #16
0
ファイル: GuidGenerator.cs プロジェクト: yonglehou/Ractor.CLR
        internal static byte[] GuidSequentialArray(byte bucket, SequentialGuidType guidType, DateTime?utcDateTime = null)
        {
            //if (bucket > 63) throw new ArgumentOutOfRangeException("bucket", "Bucket is too large! 64 buckets ought to be enough for anybody!");

            var bytes = new byte[16];

            Rng.GetBytes(bytes);

            long ticks = utcDateTime.HasValue? utcDateTime.Value.Ticks : GetTicks();

            // Convert to a byte array
            byte[] ticksArray = BitConverter.GetBytes(ticks);
            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(ticksArray);
            }

            // Copy the bytes into the guid

            switch (guidType)
            {
            case SequentialGuidType.SequentialAsString:
            case SequentialGuidType.SequentialAsBinary:
                Array.Copy(ticksArray, 1, bytes, 0, 7);     // 7 bytes for ticks ~ 228 years

                // If formatting as a string, we have to reverse the order
                // of the Data1 and Data2 blocks on little-endian systems.
                if (guidType == SequentialGuidType.SequentialAsString && BitConverter.IsLittleEndian)
                {
                    Array.Reverse(bytes, 0, 4);
                    Array.Reverse(bytes, 4, 2);
                    Array.Reverse(bytes, 6, 2);
                }
                break;

            case SequentialGuidType.SequentialAtEnd:
                Buffer.BlockCopy(ticksArray, 1, bytes, 9, 7);
                break;
            }


            var guidTypeByte = (byte)guidType;

            // first two bits for sequence type, other 6 bits for bucket
            bytes[8] = (byte)(((guidTypeByte & 3) << 6) | (bucket & 63));
            return(bytes);
        }
コード例 #17
0
        public static Guid Generate(SequentialGuidType sequentialGuidType)
        {
            var randomBytes = new byte[10];

            Rng.GetBytes(randomBytes);

            var timestamp      = DateTime.UtcNow.Ticks / 10000L;
            var timestampBytes = BitConverter.GetBytes(timestamp);

            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(timestampBytes);
            }

            var guidBytes = new byte[16];

            switch (sequentialGuidType)
            {
            case SequentialGuidType.SequentialAsString:
            case SequentialGuidType.SequentialAsBinary:
                Buffer.BlockCopy(timestampBytes, 2, guidBytes, 0, 6);
                Buffer.BlockCopy(randomBytes, 0, guidBytes, 6, 10);

                // If formatting as a string, we have to reverse the order
                // of the Data1 and Data2 blocks on little-endian systems.
                if (sequentialGuidType == SequentialGuidType.SequentialAsString && BitConverter.IsLittleEndian)
                {
                    Array.Reverse(guidBytes, 0, 4);
                    Array.Reverse(guidBytes, 4, 2);
                }
                break;

            case SequentialGuidType.SequentialAtEnd:

                Buffer.BlockCopy(randomBytes, 0, guidBytes, 0, 10);
                Buffer.BlockCopy(timestampBytes, 2, guidBytes, 10, 6);
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(sequentialGuidType), sequentialGuidType, null);
            }

            return(new Guid(guidBytes));
        }
コード例 #18
0
        public static Guid NewSequentialGuid(SequentialGuidType guidType = SequentialGuidType.SequentialAtEnd)
        {
            byte[] randomBytes = new byte[10];
            _rng.GetBytes(randomBytes);

            long timestamp = DateTime.UtcNow.Ticks / 10000L;

            byte[] timestampBytes = BitConverter.GetBytes(timestamp);

            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(timestampBytes);
            }

            byte[] guidBytes = new byte[16];

            switch (guidType)
            {
            case SequentialGuidType.NoSequential:
                return(Guid.NewGuid());

            case SequentialGuidType.SequentialAsString:
            case SequentialGuidType.SequentialAsBinary:
                Buffer.BlockCopy(timestampBytes, 2, guidBytes, 0, 6);
                Buffer.BlockCopy(randomBytes, 0, guidBytes, 6, 10);

                // If formatting as a string, we have to reverse the order
                // of the Data1 and Data2 blocks on little-endian systems.
                if (guidType == SequentialGuidType.SequentialAsString && BitConverter.IsLittleEndian)
                {
                    Array.Reverse(guidBytes, 0, 4);
                    Array.Reverse(guidBytes, 4, 2);
                }
                break;

            case SequentialGuidType.SequentialAtEnd:
                Buffer.BlockCopy(randomBytes, 0, guidBytes, 0, 10);
                Buffer.BlockCopy(timestampBytes, 2, guidBytes, 10, 6);
                break;
            }

            return(new Guid(guidBytes));
        }
コード例 #19
0
        public static Guid NewGuid(SequentialGuidType guidType)
        {
            var randomBytes = new byte[10];

            _random.NextBytes(randomBytes);

            //private static readonly RNGCryptoServiceProvider _rng = new RNGCryptoServiceProvider();
            //_rng.GetBytes(randomBytes);


            var timestamp      = DateTime.UtcNow.Ticks / 10000L;
            var timestampBytes = BitConverter.GetBytes(timestamp);

            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(timestampBytes);
            }

            var guidBytes = new byte[16];

            switch (guidType)
            {
            case SequentialGuidType.SequentialAsString:
            case SequentialGuidType.SequentialAsBinary:
                Buffer.BlockCopy(timestampBytes, 2, guidBytes, 0, 6);
                Buffer.BlockCopy(randomBytes, 0, guidBytes, 6, 10);

                // If formatting as a string, we have to reverse the order
                // of the Data1 and Data2 blocks on little-endian systems.
                if (guidType == SequentialGuidType.SequentialAsString && BitConverter.IsLittleEndian)
                {
                    Array.Reverse(guidBytes, 0, 4);
                    Array.Reverse(guidBytes, 4, 2);
                }
                break;

            case SequentialGuidType.SequentialAtEnd:
                Buffer.BlockCopy(randomBytes, 0, guidBytes, 0, 10);
                Buffer.BlockCopy(timestampBytes, 2, guidBytes, 10, 6);
                break;
            }
            return(new Guid(guidBytes));
        }
コード例 #20
0
ファイル: GuidGenerator.cs プロジェクト: Stan-/Ractor.CLR
        internal static byte[] GuidSequentialArray(byte bucket, SequentialGuidType guidType, DateTime? utcDateTime = null) {
            //if (bucket > 63) throw new ArgumentOutOfRangeException("bucket", "Bucket is too large! 64 buckets ought to be enough for anybody!");
            
            var bytes = new byte[16];
            Rng.GetBytes(bytes);

            long ticks = utcDateTime.HasValue? utcDateTime.Value.Ticks : GetTicks();

            // Convert to a byte array 
            byte[] ticksArray = BitConverter.GetBytes(ticks);
            if (BitConverter.IsLittleEndian) {
                Array.Reverse(ticksArray);
            }

            // Copy the bytes into the guid 

            switch (guidType) {
                case SequentialGuidType.SequentialAsString:
                case SequentialGuidType.SequentialAsBinary:
                    Array.Copy(ticksArray, 1, bytes, 0, 7); // 7 bytes for ticks ~ 228 years

                    // If formatting as a string, we have to reverse the order
                    // of the Data1 and Data2 blocks on little-endian systems.
                    if (guidType == SequentialGuidType.SequentialAsString && BitConverter.IsLittleEndian) {
                        Array.Reverse(bytes, 0, 4);
                        Array.Reverse(bytes, 4, 2);
                        Array.Reverse(bytes, 6, 2);
                    }
                    break;

                case SequentialGuidType.SequentialAtEnd:
                    Buffer.BlockCopy(ticksArray, 1, bytes, 9, 7);
                    break;
            }


            var guidTypeByte = (byte) guidType;
            // first two bits for sequence type, other 6 bits for bucket
            bytes[8] = (byte)(( (guidTypeByte & 3) << 6 ) | (bucket & 63) );
            return bytes;
        }
コード例 #21
0
ファイル: TestGuidUtil.cs プロジェクト: jangocheng/Lucky.Core
        /// <summary>
        /// Gets the DateTime from sequential GUID.
        /// </summary>
        /// <param name="guid">The GUID.</param>
        /// <param name="guidType">Specifies the type of sequential GUID (i.e. whether sequential as a string, as a byte array, or according to the Data4 block). This can affect performance under various database types.</param>
        /// <returns> DateTime object expressed as the Coordinated Universal Time (UTC).</returns>
        private static DateTime GetTimestampFromGuid(Guid guid, SequentialGuidType guidType)
        {
            byte[] guidBytes = guid.ToByteArray();

            byte[] timestampBytes = new byte[8];

            switch (guidType)
            {
            case SequentialGuidType.SequentialAsString:

                if (BitConverter.IsLittleEndian)
                {
                    Array.Reverse(guidBytes, 0, 4);
                    Array.Reverse(guidBytes, 4, 2);
                }

                Buffer.BlockCopy(guidBytes, 0, timestampBytes, 2, 6);
                break;

            case SequentialGuidType.SequentialAsBinary:

                Buffer.BlockCopy(guidBytes, 0, timestampBytes, 2, 6);
                break;

            case SequentialGuidType.SequentialAtEnd:

                Buffer.BlockCopy(guidBytes, 10, timestampBytes, 2, 6);
                break;
            }

            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(timestampBytes);
            }

            long dateTimeData = BitConverter.ToInt64(timestampBytes, 0) * TicksFactor;

            DateTime result = DateTime.FromBinary(dateTimeData);

            return(result);
        }
コード例 #22
0
        public static Guid Generate(SequentialGuidType sequentialGuidType)
        {
            var randomBytes = new byte[10];
            Rng.GetBytes(randomBytes);

            var timestamp = DateTime.UtcNow.Ticks / 10000L;
            var timestampBytes = BitConverter.GetBytes(timestamp);

            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(timestampBytes);
            }

            var guidBytes = new byte[16];

            switch (sequentialGuidType)
            {
                case SequentialGuidType.SequentialAsString:
                case SequentialGuidType.SequentialAsBinary:
                    Buffer.BlockCopy(timestampBytes, 2, guidBytes, 0, 6);
                    Buffer.BlockCopy(randomBytes, 0, guidBytes, 6, 10);

                    // If formatting as a string, we have to reverse the order
                    // of the Data1 and Data2 blocks on little-endian systems.
                    if (sequentialGuidType == SequentialGuidType.SequentialAsString && BitConverter.IsLittleEndian)
                    {
                        Array.Reverse(guidBytes, 0, 4);
                        Array.Reverse(guidBytes, 4, 2);
                    }
                    break;
                case SequentialGuidType.SequentialAtEnd:

                    Buffer.BlockCopy(randomBytes, 0, guidBytes, 0, 10);
                    Buffer.BlockCopy(timestampBytes, 2, guidBytes, 10, 6);
                    break;
                default:
                    throw new ArgumentOutOfRangeException(nameof(sequentialGuidType), sequentialGuidType, null);
            }

            return new Guid(guidBytes);
        }
コード例 #23
0
        public static Guid Create(SequentialGuidType guidType = SequentialGuidType.SequentialAsString)
        {
            byte[] randomBytes = Guid.NewGuid().ToByteArray();

            long timestamp      = DateTime.UtcNow.Ticks / 10000L;
            var  timestampBytes = BitConverter.GetBytes(timestamp);

            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(timestampBytes);
            }

            var guidBytes = new byte[16];

            switch (guidType)
            {
            case SequentialGuidType.SequentialAsString:
            case SequentialGuidType.SequentialAsBinary:
                Buffer.BlockCopy(timestampBytes, 2, guidBytes, 0, 6);
                Buffer.BlockCopy(randomBytes, 0, guidBytes, 6, 10);

                // If formatting as a string, we have to reverse the order
                // of the Data1 and Data2 blocks on little-endian systems.
                if (guidType == SequentialGuidType.SequentialAsString && BitConverter.IsLittleEndian)
                {
                    Array.Reverse(guidBytes, 0, 4);
                    Array.Reverse(guidBytes, 4, 2);
                }
                break;

            case SequentialGuidType.SequentialAtEnd:
                Buffer.BlockCopy(randomBytes, 0, guidBytes, 0, 10);
                Buffer.BlockCopy(timestampBytes, 2, guidBytes, 10, 6);
                break;

            default:
                throw new Exception($"Case missing for {guidType}");
            }

            return(new Guid(guidBytes));
        }
コード例 #24
0
		public static Guid NewSequentialGuid(DateTime created, Guid sourceGuid, SequentialGuidType resultingGuidType)
		{
			var randomBytes = sourceGuid.ToByteArray();

			var timestamp = created.Ticks / 10000L;
			var timestampBytes = BitConverter.GetBytes(timestamp);

			if (BitConverter.IsLittleEndian)
				Array.Reverse(timestampBytes);

			var guidBytes = new byte[16];

			switch (resultingGuidType)
			{
				case (SequentialGuidType.SequentialAsString):
				case (SequentialGuidType.SequentialAsBinary):
					{
						Buffer.BlockCopy(timestampBytes, 2, guidBytes, 0, 6);
						Buffer.BlockCopy(randomBytes, 0, guidBytes, 6, 10);

						// If formatting as a string, we have to reverse the order
						// of the Data1 and Data2 blocks on little-endian systems.
						if (resultingGuidType == SequentialGuidType.SequentialAsString &&
							BitConverter.IsLittleEndian)
						{
							Array.Reverse(guidBytes, 0, 4);
							Array.Reverse(guidBytes, 4, 2);
						}
						break;
					}

				case (SequentialGuidType.SequentialAtEnd):
					{
						Buffer.BlockCopy(randomBytes, 0, guidBytes, 0, 10);
						Buffer.BlockCopy(timestampBytes, 2, guidBytes, 10, 6);
						break;
					}
			}

			return new Guid(guidBytes);
		}
コード例 #25
0
        ///<summary>
        /// Generates a GuidComb (COMBined GUID/timestamp). This is a Guid generation model, suggested by Jimmy Nilsson, where some bytes have been replaced by a timestamp-based value that is guaranteed to increase, but not decrease, with each new value generated.
        /// The goal is to remove the database performance limitations of using GUIDS as surrogate primary keys.
        ///</summary>
        ///<returns><see cref="Guid"/></returns>
        /// TODO: Determine the database type from service locator and predetermine what the guidType should be
        public static Guid Generate(SequentialGuidType guidType)
        {
            byte[] randomBytes = new byte[10];
            _rng.GetBytes(randomBytes);
            // TODO: Implement DependencyInjection for date time instance
            //long timestamp = ServiceLocator.Current.GetInstance<IDateTimeProvider>().UtcNow.Ticks / 10000L;
            long timestamp = DateTime.UtcNow.Ticks / 10000L;

            byte[] timestampBytes = BitConverter.GetBytes(timestamp);

            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(timestampBytes);
            }

            byte[] guidBytes = new byte[16];

            switch (guidType)
            {
            case SequentialGuidType.SequentialAsString:
            case SequentialGuidType.SequentialAsBinary:
                Buffer.BlockCopy(timestampBytes, 2, guidBytes, 0, 6);
                Buffer.BlockCopy(randomBytes, 0, guidBytes, 6, 10);

                // If formatting as a string, we have to reverse the order
                // of the Data1 and Data2 blocks on little-endian systems.
                if (guidType == SequentialGuidType.SequentialAsString && BitConverter.IsLittleEndian)
                {
                    Array.Reverse(guidBytes, 0, 4);
                    Array.Reverse(guidBytes, 4, 2);
                }
                break;

            case SequentialGuidType.SequentialAtEnd:
                Buffer.BlockCopy(randomBytes, 0, guidBytes, 0, 10);
                Buffer.BlockCopy(timestampBytes, 2, guidBytes, 10, 6);
                break;
            }

            return(new Guid(guidBytes));
        }
コード例 #26
0
        public static Guid Create(SequentialGuidType guidType)
        {
            var randomBytes = new byte[10];

            _RandomGenerator.GetBytes(randomBytes);

            var timestamp      = DateTimeOffset.UtcNow.Ticks / 10000L;
            var timestampBytes = BitConverter.GetBytes(timestamp);

            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(timestampBytes);
            }

            var guidBytes = new byte[16];

            switch (guidType)
            {
            case SequentialGuidType.SequentialAsString:
            case SequentialGuidType.SequentialAsBinary:
                Buffer.BlockCopy(timestampBytes, 2, guidBytes, 0, 6);
                Buffer.BlockCopy(randomBytes, 0, guidBytes, 6, 10);

                if (guidType == SequentialGuidType.SequentialAsString && BitConverter.IsLittleEndian)
                {
                    Array.Reverse(guidBytes, 0, 4);
                    Array.Reverse(guidBytes, 4, 2);
                }

                break;

            case SequentialGuidType.SequentialAtEnd:
                Buffer.BlockCopy(randomBytes, 0, guidBytes, 0, 10);
                Buffer.BlockCopy(timestampBytes, 2, guidBytes, 10, 6);
                break;
            }

            return(new Guid(guidBytes));
        }
コード例 #27
0
 /// <summary>
 /// Initialize the generator.
 /// </summary>
 /// <param name="type">The sequential guid type.</param>
 public SequentialGuidGenerator(SequentialGuidType type)
 {
     _type = type;
 }
コード例 #28
0
        private static Guid NewGuid(SequentialGuidType guidType)
        {
            long timestamp = DateTime.UtcNow.Ticks / 10000L;
            //timestamp += Threading.Interlocked.Increment(ref guidSequenceNumber);
            byte[] timestampBytes = BitConverter.GetBytes(timestamp);
            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(timestampBytes);
            }

            byte[] guidBytes = Guid.NewGuid().ToByteArray();
            switch (guidType)
            {
                case SequentialGuidType.SequentialAsString:
                case SequentialGuidType.SequentialAsBinary:
                    Buffer.BlockCopy(timestampBytes, 2, guidBytes, 0, 6);
                    // If formatting as a string, we have to reverse the order
                    // of the Data1 and Data2 blocks on little-endian systems.
                    if (guidType == SequentialGuidType.SequentialAsString && BitConverter.IsLittleEndian)
                    {
                        Array.Reverse(guidBytes, 0, 4);
                        Array.Reverse(guidBytes, 4, 2);
                    }
                    break;

                case SequentialGuidType.SequentialAtEnd:
                    Buffer.BlockCopy(timestampBytes, 2, guidBytes, 10, 6);
                    break;
            }

            return new Guid(guidBytes);
        }
コード例 #29
0
        public Guid Create(SequentialGuidType guidType)
        {
            // We start with 16 bytes of cryptographically strong random data.
            byte[] randomBytes = new byte[10];
            _rng.GetBytes(randomBytes);

            // An alternate method: use a normally-created GUID to get our initial
            // random data:
            // byte[] randomBytes = Guid.NewGuid().ToByteArray();
            // This is faster than using RNGCryptoServiceProvider, but I don't
            // recommend it because the .NET Framework makes no guarantee of the
            // randomness of GUID data, and future versions (or different
            // implementations like Mono) might use a different method.

            // Now we have the random basis for our GUID.  Next, we need to
            // create the six-byte block which will be our timestamp.

            // We start with the number of milliseconds that have elapsed since
            // DateTime.MinValue.  This will form the timestamp.  There's no use
            // being more specific than milliseconds, since DateTime.Now has
            // limited resolution.

            // Using millisecond resolution for our 48-bit timestamp gives us
            // about 5900 years before the timestamp overflows and cycles.
            // Hopefully this should be sufficient for most purposes. :)
            long timestamp = DateTime.UtcNow.Ticks / 10000L;

            // Then get the bytes
            byte[] timestampBytes = BitConverter.GetBytes(timestamp);

            // Since we're converting from an Int64, we have to reverse on
            // little-endian systems.
            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(timestampBytes);
            }

            byte[] guidBytes = new byte[16];

            switch (guidType)
            {
                case SequentialGuidType.SequentialAsString:
                case SequentialGuidType.SequentialAsBinary:

                    // For string and byte-array version, we copy the timestamp first, followed
                    // by the random data.
                    Buffer.BlockCopy(timestampBytes, 2, guidBytes, 0, 6);
                    Buffer.BlockCopy(randomBytes, 0, guidBytes, 6, 10);

                    // If formatting as a string, we have to compensate for the fact
                    // that .NET regards the Data1 and Data2 block as an Int32 and an Int16,
                    // respectively.  That means that it switches the order on little-endian
                    // systems.  So again, we have to reverse.
                    if (guidType == SequentialGuidType.SequentialAsString && BitConverter.IsLittleEndian)
                    {
                        Array.Reverse(guidBytes, 0, 4);
                        Array.Reverse(guidBytes, 4, 2);
                    }

                    break;

                case SequentialGuidType.SequentialAtEnd:

                    // For sequential-at-the-end versions, we copy the random data first,
                    // followed by the timestamp.
                    Buffer.BlockCopy(randomBytes, 0, guidBytes, 0, 10);
                    Buffer.BlockCopy(timestampBytes, 2, guidBytes, 10, 6);
                    break;
            }

            return new Guid(guidBytes);
        }
コード例 #30
0
ファイル: GuidHelper.cs プロジェクト: xinzeyang/iiServices
 /// <summary>
 /// 获取有序的唯一ID。
 /// </summary>
 /// <returns></returns>
 public static Guid GenerateComb(SequentialGuidType sequentialGuidType = SequentialGuidType.SequentialAtEnd)
 {
     return(SequentialGuidGenerator.NewSequentialGuid(sequentialGuidType));
 }
コード例 #31
0
ファイル: GuidGenerator.cs プロジェクト: yonglehou/Ractor.CLR
 /// <summary>
 ///     Generate new Guid for a bucket
 /// </summary>
 public static Guid NewBucketGuid(byte bucket, SequentialGuidType guidType = SequentialGuidType.SequentialAsString, DateTime?utcDateTime = null)
 {
     return(new Guid(GuidSequentialArray(bucket, guidType, utcDateTime)));
 }
コード例 #32
0
ファイル: GuidGenerator.cs プロジェクト: yonglehou/Ractor.CLR
 /// <summary>
 ///     Generate a new Guid that will have the same bucket as the root Guid
 /// </summary>
 public static Guid NewBucketGuid(Guid rootGuid, SequentialGuidType guidType = SequentialGuidType.SequentialAsString)
 {
     return(new Guid(GuidSequentialArray(rootGuid.ToByteArray()[8], guidType)));
 }
コード例 #33
0
 public SequentialGuidIdGenerator(SequentialGuidType sequentialGuidType)
 {
     _sequentialGuidType = sequentialGuidType;
 }
コード例 #34
0
ファイル: IdGenerator.cs プロジェクト: kangwl/KANG.Frame
        /// <summary>
        /// Gets the DateTime from sequential GUID.
        /// </summary>
        /// <param name="guid">The GUID.</param>
        /// <param name="guidType">Specifies the type of sequential GUID (i.e. whether sequential as a string, as a byte array, or according to the Data4 block). This can affect performance under various database types.</param>
        /// <returns> DateTime object expressed as the Coordinated Universal Time (UTC).</returns>
        private static DateTime GetTimestampFromGuid(Guid guid, SequentialGuidType guidType) {
            byte[] guidBytes = guid.ToByteArray();

            byte[] timestampBytes = new byte[8];

            switch (guidType) {
                case SequentialGuidType.SequentialAsString:

                    if (BitConverter.IsLittleEndian) {
                        Array.Reverse(guidBytes, 0, 4);
                        Array.Reverse(guidBytes, 4, 2);
                    }

                    Buffer.BlockCopy(guidBytes, 0, timestampBytes, 2, 6);
                    break;

                case SequentialGuidType.SequentialAsBinary:

                    Buffer.BlockCopy(guidBytes, 0, timestampBytes, 2, 6);
                    break;

                case SequentialGuidType.SequentialAtEnd:

                    Buffer.BlockCopy(guidBytes, 10, timestampBytes, 2, 6);
                    break;
            }

            if (BitConverter.IsLittleEndian) {
                Array.Reverse(timestampBytes);
            }

            long dateTimeData = BitConverter.ToInt64(timestampBytes, 0) * TicksFactor;

            DateTime result = DateTime.FromBinary(dateTimeData);

            return result;
        }
コード例 #35
0
        /// <summary>
        /// Returns a new GUID value which is sequentially ordered when formatted as
        /// a string, a byte array, or ordered by the least significant six bytes of the
        /// Data4 block, as specified by <paramref name="guidType" />.
        /// </summary>
        /// <param name="guidType">
        /// Specifies the type of sequential GUID (i.e. whether sequential as a string,
        /// as a byte array, or according to the Data4 block.  This can affect
        /// performance under various database types; see below.
        /// </param>
        /// <returns>
        /// A <see cref="Guid" /> structure whose value is created by replacing
        /// certain randomly-generated bytes with a sequential timestamp.
        /// </returns>
        /// <remarks>
        /// <para>
        /// This method creates a new GUID value which combines a random component
        /// with the current timestamp, also known as a COMB.  The general concept
        /// is outlined in Jimmy Nilsson's article "The Cost of GUIDs as Primary Keys",
        /// and involves replacing either the least significant or most significant
        /// six bytes of the GUID with the current timestamp.  This reduces the
        /// random component of the GUID from 16 bytes to 10 bytes, but this is
        /// still sufficient to prevent a collision under most real-world circumstances.
        /// </para>
        /// <para>
        /// The purpose of sequential GUIDs is not to promote the use of GUIDs as
        /// sortable entities.  In fact, GUIDs generated very close together may
        /// have the same timestamp and are not guaranteed to be sequentially ordered
        /// at all.  The intent is to increase performance when doing repeated
        /// inserts into database tables that have a clustered index on a GUID
        /// column, so that later entries do not have to be inserted into the middle
        /// of the table, but can simply be appended to the end.
        /// </para>
        /// <para>
        /// According to experiments, Microsoft SQL Server sorts GUID values using
        /// the least significant six bytes of the Data4 block; therefore, GUIDs being
        /// generated for use with SQL Server should pass a <paramref name="guidType" />
        /// value of <c>SequentialAtEnd</c>.  GUIDs generated for most other database
        /// types should be passed a <paramref name="guidType" /> value of
        /// <c>SequentialAsString</c> or <c>SequentialAsByteArray</c>.
        /// </para>
        /// <para>
        /// Various standards already define a time-based UUID; however, the
        /// format specified by these standards splits the timestamp into
        /// several components, limiting its usefulness as a sequential ID.
        /// Additionally, the format used for such UUIDs is not compatible
        /// with the GUID ordering on Microsoft SQL Server.
        /// </para>
        /// </remarks>
        public static Guid Create(SequentialGuidType guidType = SequentialGuidType.SequentialAsString)
        {
            // We start with 16 bytes of cryptographically strong random data.
            byte[] randomBytes = new byte[10];
            SequentialGuid.RandomGenerator.GetBytes(randomBytes);

            // An alternate method: use a normally-created GUID to get our initial
            // random data:
            // byte[] randomBytes = Guid.NewGuid().ToByteArray();
            // This is faster than using RNGCryptoServiceProvider, but I don't
            // recommend it because the .NET Framework makes no guarantee of the
            // randomness of GUID data, and future versions (or different
            // implementations like Mono) might use a different method.

            // Now we have the random basis for our GUID.  Next, we need to
            // create the six-byte block which will be our timestamp.

            // We start with the number of milliseconds that have elapsed since
            // DateTime.MinValue.  This will form the timestamp.  There's no use
            // being more specific than milliseconds, since DateTime.Now has
            // limited resolution.

            // Using millisecond resolution for our 48-bit timestamp gives us
            // about 5900 years before the timestamp overflows and cycles.
            // Hopefully this should be sufficient for most purposes. :)
            long timestamp = DateTime.UtcNow.Ticks / 10000L;

            // Then get the bytes
            byte[] timestampBytes = BitConverter.GetBytes(timestamp);

            // Since we're converting from an Int64, we have to reverse on
            // little-endian systems.
            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(timestampBytes);
            }

            byte[] guidBytes = new byte[16];

            switch (guidType)
            {
            case SequentialGuidType.SequentialAsString:
            case SequentialGuidType.SequentialAsBinary:

                // For string and byte-array version, we copy the timestamp first, followed
                // by the random data.
                Buffer.BlockCopy(timestampBytes, 2, guidBytes, 0, 6);
                Buffer.BlockCopy(randomBytes, 0, guidBytes, 6, 10);

                // If formatting as a string, we have to compensate for the fact
                // that .NET regards the Data1 and Data2 block as an Int32 and an Int16,
                // respectively.  That means that it switches the order on little-endian
                // systems.  So again, we have to reverse.
                if (guidType == SequentialGuidType.SequentialAsString && BitConverter.IsLittleEndian)
                {
                    Array.Reverse(guidBytes, 0, 4);
                    Array.Reverse(guidBytes, 4, 2);
                }

                break;

            case SequentialGuidType.SequentialAtEnd:

                // For sequential-at-the-end versions, we copy the random data first,
                // followed by the timestamp.
                Buffer.BlockCopy(randomBytes, 0, guidBytes, 0, 10);
                Buffer.BlockCopy(timestampBytes, 2, guidBytes, 10, 6);
                break;
            }

            return(new Guid(guidBytes));
        }
コード例 #36
0
 /// <summary>
 /// Sets the default sequential GUID generation type.
 /// This method should be called at the application initialization.
 /// </summary>
 /// <param name="value">A sequential GUID generation type.</param>
 public static void SetDefaultSequentialGuidType(SequentialGuidType value)
 {
     defaultSequentialGuidType = value;
 }
コード例 #37
0
 /// <summary>
 /// 得到唯一标识提供者
 /// </summary>
 /// <param name="sequentialGuidType">唯一标识类型</param>
 /// <returns></returns>
 public IGuidGeneratorProvider GetGuidGeneratorProvider(SequentialGuidType sequentialGuidType)
 {
     return(GetGuidGeneratorProvider(sequentialGuidType.Id));
 }
コード例 #38
0
ファイル: GuidGenerator.cs プロジェクト: Stan-/Ractor.CLR
 public static Guid NewGuid(SequentialGuidType guidType = SequentialGuidType.SequentialAsString, DateTime? utcDateTime = null) {
     return new Guid(GuidSequentialArray(0, guidType, utcDateTime));
 }
コード例 #39
0
ファイル: GuidGenerator.cs プロジェクト: Stan-/Ractor.CLR
 /// <summary>
 ///     Generate a new Guid that will have the same bucket as the root Guid
 /// </summary>
 public static Guid NewBucketGuid(Guid rootGuid, SequentialGuidType guidType = SequentialGuidType.SequentialAsString) {
     return new Guid(GuidSequentialArray(rootGuid.ToByteArray()[8], guidType));
 }
コード例 #40
0
ファイル: GuidGenerator.cs プロジェクト: Stan-/Ractor.CLR
 /// <summary>
 ///     Generate new Guid for a bucket
 /// </summary>
 public static Guid NewBucketGuid(byte bucket, SequentialGuidType guidType = SequentialGuidType.SequentialAsString, DateTime? utcDateTime = null) {
     return new Guid(GuidSequentialArray(bucket, guidType,utcDateTime));
 }
コード例 #41
0
ファイル: GuidGenerator.cs プロジェクト: Stan-/Ractor.CLR
 public static Guid NewRandomBucketGuid(SequentialGuidType guidType = SequentialGuidType.SequentialAsString, DateTime? utcDateTime = null) {
     var bs = new byte[1];
     bs[0] = 0;
     while (bs[0] == 0) { Rng.GetBytes(bs); } // 1-255
     return new Guid(GuidSequentialArray(bs[0], guidType, utcDateTime));
 }
コード例 #42
0
 public static Guid NewRandomBucketGuid(SequentialGuidType guidType = SequentialGuidType.SequentialAsString, DateTime?utcDateTime = null)
 {
     return(new Guid(GuidSequentialArray((byte)Rng.Next(1, 256), guidType, utcDateTime)));
 }
コード例 #43
0
ファイル: GuidGenerator.cs プロジェクト: yonglehou/Ractor.CLR
 public static Guid NewGuid(SequentialGuidType guidType = SequentialGuidType.SequentialAsString, DateTime?utcDateTime = null)
 {
     return(new Guid(GuidSequentialArray(0, guidType, utcDateTime)));
 }
コード例 #44
0
		public static Guid NewSequentialGuid(SequentialGuidType guidType) => NewSequentialGuid(DateTime.UtcNow, Guid.NewGuid(), guidType);
コード例 #45
0
ファイル: IdGenerator.cs プロジェクト: kangwl/KANG.Frame
        /// <summary>
        /// Generates a new GUID value which is sequentially ordered when formatted as a string, a byte array, or ordered by the least significant six bytes of the Data4 block, as specified by <paramref name="guidType" />.
        /// </summary>
        /// <param name="guidType">Specifies the type of sequential GUID (i.e. whether sequential as a string, as a byte array, or according to the Data4 block). This can affect performance under various database types.</param>
        /// <returns>A <see cref="Guid" /> structure whose value is created by replacing certain randomly-generated bytes with a sequential timestamp.</returns>
        private static Guid NewSequentialGuid(SequentialGuidType guidType) {
            // slower but more random
            byte[] randomBytes = new byte[10];
            RandomGenerator.GetBytes(randomBytes);

            ////// faster but less random
            ////byte[] randomBytes = Guid.NewGuid().ToByteArray();

            long timestamp = DateTime.UtcNow.Ticks / TicksFactor;
            byte[] timestampBytes = BitConverter.GetBytes(timestamp);

            if (BitConverter.IsLittleEndian) {
                Array.Reverse(timestampBytes);
            }

            byte[] guidBytes = new byte[16];

            switch (guidType) {
                case SequentialGuidType.SequentialAsString:

                    Buffer.BlockCopy(timestampBytes, 2, guidBytes, 0, 6);
                    Buffer.BlockCopy(randomBytes, 0, guidBytes, 6, 10);

                    if (BitConverter.IsLittleEndian) {
                        Array.Reverse(guidBytes, 0, 4);
                        Array.Reverse(guidBytes, 4, 2);
                    }

                    break;

                case SequentialGuidType.SequentialAsBinary:

                    Buffer.BlockCopy(timestampBytes, 2, guidBytes, 0, 6);
                    Buffer.BlockCopy(randomBytes, 0, guidBytes, 6, 10);
                    break;

                case SequentialGuidType.SequentialAtEnd:

                    Buffer.BlockCopy(randomBytes, 0, guidBytes, 0, 10);
                    Buffer.BlockCopy(timestampBytes, 2, guidBytes, 10, 6);
                    break;
            }

            return new Guid(guidBytes);
        }