Skip to content

Instantly share code, notes, and snippets.

@cajuncoding
Last active June 8, 2023 06:15
Show Gist options
  • Save cajuncoding/9d11518e388082e0520676012bb94f5e to your computer and use it in GitHub Desktop.
Save cajuncoding/9d11518e388082e0520676012bb94f5e to your computer and use it in GitHub Desktop.
A simple, relatively efficient, class for generating very unique Ids of arbitrary length.
using System;
using System.Linq;
using System.Text;
namespace CajunCoding.UniqueIds
{
/// <summary>
/// BBernard / CajunCoding
/// A simple, relatively efficient, class for generating very unique Ids of arbitrary length.
/// They are not guaranteed to universally unique but the risk of collisions is of no practical implication for many uses
/// (e.g. temporary names, copied names, etc.).
/// With the ability to control the length (longer lengths will be more unique) it becomes suitable for many use cases
/// where a full GUID is simply too long.
/// NOTE: Inspired by the Stack Overflow Answer here: https://stackoverflow.com/a/44960751/7293142
/// The Original author claims 0.001% duplicates in 100 million.
/// </summary>
public static class TokenIdGenerator
{
private static readonly string[] AllCharsArray = Enumerable
//Start with the Full Uppercase Alphabet (26 chars) starting at 'A'
.Range(65, 26).Select(e => ((char)e).ToString())
//Append Full Lowercase Alphabet (26 chars) starting at 'a'
.Concat(Enumerable.Range(97, 26).Select(e => ((char)e).ToString()))
//Append Integer values 0-9
.Concat(Enumerable.Range(0, 10).Select(e => e.ToString()))
.ToArray();
private static readonly string AllCharsString = string.Join(string.Empty, AllCharsArray);
/// <summary>
/// Generates a unique short ID that can be much smaller than a GUID while being very unique --
/// but still not 100% unique because neither is a GUID. It may also be much longer makint it
/// highly unique and far more alphanumerically complex than GUIDs.
/// </summary>
/// <returns></returns>
public static string NewTokenId(int length = 10)
{
var stringBuilder = new StringBuilder();
var charsArray = (length <= AllCharsArray.Length)
? AllCharsArray
: Enumerable
.Repeat(AllCharsString, (int)Math.Ceiling((decimal)length / AllCharsString.Length))
.SelectMany(s => s)
.Select(c => c.ToString())
.ToArray();
charsArray
//Randomize by Sorting on Completely Unique GUID values (that change with every request);
// effectively deriving the uniqueness from GUIDs!
.OrderBy(c => Guid.NewGuid())
.Take(length)
.ToList()
.ForEach(e => stringBuilder.Append(e));
var tokenId = stringBuilder.ToString();
return tokenId;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment