/// <summary>
        /// Get a Base36 encoded timestamp string, based on Epoch. Use for disposable
        /// strings where global/universal uniqueness is not critical. If using the
        /// default resolution of Microseconds, 5 character values are exhausted in 1 minute.
        /// 6 characters = ½ hour. 7 characters = 21 hours. 8 characters = 1 month.
        /// 9 characters = 3 years. 10 characters = 115 years. 11 characters = 4170 years.
        /// 12 characteres = 150 thousand years.
        /// </summary>
        /// <param name="length"></param>
        /// <param name="resolution"></param>
        /// <param name="sinceUtc">Defaults to Epoch</param>
        /// <param name="strict">If false (default), overflow values will use the
        /// value modulus 36. Otherwise it will throw an overflow exception.</param>
        /// <returns></returns>
        public string GetTimestamp(int length, TimestampResolution resolution = TimestampResolution.Microsecond, DateTime?sinceUtc = null, bool strict = false)
        {
            if (length < 1 || length > 12)
            {
                throw new ArgumentOutOfRangeException(nameof(length), "Length must be between 1 and 12; 36^13 overflows Int64.MaxValue");
            }
            var  origin  = sinceUtc ?? _epoch;
            var  elapsed = DateTime.UtcNow.Subtract(origin);
            long intervals;

            switch (resolution)
            {
            case TimestampResolution.Day:
                intervals = elapsed.Days;
                break;

            case TimestampResolution.Hour:
                intervals = Convert.ToInt64(elapsed.TotalHours);
                break;

            case TimestampResolution.Minute:
                intervals = Convert.ToInt64(elapsed.TotalMinutes);
                break;

            case TimestampResolution.Second:
                intervals = Convert.ToInt64(elapsed.TotalSeconds);
                break;

            case TimestampResolution.Millisecond:
                intervals = Convert.ToInt64(elapsed.TotalMilliseconds);
                break;

            case TimestampResolution.Microsecond:
                intervals = (long)(elapsed.TotalMilliseconds * 1000.0);     // elapsed.TotalMicroseconds();
                break;

            case TimestampResolution.Ticks:
                intervals = elapsed.Ticks;
                break;

            case TimestampResolution.None:
            default:
                throw new ArgumentOutOfRangeException(nameof(resolution));
            }
            var combinations = Math.Pow(36, length);

            if (combinations < intervals)
            {
                if (strict)
                {
                    throw new OverflowException(string.Format("At resolution {0}, value is greater than {1}-character timestamps can express.", resolution.ToString(), length));
                }
                intervals = intervals % 36;
            }
            string encoded = Base36Converter.FromLong(intervals);

            return(encoded.Length > length?
                   encoded.Substring(0, length) :
                       encoded.PadLeft(length, '0'));
        }
        /// <summary>
        ///     Base36 representation of the SHA1 of the hostname. The constructor argument
        ///     numServerCharacters controls the maximum length of this hash.
        /// </summary>
        /// <returns>2 character Base36 checksum of MD5 of hostname</returns>
        public string ComputeHostHash()
        {
            string hostname = Dns.GetHostName();

            if (!hostname.HasValue())
            {
                hostname = Environment.MachineName;
            }
            string hashHex;

            using (var sha1 = new SHA1Managed())
            {
                hashHex = BitConverter.ToString(sha1.ComputeHash(Encoding.UTF8.GetBytes(hostname)));
                if (hashHex.Length > 14) // > 14 chars overflows int64
                {
                    hashHex = hashHex.Truncate(14);
                }
            }
            string hashBase36 = Base36Converter.FromHex(hashHex);

            if (hashBase36.Length > this._numServerCharacters)
            {
                hashBase36 = hashBase36.Truncate(this._numServerCharacters);
            }
            return(hashBase36);
        }
Ejemplo n.º 3
0
        public void EncodeTest()
        {
            Assert.Equal("0", Base36Converter.Encode(0));
            Assert.Equal("6TY", Base36Converter.Encode(8854));

            Assert.Equal("AQF8AA0006EH", 1412823931503067241.ToBase36());
        }
