Esempio n. 1
0
        /// <summary>
        /// Generates a unique, sequential, Base36 string, 16 characters long.
        /// The first 10 characters are the microseconds elapsed since the InService DateTime
        ///		(constant field you hardcode in this file).
        /// The next 2 characters are a compressed checksum of the MD5 of this host.
        /// The next 1 character is a reserved constant of 36 ('Z' in Base36).
        /// The last 3 characters are random number less than 46655 additional for additional uniqueness.
        /// </summary>
        /// <param name="delimiter">If provided, formats the ID as four groups of
        /// 4 characters separated by the delimiter.</param>
        /// <returns>Returns a unique, sequential, 16-character Base36 string</returns>
        public static string NewBase36String(string delimiter)
        {
            // For 10 chars from timestamp, microseconds since InService, uses Stopwatch...
            long microseconds = initStaticsReturnMicroseconds();

            // For 2 chars from host id MD5...
            string hostHash = (_hostHash ?? (_hostHash = ComputeHostHash()));

            // 1 reserved char; static largest base36 digit.
            // If the same ID system, scheme and sequence is still in use
            // more than 115.85 years after in-service date, decrements
            // 'reserved' by 1 for each whole multiple of 115 years
            // elapsed, up to 35 times max. If the same system, scheme
            // and sequence is still in service 3,850 years from the
            // initial go-live, you probably have bigger problems than
            // ID collisions...
            int reserved = _reserved;

            // 3 chars random in Base36 = 46656 units
            string        rndHexStr = getRandomDigits();
            StringBuilder sb        = new StringBuilder();

            sb.Append(Base36Converter.FromInt64(microseconds).PadLeft(10, '0'));
            sb.Length = 10;
            sb.Append(hostHash.PadLeft(2, '0'));
            sb.Length = 12;
            sb.Append(Base36Converter.FromInt32(reserved));
            sb.Length = 13;
            sb.Append(Base36Converter.FromHex(rndHexStr).PadLeft(3, '0'));
            sb.Length = 16;
            if (!string.IsNullOrEmpty(delimiter))
            {
                sb.Insert(12, delimiter);
                sb.Insert(8, delimiter);
                sb.Insert(4, delimiter);
            }
            return(sb.ToString());
        }