C# Tips | 文字列処理:UUID生成

C# C#
スポンサーリンク

はじめに 「UUID生成」は“かぶらないIDを雑に、でも安全に作る”技

業務システムを作っていると、ほぼ必ず出てくるのが「一意なIDが欲しい」という場面です。
注文ID、トランザクションID、ファイル名、トークン、セッションキー…。

ここで頼りになるのが UUID(GUID) です。
C# では Guid 型として標準で用意されていて、「ほぼ絶対にかぶらないID」を一行で生成できる道具だと思ってください。

ここでは、初心者向けに、

UUID(GUID)とは何か
C# での基本的な生成方法
文字列としてのフォーマット("D", "N", "B" など)の違い
業務ユーティリティとしてどうラップすると使いやすいか

を、例題付きでかみ砕いて説明していきます。


UUID / GUID の基本をおさえる

UUID と GUID の違い(ざっくりでOK)

用語としては、

  • UUID(Universally Unique Identifier)
  • GUID(Globally Unique Identifier)

がありますが、C# の世界では Guid 型として実装されています。
ここでは「UUID = GUID = Guid」くらいの理解で大丈夫です。

重要なのは、「ほぼ絶対に重複しない128ビットのID」という性質です。
「乱数+時間+その他いろいろ」を組み合わせて作られるので、
普通の業務システムで「かぶったらどうしよう」と心配する必要はまずありません。

典型的な見た目

よく見る形式はこんな感じです。

550e8400-e29b-41d4-a716-446655440000

8桁-4桁-4桁-4桁-12桁 の16進数で構成されています。
これが「文字列としてのUUID」です。


C# での基本:Guid.NewGuid()

一番シンプルな生成方法

UUIDを生成するコードは、たったこれだけです。

using System;

Guid id = Guid.NewGuid();
Console.WriteLine(id);
C#

実行すると、例えばこんな感じの値が出ます。

550e8400-e29b-41d4-a716-446655440000

Guid.NewGuid() が「新しいUUIDを1つ作る」メソッドです。
これを呼ぶたびに、ほぼ絶対にかぶらない新しいIDが生成されます。

文字列として扱いたい場合

DBのキーやログに出したいときは、文字列にします。

Guid id = Guid.NewGuid();
string idString = id.ToString();

Console.WriteLine(idString); // 550e8400-e29b-41d4-a716-446655440000
C#

ToString() のデフォルトは "D" フォーマット(ハイフン付き)です。
この形が一番よく使われます。


フォーマットの違いを知っておく(”D”, “N”, “B”, “P”)

よく使うフォーマット4種類

Guid.ToString には、いくつかのフォーマット指定子があります。
よく使うのはこの4つです。

Guid id = Guid.NewGuid();

Console.WriteLine(id.ToString("D")); // 550e8400-e29b-41d4-a716-446655440000
Console.WriteLine(id.ToString("N")); // 550e8400e29b41d4a716446655440000
Console.WriteLine(id.ToString("B")); // {550e8400-e29b-41d4-a716-446655440000}
Console.WriteLine(id.ToString("P")); // (550e8400-e29b-41d4-a716-446655440000)
C#

ざっくりまとめると、

  • "D":ハイフン付き(デフォルト、よく見る形)
  • "N":ハイフンなし(32桁の16進数だけ)
  • "B"{} で囲む
  • "P"() で囲む

業務でよく使うのは "D""N" です。

どれを使うかの目安

ハイフン付き "D" は、人間が見て識別しやすいので、ログや画面表示に向いています。
ハイフンなし "N" は、ファイル名やURLパラメータ、キー文字列など、
「余計な記号を入れたくない」場面でよく使われます。

例えば、ファイル名に使うならこうです。

string fileName = Guid.NewGuid().ToString("N") + ".tmp";
// 例: 550e8400e29b41d4a716446655440000.tmp
C#

業務ユーティリティとしてラップする

「Guid.NewGuid() をそのまま書かない」メリット

小さなサンプルなら Guid.NewGuid() を直接書いてもいいのですが、
業務システムでは、ユーティリティクラスにまとめておくと後々楽です。

理由は、

  • フォーマットを一箇所で統一できる
  • テスト時に差し替えやすくなる(固定のIDを返すなど)
  • 「何のためのIDか」が名前から分かる

からです。

シンプルなユーティリティ例

using System;

public static class UuidUtil
{
    // ハイフン付き(デフォルト)UUID文字列
    public static string NewStringD()
    {
        return Guid.NewGuid().ToString("D");
    }