Ejemplo n.º 4
0
 public void DecodeTest()
 {
     Assert.Equal(0, Base36Converter.Decode(""));
     Assert.Equal(0, Base36Converter.Decode("0"));
     Assert.Equal(-1, Base36Converter.Decode("%"));
     Assert.Equal(1412823931503067241, Base36Converter.Decode("AQF8AA0006EH"));
 }
        /// <summary>
        ///     Base36 representation of the SHA1 of the hostname. The constructor argument
        ///     numServerCharacters controls the maximum length of this hash.
        /// </summary>
        /// <returns>2 character Base36 checksum of MD5 of hostname</returns>
        public string ComputeHostHash(string hostname = null)
        {
            if (_hostHashBase36?.Length == _numServerCharacters)
            {
                return(_hostHashBase36);
            }
            if (string.IsNullOrWhiteSpace(hostname))
            {
                hostname = Dns.GetHostName()
                           ?? Environment.MachineName;
            }
            string hashHex;

            using (var sha1 = System.Security.Cryptography.SHA1.Create())
            {
                hashHex = BitConverter.ToString(sha1.ComputeHash(Encoding.UTF8.GetBytes(hostname)));
                if (hashHex.Length > 14) // > 14 chars overflows int64
                {
                    hashHex = hashHex.Substring(0, 14);
                }
            }
            string hashBase36 = Base36Converter.FromHex(hashHex);

            return(_hostHashBase36 = hashBase36);
        }
Ejemplo n.º 6
0
 /// <summary>
 ///     This is not cross-process safe.
 /// </summary>
 /// <returns></returns>
 private string GetRandomDigitsLock()
 {
     // NOTE: Using a mutex would enable cross-process locking.
     lock (_randomLock)
     {
         long next = _rnd.NextLong(this._maxRandom);
         return(Base36Converter.Encode(next));
     }
 }
Ejemplo n.º 7
0
        public void Next_Base36_Decode_Test()
        {
            var snowflakeIdWorker = new SnowflakeIdWorker(1, 1);
            var nextId            = snowflakeIdWorker.NextId();
            var encode            = Base36Converter.Encode(nextId);
            var decode            = Base36Converter.Decode(encode);

            Console.WriteLine(encode);
            Assert.AreEqual(nextId, decode);
        }
 private string GetRandomBase36DigitsSafe()
 {
     lock (_randomLock)
     {
         long   number  = ConcurrentRandom.Random.NextLong(this._maxRandom);
         string encoded = Base36Converter.FromLong(number);
         return
             (encoded.Length == this._numRandomCharacters
                 ? encoded
                 : encoded.Length > this._numRandomCharacters
                     ? encoded.Substring(0, _numRandomCharacters)
                     : encoded.PadLeft(this._numRandomCharacters, '0'));
     }
 }
 /// <summary>
 ///     Gets random component of Id, pre trimmed and padded to the correct length.
 /// </summary>
 /// <returns></returns>
 private string GetRandomBase36DigitsSafe()
 {
     lock (_randomLock)
     {
         byte[] buffer = new byte[8];
         _random.NextBytes(buffer);
         var    number  = Math.Abs(BitConverter.ToInt64(buffer, 0) % this._maxRandom);
         string encoded = Base36Converter.FromLong(number);
         return
             (encoded.Length == this._numRandomCharacters
                 ? encoded
                 : encoded.Length > this._numRandomCharacters
                     ? encoded.Substring(0, _numRandomCharacters)
                     : encoded.PadLeft(this._numRandomCharacters, '0'));
     }
 }
 /// <summary>
 ///     Gets a random Base36 string of the specified <paramref name="length"/>.
 /// </summary>
 /// <returns></returns>
 public string GetRandomString(int length)
 {
     if (length < 1 || length > 12)
     {
         throw new ArgumentOutOfRangeException("length", "Length must be between 1 and 12; 36^13 overflows Int64.MaxValue");
     }
     lock (_randomLock)
     {
         var    maxRandom = (long)Math.Pow(36, length);
         long   random    = ConcurrentRandom.Random.NextLong(maxRandom);
         string encoded   = Base36Converter.FromLong(random);
         return(encoded.Length > length?
                encoded.Truncate(length) :
                    encoded.PadLeft(length, '0'));
     }
 }
 /// <summary>
 ///     Gets a random Base36 string of the specified <paramref name="length"/>.
 /// </summary>
 /// <returns></returns>
 public string GetRandomString(int length)
 {
     if (length < 1 || length > 12)
     {
         throw new ArgumentOutOfRangeException(nameof(length), "Length must be between 1 and 12; 36^13 overflows Int64.MaxValue");
     }
     lock (_randomLock)
     {
         var maxRandom = (long)Math.Pow(36, length);
         _random.NextBytes(_randomBuffer);
         var    random  = Math.Abs(BitConverter.ToInt64(_randomBuffer, 0) % maxRandom);
         string encoded = Base36Converter.FromLong(random);
         return(encoded.Length > length?
                encoded.Substring(0, length) :
                    encoded.PadLeft(length, '0'));
     }
 }
