Aar*_*ght 8 language-agnostic algorithm unique uniqueidentifier
我发现了许多关于生成UID的不同问题,但据我所知,我的要求有点独特(ha).
总结一下:我需要生成一个非常短的ID,它是"本地"唯一的,但不必是"全局"或"普遍"唯一的.约束不仅仅基于美学或空间问题,而是由于这实际上被用作硬件标签,并且这受到硬件约束的约束.以下是规格:
我知道可以使用少于12个十进制数字将时间戳编码为100 ms甚至10 ms精度,这足以保证此应用程序的"足够唯一"ID.我在这里问这个问题的原因是因为我真的想要尝试在那里加入人类可读的年/月或编码关于源机器的一些信息,或两者兼而有之.
我希望有人可以帮助在这些软性要求上做出妥协......或者解释为什么在给出其他要求的情况下它们都不可能.
(PS我的"原生"语言是C#,但如果有人有任何好主意,任何语言或甚至伪代码的代码都可以.)
更新:
既然我已经有机会在它上面睡觉了,我想我实际上要做的是默认使用时间戳编码,并允许单个安装通过定义自己的2或者切换到机器顺序ID 3位机器ID.这样,想要弄乱ID并打包在人类可读信息中的客户可以找出他们自己确保唯一性的方法,我们对滥用不负责任.也许我们通过提供服务器实用程序来帮助处理机器ID,如果它们碰巧正在进行所有在线安装.
怎么样yyMMddhhmmID
?
yy = two-digit year
MM = two-digit month
dd = two-digit day
hh = two-digit hour (24-hour time)
mm = two-digit minute
ID = machine-specific ID
Run Code Online (Sandbox Code Playgroud)
示例:0912113201
来自带有ID = 01
.
或者(如果你不喜欢两位数的年份(Y2K 哈哈)),怎么样yyyyMMIDxxxx
?
yyyy = four-digit year
MM = two-digit month
ID = machine-specific ID
xxxx = sequentially-incremented integer
Run Code Online (Sandbox Code Playgroud)
示例:200912010001
来自带有ID = 01
.
正如您所说,每台机器每五分钟最多只会生成一个标识符,这为您每月提供了 8,928 (24 * 31 * 60 / 5 = 8928) 个标识符的空间,这将适合xxxx
. 如果您需要序列或机器 IDyyy
中的额外数字,则可以将年份压缩为三位数年份(例如 009)。xxxx
这两个都符合您要求的时间戳/机器 ID。
我们都喜欢具体的代码:
class Machine {
public int ID { get; private set; }
public Machine(int id) {
ID = id;
}
}
class IdentifierGenerator {
readonly Machine machine;
int seed;
const int digits = 4;
readonly int modulus;
readonly string seedFormat;
public IdentifierGenerator(Machine machine) {
this.machine = machine;
this.modulus = (int)Math.Pow(10, digits);
this.seedFormat = new string('0', digits);
}
public string Generate() {
string identifier = DateTime.Now.ToString("yyyyMM")
+ machine.ID.ToString("00")
+ seed.ToString(seedFormat);
seed = (seed + 1) % modulus;
return identifier;
}
}
Machine m = new Machine(1);
IdentifierGenerator gen = new IdentifierGenerator(m);
Console.WriteLine(gen.Generate());
Console.WriteLine(gen.Generate());
Run Code Online (Sandbox Code Playgroud)
输出:
200912010000
200912010001
Run Code Online (Sandbox Code Playgroud)