需要处理> 1000但是<每天10000条新记录
无法使用GUID / UUID,自动递增数字等。
理想情况下应该是5或6个字符长,当然可以是字母
想重用现有的,众所周知的算法(如果有的话)
还有什么吗?
答案 0 :(得分:95)
baseurl和bit.ly用于缩写的URL。这是一种易于理解的方法,用于创建“独特的”人类可读ID。 当然,您必须存储创建的ID并在创建时检查重复项以确保唯一性。 (请参阅答案底部的代码)
基本62唯一性指标
基地62中的5个字符将为您提供62 ^ 5个唯一ID = 916,132,832(~10亿) 每天10k ID,你可以获得91k +天
基础62中的6个字符将为您提供62 ^ 6个唯一ID = 56,800,235,584(56亿以上) 每天10k ID,您可以获得超过500万天基本36个唯一性指标
6个字符将为您提供36 ^ 6个唯一ID = 2,176,782,336(2亿个)
7个字符将为您提供36 ^ 7个唯一ID = 78,364,164,096(780亿)
<强>代码:强>
public void TestRandomIdGenerator()
{
// create five IDs of six, base 62 characters
for (int i=0; i<5; i++) Console.WriteLine(RandomIdGenerator.GetBase62(6));
// create five IDs of eight base 36 characters
for (int i=0; i<5; i++) Console.WriteLine(RandomIdGenerator.GetBase36(8));
}
public static class RandomIdGenerator
{
private static char[] _base62chars =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
.ToCharArray();
private static Random _random = new Random();
public static string GetBase62(int length)
{
var sb = new StringBuilder(length);
for (int i=0; i<length; i++)
sb.Append(_base62chars[_random.Next(62)]);
return sb.ToString();
}
public static string GetBase36(int length)
{
var sb = new StringBuilder(length);
for (int i=0; i<length; i++)
sb.Append(_base62chars[_random.Next(36)]);
return sb.ToString();
}
}
<强>输出:强>
z5KyMg wd4SUp uSzQtH UPrGAT UIf2IS QCF9GNM5 0UV3TFSS 3MG91VKP 7NTRF10T AJK3AJU7
答案 1 :(得分:14)
我建议将http://hashids.org/转换为字符串(使用salt)。
它允许将此字符串解码回数字。因此您不需要将其存储在数据库中。
包含JavaScript,Ruby,Python,Java,Scala,PHP,Perl,Swift,Clojure,Objective-C,C,C ++ 11,Go,Erlang,Lua,Elixir,ColdFusion,Groovy,Kotlin,Nim的库,VBA,CoffeeScript和Node.js&amp; .NET。
答案 2 :(得分:6)
我有与OP相似的要求。我查看了可用的库,但大多数是基于随机性,我不想要它。我真的找不到任何基于随机而且仍然很短的东西...所以我最终根据the technique Flickr uses滚动自己,但修改为需要较少的协调并允许更长时间离线。
简而言之:
缺点:
优点
我已经为客户端发布了一个Javascript库,以及一个Java EE服务器实现。用其他语言实现服务器也应该很容易。
以下是项目:
suid - 分布式服务 - 短而甜的唯一ID
suid-server-java - Java EE技术堆栈的Suid服务器实现。
这两个库都可以在自由的Creative Commons开源许可下使用。 希望这可以帮助其他人寻找简短的唯一ID。
答案 3 :(得分:3)
当我为几年前开发的应用程序解决了这个问题时,我使用了 base 36 。我需要生成人类可读的合理唯一数字(无论如何在当前日历年内)。我选择使用从当年1月1日午夜开始的时间(因此每年,时间戳可以重复)并将其转换为基数为36的数字。如果正在开发的系统遇到致命问题,它会生成通过Web界面向最终用户显示的基本36号码(7个字符),然后可以将遇到的问题(和号码)转发给技术支持人员(谁然后可以使用它来查找堆栈跟踪开始的日志中的点)。对于用户来说,像 56af42g7 这样的数字比 2016-01-21T15:34:29.933-08:00 或随机UUID等时间戳更容易阅读和中继的 5f0d3e0c-da96-11e5-b5d2-0a1d41d68578 强>
答案 4 :(得分:0)
我真的很喜欢仅使用Base64格式编码GUID并截断尾随==以获得22个字符的字符串的简便性(它需要一行代码,并且您始终可以将其转换回GUID)。 可悲的是,它有时包含+和/字符。对于数据库来说还可以,对于URL来说不是很好,但是它帮助我理解了其他答案:-)
摘自Christiaan van Bergen的https://www.codeproject.com/Tips/1236704/Reducing-the-string-Length-of-a-Guid
我们发现将Guid(16字节)转换为ASCII 使用Base64表示法会导致可用且仍然唯一 messageID仅22个字符。
var newGuid = Guid.NewGuid();
var messageID = Convert.ToBase64String(newGuid.ToByteArray());
var message22chars = Convert.ToBase64String(Guid.NewGuid().ToByteArray()).Substring(0,22);
例如:Guid'e6248889-2a12-405a-b06d-9695b82c0a9c'(字符串 长度:36)将获得Base64表示形式: 'iYgk5hIqWkCwbZaVuCwKnA =='(字符串长度:24)
Base64表示形式以'=='字符结尾。你可以 只需将它们截断,而不会影响唯一性。离开你 标识符只有22个字符。