在 C++ 中生成唯一 ID 的算法?

发布于 2024-08-17 01:38:11 字数 51 浏览 2 评论 0原文

在 C++ 中生成唯一 id 的最佳算法是什么? 长度 ID 应为 32 位无符号整数。

What can be the best algorithm to generate a unique id in C++?
The length ID should be a 32 bit unsigned integer.

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

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

发布评论

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

评论(6

ゝ杯具 2024-08-24 01:38:11

获取唯一的 32 位 ID 直观上很简单:下一个。工作 40 亿次。 136 年来独一无二,如果您需要一秒钟。问题在于细节:前一个是什么?您需要一种可靠的方法来保留上次使用的值,并需要一种原子的方法来更新它。

这有多困难取决于 ID 的范围。如果它是一个进程中的一个线程,那么您只需要一个文件。如果一个进程中有多个线程,那么您需要一个文件和一个互斥体。如果一台机器上有多个进程,那么您需要一个文件和一个命名互斥体。如果是多台机器上的多个进程,那么您需要分配一个权威 ID 提供者,即所有机器都与之通信的单个服务器。数据库引擎是这样的常见提供商,它们内置了一个功能,即自动增量列。

随着范围的扩大,获取 ID 的费用逐渐增加。当它变得不切实际时,范围是互联网或提供商太慢或不可用,那么您需要放弃 32 位值。切换到随机值。随机性足以使机器被流星击中的可能性比重复相同 ID 的可能性至少高出一百万倍。一个好ID。它只有 4 倍大。

Getting a unique 32-bit ID is intuitively simple: the next one. Works 4 billion times. Unique for 136 years if you need one a second. The devil is in the detail: what was the previous one? You need a reliable way to persist the last used value and an atomic way to update it.

How hard that will be depends on the scope of the ID. If it is one thread in one process then you only need a file. If it is multiple threads in one process then you need a file and a mutex. If is multiple processes on one machine then you need a file and a named mutex. If it is multiple processes on multiple machines then you need to assign a authoritative ID provider, a single server that all machines talk to. A database engine is a common provider like that, they have this built-in as a feature, an auto-increment column.

The expense of getting the ID goes progressively up as the scope widens. When it becomes impractical, scope is Internet or provider too slow or unavailable then you need to give up on a 32-bit value. Switch to a random value. One that's random enough to make the likelihood that the machine is struck by a meteor is at least a million times more likely than repeating the same ID. A goo-ID. It is only 4 times as large.

勿忘初心 2024-08-24 01:38:11

这是我能想到的最简单的ID。

MyObject obj;
uint32_t id = reinterpret_cast<uint32_t>(&obj);

在任何给定时间,该 ID 在整个应用程序中都是唯一的。同一地址不会有其他对象。当然,如果重新启动应用程序,该对象可能会被分配一个新的ID。一旦对象的生命周期结束,另一个对象可能会被分配相同的 ID。

不同内存空间(例如,不同计算机上)中的对象可能会被分配相同的 ID。

最后但并非最不重要的一点是,如果指针大小大于 32 位,则映射将不是唯一的。

但由于我们对您想要什么样的 ID 以及它应该有多独特一无所知,因此这似乎是一个很好的答案。

Here's the simplest ID I can think of.

MyObject obj;
uint32_t id = reinterpret_cast<uint32_t>(&obj);

At any given time, this ID will be unique across the application. No other object will be located at the same address. Of course, if you restart the application, the object may be assigned a new ID. And once the object's lifetime ends, another object may be assigned the same ID.

And objects in different memory spaces (say, on different computers) may be assigned identical IDs.

And last but not least, if the pointer size is larger than 32 bits, the mapping will not be unique.

But since we know nothing about what kind of ID you want, and how unique it should be, this seems as good an answer as any.

南烟 2024-08-24 01:38:11

您可以看到这个。 (我认为完整的答案位于 Stack Overflow 上。)
此站点中有关 Linux 中 C++ 中唯一 id 的一些注释。您可以在 Linux 中使用 uuid,请参阅此人页面和示例。 。

如果您使用 Windows 并需要 Windows API,请参阅此 MSDN 页面

此维基百科页面也很有用:http://en .wikipedia.org/wiki/Universally_Unique_Identifier

You can see this. (Complete answer, I think, is on Stack Overflow.)
Some note for unique id in C++ in Linux in this site. And you can use uuid in Linux, see this man page and sample for this.

If you use windows and need windows APIs, see this MSDN page.

This Wikipedia page is also useful: http://en.wikipedia.org/wiki/Universally_Unique_Identifier.

倒带 2024-08-24 01:38:11
DWORD uid = ::GetTickCount();
::Sleep(100);
DWORD uid = ::GetTickCount();
::Sleep(100);
本王不退位尔等都是臣 2024-08-24 01:38:11

如果您有能力使用 Boost,那么有一个 UUID 库应该可以解决这个问题。使用起来非常简单 - 查看文档和此答案

If you can afford to use Boost, then there is a UUID library that should do the trick. It's very straightforward to use - check the documentation and this answer.

久夏青 2024-08-24 01:38:11

上下文很少,但如果您正在为应用程序中的对象寻找唯一 ID,您始终可以使用类似于以下的单例方法,

class IDGenerator {
   public:
      static IDGenerator * instance ();
      uint32_t next () { return _id++; }
   private:
      IDGenerator () : _id(0) {}

      static IDGenerator * only_copy;
      uint32_t _id;
}

IDGenerator *
IDGenerator::instance () {
   if (!only_copy) {
      only_copy = new IDGenerator();
   }
   return only_copy;
}

现在您可以通过执行以下操作随时获取唯一 ID:

IDGenerator::instance( )->下一个()

There is little context, but if you are looking for a unique ID for objects within your application you can always use a singleton approach similar to

class IDGenerator {
   public:
      static IDGenerator * instance ();
      uint32_t next () { return _id++; }
   private:
      IDGenerator () : _id(0) {}

      static IDGenerator * only_copy;
      uint32_t _id;
}

IDGenerator *
IDGenerator::instance () {
   if (!only_copy) {
      only_copy = new IDGenerator();
   }
   return only_copy;
}

And now you can get a unique ID at any time by doing:

IDGenerator::instance()->next ()

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