如何为实体创建唯一的 7 位数代码?

发布于 2024-08-21 01:40:01 字数 435 浏览 0 评论 0原文

当用户在我的系统中添加新项目时,我想为该项目生成一个唯一的非递增伪随机 7 位代码。创建的项目数量仅为数千(<10,000)。

因为它需要是唯一的,并且没有两个项目会具有相同的信息,所以我可以使用哈希值,但它需要是他们可以与其他人共享的代码 - 因此是 7 位数字。

我最初的想法只是循环生成一个随机数,检查它是否尚未使用,如果已使用,则冲洗并重复。我认为,考虑到发生碰撞的可能性很低,这是一个合理但令人不快的解决方案。

此问题的回复建议生成所有未使用号码的列表并打乱它们。我可能可以在数据库中保留这样的列表,但我们谈论的是相对不常见的 10,000,000 个条目。

有人有更好的方法吗?

When a user adds a new item in my system, I want to produce a unique non-incrementing pseudo-random 7-digit code for that item. The number of items created will only number in the thousands (<10,000).

Because it needs to be unique and no two items will have the same information, I could use a hash, but it needs to be a code they can share with other people - hence the 7 digits.

My original thought was just to loop the generation of a random number, check that it wasn't already used, and if it was, rinse and repeat. I think this is a reasonable if distasteful solution given the low likelihood of collisions.

Responses to this question suggest generating a list of all unused numbers and shuffling them. I could probably keep a list like this in a database, but we're talking 10,000,000 entries for something relatively infrequent.

Does anyone have a better way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

时光匆匆的小流年 2024-08-28 01:40:01

选择一个 7 位质数数字A,和一个大质数数字B,以及

int nth_unique_7_digit_code(int n) {
    return (n * B) % A;
}

所有唯一数字的计数由此生成的代码将为A

如果你想更“安全”,请执行 pow(some_prime_number, n) % A,即

static int current_code = B;
int get_next_unique_code() {
   current_code = (B * current_code) % A;
   return current_code;
}

Pick a 7-digit prime number A, and a big prime number B, and

int nth_unique_7_digit_code(int n) {
    return (n * B) % A;
}

The count of all unique codes generated by this will be A.

If you want to be more "secure", do pow(some_prime_number, n) % A, i.e.

static int current_code = B;
int get_next_unique_code() {
   current_code = (B * current_code) % A;
   return current_code;
}
我不咬妳我踢妳 2024-08-28 01:40:01

您可以使用递增 ID,然后将其与某个固定键进行异或。

const int XORCode = 12345;

private int Encode(int id)
{
    return id^XORCode;
}

private int Decode(int code)
{
    return code^XORCode;
}

You could use an incrementing ID and then XOR it on some fixed key.

const int XORCode = 12345;

private int Encode(int id)
{
    return id^XORCode;
}

private int Decode(int code)
{
    return code^XORCode;
}
够钟 2024-08-28 01:40:01

老实说,如果您只想生成几千个 7 位代码,而有 1000 万个不同的代码可用,我认为只需生成一个随机代码并检查碰撞就足够了。

在最坏的情况下,第一次命中发生冲突的可能性约为千分之一,并且生成新的 7 位代码并再次检查冲突的计算工作量将比保留一个新的代码小得多。字典或类似的解决方案。

使用 GUID 而不是 harryovers 建议的 7 位数代码当然也可行,但当然 GUID 对于用户来说会稍微难记一些。

Honestly, if you want to generate only a couple of thousand 7-digit codes, while 10 million different codes will be available, I think just generating a random one and checking for a collision is good enough.

The chance of a collision on the first hit will be, in the worst case scenario, about 1 in a thousand, and the computational effort to just generate a new 7-digit code and check for a collision again will be much smaller than keeping a dictionary, or similar solutions.

Using a GUID instead of a 7-digit code as harryovers suggested will also certainly work, but of course a GUID will be slightly harder to remember for your users.

秋心╮凉 2024-08-28 01:40:01

我建议使用 guid 而不是 7 位代码,因为它会更加独特,而且您不必担心生成它们,因为 .NET 会为您完成此操作。

i would suggest using a guid instead of a 7 digit code as it will be more unique and you don't have to worry about generateing them as .NET will do this for you.

随心而道 2024-08-28 01:40:01

“唯一”ID 的所有解决方案都必须在某处有一个数据库:要么包含已用 ID,要么包含空闲 ID。正如您所注意到的,具有免费 ID 的数据库会非常大,因此人们通常会使用“已用 ID”数据库并检查冲突。

也就是说,一些数据库提供了“随机 ID”生成器/序列,它已经以随机顺序返回一定范围内的 ID。

这是通过使用随机数生成器来实现的,该随机数生成器可以创建一个范围内的所有数字而无需重复自身,并且还可以将其状态保存在某处。因此,您要做的就是运行生成器一次,使用 ID 并保存新状态。对于下一次运行,您加载状态并将生成器重置为最后一个状态以获取下一个随机 ID。