    // ハイフンなしUUID文字列
    public static string NewStringN()
    {
        return Guid.NewGuid().ToString("N");
    }

    // Guid 型そのものが欲しい場合
    public static Guid NewGuid()
    {
        return Guid.NewGuid();
    }
}
C#

使い方はこんな感じです。

string orderId = UuidUtil.NewStringN();   // 注文ID用にハイフンなし
string logId   = UuidUtil.NewStringD();   // ログ用にハイフン付き
Guid   rawId   = UuidUtil.NewGuid();      // DBのGuidカラム用
C#

「どの形式をどこで使うか」をユーティリティのメソッド名で表現しておくと、
呼び出し側のコードがかなり読みやすくなります。


UUIDを「キー」として使うときの考え方

連番IDとの違い

DBの主キーとして、よくある選択肢は、

  • 整数の連番(int / bigint
  • UUID(uniqueidentifier / char(36) など)

です。

UUIDのメリットは、

  • アプリ側だけで発行できる(DBに聞きに行かなくていい)
  • システムをまたいでもIDがかぶりにくい
  • 外部に漏れても「件数や順番」がバレにくい

といったところです。

一方で、

  • 文字列としては長い
  • インデックスのサイズが大きくなる
  • 人間が手入力するには向かない

というデメリットもあります。

「外部公開するID」「トレース用ID」「分散システム間で共有するID」などにはUUIDが向いています。
「内部だけで使う単純なテーブルの主キー」なら、連番でも十分です。

「見せるID」と「内部ID」を分けるのもアリ

実務では、

  • DBの主キーは連番
  • 外部に見せるID(URLやAPIレスポンス)はUUID

という二重構造にすることもよくあります。

例えば、

public class Order
{
    public long Id { get; set; }          // DB内部用の連番
    public string PublicId { get; set; }  // 外部公開用のUUID文字列
}
C#

PublicIdUuidUtil.NewStringN() を入れておけば、
URLに https://example.com/orders/550e8400e29b41d4a716446655440000 のように載せても、
内部の連番構造が外からは見えません。


UUIDをパースする・検証する

文字列から Guid に戻す

UUID文字列を受け取って Guid に戻したい場合は、Guid.Parse / Guid.TryParse を使います。

string text = "550e8400-e29b-41d4-a716-446655440000";

Guid id = Guid.Parse(text); // 不正な文字列なら例外

// 例外を避けたいなら TryParse
if (Guid.TryParse(text, out var parsed))
{
    Console.WriteLine(parsed);
}
else
{
    Console.WriteLine("UUIDとして不正な文字列です");
}
C#

"D" 形式でも "N" 形式でも、Guid.TryParse はちゃんと解釈してくれます。

UUID文字列の検証ユーティリティ

「これはUUIDとして妥当な文字列か?」だけを見たい場合は、
Guid.TryParse をラップしたユーティリティを用意しておくと便利です。

public static class UuidValidator
{
    public static bool IsValidUuid(string? value)
    {
        if (string.IsNullOrWhiteSpace(value))
        {
            return false;
        }

        return Guid.TryParse(value.Trim(), out _);
    }
}
C#

これで、

Console.WriteLine(UuidValidator.IsValidUuid("550e8400-e29b-41d4-a716-446655440000")); // true
Console.WriteLine(UuidValidator.IsValidUuid("550e8400e29b41d4a716446655440000"));     // true
Console.WriteLine(UuidValidator.IsValidUuid("not-a-uuid"));                           // false
C#

のように、「UUIDっぽいかどうか」を簡単にチェックできます。


まとめ 「UUID生成ユーティリティ」は“世界でかぶらないIDを、気負わず配るための道具”

UUID(GUID)は、「ほぼ絶対にかぶらないID」を簡単に作るための標準ツールです。
C# では Guid.NewGuid() 一発で生成でき、ToString("D") / "N" で用途に応じた文字列にできます。

押さえておきたいポイントは、

Guid.NewGuid() がUUID生成の基本
ToString("D")(ハイフン付き)と "N"(ハイフンなし)を使い分ける
ユーティリティクラスにラップして、フォーマットと用途を名前で表現する
外部公開IDやトレースIDにはUUIDが向いている
Guid.TryParse を使えば、UUID文字列の検証やパースも簡単にできる

ここまで理解できれば、「なんとなく Guid.NewGuid() を呼んでいる」段階から一歩進んで、
“業務の中で意味のあるID設計”の一部として、UUID生成ユーティリティを自分の手で組み込めるようになっていきます。

タイトルとURLをコピーしました