Ejemplo n.º 12
0
 /// <summary>
 ///     Gets random component of Id, pre trimmed and padded to the correct length.
 /// </summary>
 /// <returns></returns>
 private string GetRandomBase36DigitsSafe()
 {
     if (_randomMutex.WaitOne())
     {
         long   random  = _rnd.NextLong(this._maxRandom);
         string encoded = Base36Converter.FromInt64(random);
         try
         {
             return(encoded.Length > this._numRandomCharacters ?
                    encoded.Truncate(this._numRandomCharacters) :
                    encoded.PadLeft(this._numRandomCharacters, '0'));
         }
         finally
         {
             _randomMutex.ReleaseMutex();
         }
     }
     throw new AbandonedMutexException();
 }
        /// <summary>
        ///     Generates a unique, sequential, Base36 string; you control the len
        ///     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>
        /// <returns>Returns a unique, sequential, 16-character Base36 string</returns>
        public string NewId(bool delimited)
        {
            // Keep access sequential so threads cannot accidentally
            // read another thread's values within this method:

            // Microseconds since InService (using Stopwatch) provides the
            // first n chars (n = _numTimestampCharacters):
            lock (_sb)
            {
                _sb.Clear();
                long   microseconds       = ConcurrentStopwatch.GetMicroseconds();
                string base36Microseconds = Base36Converter.FromLong(microseconds);
                if (base36Microseconds.Length > this._numTimestampCharacters)
                {
                    base36Microseconds = base36Microseconds.Substring(0, this._numTimestampCharacters);
                }
                _sb.Append(base36Microseconds.PadLeft(this._numTimestampCharacters, '0'));

                if (_numServerCharacters > 0)
                {
                    _sb.Append(_hostHash.Substring(0, _numServerCharacters));
                }

                if (!string.IsNullOrWhiteSpace(this._reservedValue))
                {
                    _sb.Append(this._reservedValue);
                }
                // Add the random component:
                _sb.Append(GetRandomBase36DigitsSafe());

                if (!delimited || string.IsNullOrWhiteSpace(_delimiter) || this._delimiterPositions == null)
                {
                    return(_sb.ToString());
                }
                foreach (var pos in this._delimiterPositions)
                {
                    _sb.Insert(pos, this._delimiter);
                }
                return(_sb.ToString());
            }
        }