All solutions for a "unique" ID must have a database somewhere: Either one which contains the used IDs or one with the free IDs. As you noticed, the database with free IDs will be pretty big so most often, people use a "used IDs" database and check for collisions.

That said, some databases offer a "random ID" generator/sequence which already returns IDs in a range in random order.

This works by using a random number generator which can create all numbers in a range without repeating itself plus the feature that you can save it's state somewhere. So what you do is run the generator once, use the ID and save the new state. For the next run, you load the state and reset the generator to the last state to get the next random ID.

树深时见影 2024-08-28 01:40:01

我假设您将拥有一个生成的表格。在这种情况下,我认为选择随机数并根据数据库检查它们没有问题,但我不会单独这样做。生成它们很便宜,相对而言,执行数据库查询则很昂贵。我会一次生成 100 或 1,000 个,然后询问数据库其中存在哪一个。我敢打赌,大多数时候你不需要做两次。

I assume you'll have a table of the generated ones. In that case, I don't see a problem with picking random numbers and checking them against the database, but I wouldn't do it individually. Generating them is cheap, doing the DB query is expensive relative to that. I'd generate 100 or 1,000 at a time and then ask the DB which of those exists. Bet you won't have to do it twice most of the time.

何以心动 2024-08-28 01:40:01

您拥有 <10.000 件商品,因此您只需 4 位数字即可存储所有商品的唯一编号。
因为你有 7 位数字,所以你还有 3 位数字。

如果将 4 位数的唯一序列号与 3 位数的随机数组合起来,您将是唯一且随机的。您生成的每个新 ID 都会增加序列号。

您可以按任意顺序附加它们,也可以混合它们。

序列 = abcd,
rnd = ABC

您可以创建以下 ID:

  • abcdABC
  • ABCabcd
  • aAbBcCd

如果您仅使用一种混合算法,您将拥有唯一的数字,看起来是随机的。

You have <10.000 items, so you need only 4 digits to store a unique number for all items.
Since you have 7 digits, you have 3 digits extra.

If you combine a unique sequence number of 4 digits with a random number of 3 digits, you will be unique and random. You increment the sequence number with every new ID you generate.

You can just append them in any order, or mix them.

seq = abcd,
rnd = ABC

You can create the following ID's:

  • abcdABC
  • ABCabcd
  • aAbBcCd

If you use only one mixing algorithm, you will have unique numbers, that look random.

浪漫之都 2024-08-28 01:40:01

我会尝试使用 LFSR(线性反馈移位寄存器),代码非常简单,您可以随处找到示例,即 维基百科,尽管它不是加密安全的,但它看起来非常随机。此外,由于它主要使用移位操作,因此实现速度会非常快。

I would try to use an LFSR (Linear feedback shift register) the code is really simple you can find examples everywhere ie Wikipedia and even though it's not cryptographically secure it looks very random. Also the implementation will be very fast since it's using mainly shift operations.

风轻花落早 2024-08-28 01:40:01

由于数据库中只有数千个项目,您最初的想法似乎很合理。检查数万个项目的排序(索引)列表中是否存在某个值只需要几次数据获取和比较。

预先生成列表听起来不是一个好主意,因为您要么存储的数字超出所需的数量,要么不得不处理耗尽它们的情况。

With only thousands of items in the database, your original idea seems sound. Checking the existance of a value in a sorted (indexed) list of a few tens of thousands of items would only require a few data fetches and comparisons.

Pre-generating the list doesn't sound like a good idea, because you will either store way more numbers than are necessary, or you will have to deal with running out of them.

暖阳 2024-08-28 01:40:01

命中的概率非常低。
例如 - 您有 10^4 个用户和 10^7 个可能的 ID。
您在行中选择使用过的 ID 10 次的概率现在为 10^-30。
对于任何人来说,这种机会一生只有一次。

Probability of having hits is very low.
For instance - you have 10^4 users and 10^7 possible IDs.
Probability that you pick used ID 10 times in row is now 10^-30.
This chance is lower than once in a lifetime of any person.

开始看清了 2024-08-28 01:40:01

好吧,您可以要求用户选择自己的 7 位数字,并根据现有号码(您将在用完时存储的号码)进行验证,但我怀疑您会过滤大量 1234567、7654321、9999999、7777777 类型的响应,可能需要一些正则表达式来实现过滤,此外,您还必须警告用户注意此类序列,以免获得糟糕的、重复的用户输入体验。

Well, you could ask the user to pick their own 7-digit number and validate it against the population of existing numbers (which you would have stored as they were used up), but I suspect you would be filtering a lot of 1234567, 7654321, 9999999, 7777777 type responses and might need a few RegExs to achieve the filtering, plus you'd have to warn the user against such sequences in order not to have a bad, repetitive, user input experience.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文