web-dev-qa-db-ja.com

C ++で一意のIDを生成するアルゴリズム?

C++で一意のIDを生成するための最良のアルゴリズムは何ですか?長さIDは32ビットの符号なし整数である必要があります。

29
Ajay

一意の32ビットIDを取得することは直感的に簡単です。次のIDです。 40億回動作します。 1秒ごとに必要な場合は136年間ユニークです。悪魔は詳細にあります:前のものは何でしたか?最後に使用した値を永続化する信頼できる方法と、それを更新するアトミックな方法が必要です。

それがどれだけ難しいかは、IDのスコープに依存します。それが1つのプロセスの1つのスレッドである場合は、ファイルのみが必要です。 1つのプロセスに複数のスレッドがある場合、ファイルとミューテックスが必要です。 1台のマシンに複数のプロセスがある場合、ファイルと名前付きミューテックスが必要です。複数のマシン上の複数のプロセスである場合、すべてのマシンが通信する単一のサーバーである信頼できるIDプロバイダーを割り当てる必要があります。データベースエンジンはそのような一般的なプロバイダーであり、この組み込みの機能として自動インクリメント列があります。

IDを取得するための費用は、範囲が広がるにつれて徐々に増加します。実用的ではない場合、スコープはインターネットまたはプロバイダーが遅すぎるか利用できないため、32ビット値を放棄する必要があります。ランダムな値に切り替えます。機械が流星にぶつかる可能性を作るのに十分にランダムなものは、同じIDを繰り返すより少なくとも100万倍高い可能性があります。グーID。わずか4倍の大きさです。

56
Hans Passant

ここに私が考えることができる最も単純なIDがあります。

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

いつでも、このIDはアプリケーション全体で一意になります。他のオブジェクトは同じアドレスに配置されません。もちろん、アプリケーションを再起動すると、オブジェクトに新しいIDが割り当てられる場合があります。オブジェクトの存続期間が終了すると、別のオブジェクトに同じIDが割り当てられる場合があります。

また、異なるメモリ空間(たとえば、異なるコンピューター)のオブジェクトには、同一のIDが割り当てられます。

最後になりましたが、ポインターサイズが32ビットより大きい場合、マッピングは一意ではありません。

しかし、私たちはあなたがどんな種類のIDを望んでいるか、そしてそれがどれほどユニークであるべきかについて何も知らないので、これは他と同じくらい良い答えのようです。

11
jalf

this が表示されます。 (完全な答えは、スタックオーバーフローに関するものだと思います。)
このサイト のLinuxのC++の一意のIDに関する注意Linuxでuuidを使用できます。これについては ページとサンプル をご覧ください。

Windowsを使用していて、Windows APIが必要な場合は、この MSDNページ を参照してください。

このウィキペディアのページも便利です: http://en.wikipedia.org/wiki/Universally_Unique_Identifier

7
Sajad Bahmani
DWORD uid = ::GetTickCount();
::Sleep(100);
1
an0nym0usc0ward

Boostを使用する余裕がある場合は、 [〜#〜] uuid [〜#〜] トリックを実行するライブラリがあります。使い方は非常に簡単です-ドキュメントと この回答 を確認してください。

0
Sahib Yar