システムで一意なID文字列を生成する
以前のエントリで任意の文字列に対応するID値を生成する方法について言及したが、今度はシステムで一意な文字列を取得する必要が出てきた。
最初は軽く考えて以下のように書いた。System.DateTime#Ticksは100ナノ秒単位で値を取れるので、あまりヘビーでは無い要件からして普通に使う分にはこれで充分だと思ったのだ。(今考えるとちょっと恥ずかしい)
public static string GetUniqueHex() { return Convert.ToString(System.DateTime.Now.Ticks, 16); }
しかし実際に使ってみるとこれが簡単に重複する。
いろいろ調べたがどうもネームスペースからして実装を推測するとTicksは現在の日時を数値に変換しているだけでいわゆる「高解像度タイマ」を使っているわけでは無いようだ。(タイマが高解像度ならば重複しない訳ではない)
アプリケーション中だけで一意で良いのであればObject#GetHashCode().ToString()の戻り値でも良いのだろうが、今回はあくまで「システム中で一意」なので使えない。 -> RegisterHotKeyとObject.GetHashCode (その2)
ならば以下のリンクのようにパフォーマンスカウンタの高解像度タイマーを取得する手もあるが、
How to use QueryPerformanceCounter to time code in Visual Basic .NET or in Visual Basic 2005
どうも大袈裟な気もする。
取りあえずはGUIDに対応したクラス System.Guidクラスを使用してみた。
public static string GetUniqueHex() { Guid guid = Guid.NewGuid(); StringBuilder sb = new StringBuilder(); byte[] bytes = guid.ToByteArray(); foreach (Byte b in bytes) { sb.AppendFormat("{0:x2}", b); } return sb.ToString(); }
Ticksを用いるのと違ってより確実ではあるが最適解では無いような気もするな。