Ejemplo n.º 14
0
        private async void timer1_Tick(object sender, EventArgs e)
        {
            var entity = helper.getPlurks();

            PlurkContent     = "" + entity.plurks[0].content;
            PlurkQualifier   = "" + (entity.plurks[0].qualifier_translated != null ? entity.plurks[0].qualifier_translated : entity.plurks[0].qualifier);
            PlurkContent_raw = "" + entity.plurks[0].content_raw;
            PlurkName        = entity.plurk_users.First().Value.display_name;
            PlurkUserID      = entity.plurk_users.First().Key;
            PlurkID          = entity.plurks[0].plurk_id;
            PlurkUserPURL    = helper.getPublicProfile(PlurkUserID).user_info.avatar_big;
            plurkbase36      = (int)entity.plurks[0].plurk_id;
            string SRC = Base36Converter.ConvertTo(plurkbase36).ToLower();

            char[] ArraySRC = SRC.ToCharArray();
            Array.Reverse(ArraySRC);
            SRC      = new string(ArraySRC);
            PlurkURL = "https://www.plurk.com/p/" + SRC;

            if (PlurkContent.Contains("<img src="))
            {
                int    temp    = PlurkContent.IndexOf("<img src=") + 10;
                string strtemp = PlurkContent.Remove(0, temp);
                Url = strtemp.Substring(0, strtemp.IndexOf(textBox1.Text));
                if (Url.Contains("https://images.plurk.com/mx_"))
                {
                    Url = Url.Remove(Url.IndexOf("mx_"), 3);
                }
            }
            else
            {
                Url = "";
            }

            if (PlurkUserPURL != PUPURL)
            {
                PUPURL = PlurkUserPURL;
                await  SendMessage();
            }
        }
Ejemplo n.º 15
0
        public void TestSNPIDConversionToBase36()
        {
            // Berlin Orchestra Inspire
            var berlinInspire1 = Base36Converter.Encode(BERLIN_INSPIRE_1 - SNPID_CONST);

            Assert.Equal(BERLIN_INSPIRE_1_SNPID, berlinInspire1);

            // Berlin Orchestra Inspire 2
            var berlinInspire2 = Base36Converter.Encode(BERLIN_INSPIRE_2 - SNPID_CONST);

            Assert.Equal(BERLIN_INSPIRE_2_SNPID, berlinInspire2);

            // Metropolis Ark 3
            var metropolisArk3 = Base36Converter.Encode(METROPOLIS_ARK_3 - SNPID_CONST);

            Assert.Equal(METROPOLIS_ARK_3_SNPID, metropolisArk3);

            // Artist Series - Randys Prepared Piano
            var randysPreparedPiano = Base36Converter.Encode(RANDYS_PREPARED_PIANO - SNPID_CONST);

            Assert.Equal(RANDYS_PREPARED_PIANO_SNPID, randysPreparedPiano);
        }
        /// <summary>
        ///     Generates a unique, sequential, Base36 string; you control the len
        ///     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>
        /// <returns>Returns a unique, sequential, 16-character Base36 string</returns>
        public string NewId(bool delimited)
        {
            // Keep access sequential so threads cannot accidentally
            // read another thread's values within this method:
            var sb = new StringBuilder();

            // Microseconds since InService (using Stopwatch) provides the
            // first n chars (n = _numTimestampCharacters):
            lock (sb)
            {
                long   microseconds       = GetMicrosecondsSafe();
                string base36Microseconds = Base36Converter.FromLong(microseconds);
                if (base36Microseconds.Length > this._numTimestampCharacters)
                {
                    base36Microseconds = base36Microseconds.Truncate(this._numTimestampCharacters);
                }
                sb.Append(base36Microseconds.PadLeft(this._numTimestampCharacters, '0'));

                sb.Append(_hostHash);

                if (this._reservedValue.HasValue())
                {
                    sb.Append(this._reservedValue);
                    sb.Length += this._reservedValue.Length; // Truncates
                }
                // Add the random component:
                sb.Append(GetRandomBase36DigitsSafe());

                if (!delimited || !this._delimiter.HasValue() || !this._delimiterPositions.HasContents())
                {
                    return(sb.ToString());
                }
                foreach (var pos in this._delimiterPositions)
                {
                    sb.Insert(pos, this._delimiter);
                }
                return(sb.ToString());
            }
        }
Ejemplo n.º 17
0
        /// <summary>
        ///     Returns a random Base36 number 3 characters long.
        /// </summary>
        /// <returns></returns>
        private string GetRandomDigitsSpinLock()
        {
            long value;

            while (true)
            {
                bool lockTaken = false;
                try
                {
                    _locker.Enter(ref lockTaken);
                    value = _rnd.NextLong(this._maxRandom);
                    break;
                }
                finally
                {
                    if (lockTaken)
                    {
                        _locker.Exit(false);
                    }
                }
            }
            return(Base36Converter.Encode(value));
        }