Boost.UUID
認証ライブラリ
Boost.UUID
概要
Boost.UUIDはC++用のUUID(Universally Unique Identifier)生成ライブラリです。RFC 4122に準拠した128ビットの一意識別子を生成し、認証システムでのユーザーID、セッションID、APIキーなどの生成に広く使用されています。暗号学的に安全なランダム生成器を含む複数の生成方式をサポートし、分散システムでの一意性を保証します。2025年現在もBoostライブラリの一部として活発に開発が続けられています。
詳細
Boost.UUIDはC++アプリケーションでUUIDを生成・操作するための包括的なライブラリです。以下の主な特徴があります:
- RFC準拠: RFC 4122およびRFC 9562に完全準拠したUUID生成
- 複数の生成方式: ランダム、時間ベース、名前ベース、nil UUID等をサポート
- 暗号学的安全性: crypto-secureな疑似乱数生成器による安全な識別子生成
- ヘッダーオンリー: ビルド不要でインクルードするだけで使用可能
- スレッドセーフ: マルチスレッド環境での安全な使用
- 分散システム対応: 中央集権的な調整なしに一意性を保証
メリット・デメリット
メリット
- RFC標準に準拠した信頼性の高いUUID生成
- 暗号学的に安全な乱数生成による高いセキュリティ
- ヘッダーオンリーライブラリで導入とビルドが簡単
- 分散システムでの一意性保証により衝突リスクが極めて低い
- 豊富な生成オプション(時間ベース、名前ベース等)
- C++標準ライブラリとの良好な統合
デメリット
- C++以外の言語では使用できない
- Boostライブラリ全体の依存関係が必要な場合がある
- UUIDのサイズ(128ビット)が連続する整数より大きい
- 生成されるIDが予測不可能で人間には読みにくい
- パフォーマンスが重要な場面では生成コストが考慮事項
参考ページ
書き方の例
基本的なUUID生成
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <iostream>
int main() {
// ランダムUUID生成器
boost::uuids::random_generator gen;
// UUID生成
boost::uuids::uuid id = gen();
// 文字列として出力
std::cout << "Generated UUID: " << id << std::endl;
// 例: 67e55044-10b1-426f-9247-bb680e5fe0c8
return 0;
}
各種UUID生成器の使用
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <iostream>
#include <string>
int main() {
// 1. ランダムUUID(最も一般的)
boost::uuids::random_generator random_gen;
boost::uuids::uuid random_id = random_gen();
std::cout << "Random UUID: " << random_id << std::endl;
// 2. Nil UUID(すべてゼロ)
boost::uuids::nil_generator nil_gen;
boost::uuids::uuid nil_id = nil_gen();
std::cout << "Nil UUID: " << nil_id << std::endl;
// 3. 文字列からUUID生成
boost::uuids::string_generator string_gen;
boost::uuids::uuid string_id = string_gen("01234567-89ab-cdef-0123-456789abcdef");
std::cout << "String UUID: " << string_id << std::endl;
// 4. 名前ベースUUID(MD5ハッシュベース)
boost::uuids::name_generator_md5 name_gen(boost::uuids::ns::dns());
boost::uuids::uuid name_id = name_gen("example.com");
std::cout << "Name-based UUID: " << name_id << std::endl;
return 0;
}
認証システムでのユーザーID生成
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <unordered_map>
#include <string>
#include <iostream>
class UserManager {
private:
boost::uuids::random_generator uuid_gen;
std::unordered_map<std::string, std::string> users; // UUID -> username
public:
std::string createUser(const std::string& username) {
// 新しいユーザーIDを生成
boost::uuids::uuid user_id = uuid_gen();
std::string id_string = boost::uuids::to_string(user_id);
// ユーザーを登録
users[id_string] = username;
std::cout << "Created user '" << username
<< "' with ID: " << id_string << std::endl;
return id_string;
}
bool authenticateUser(const std::string& user_id) {
return users.find(user_id) != users.end();
}
std::string getUsername(const std::string& user_id) {
auto it = users.find(user_id);
return (it != users.end()) ? it->second : "";
}
};
int main() {
UserManager manager;
// ユーザー作成
std::string alice_id = manager.createUser("alice");
std::string bob_id = manager.createUser("bob");
// 認証確認
if (manager.authenticateUser(alice_id)) {
std::cout << "Alice authenticated successfully" << std::endl;
}
return 0;
}
セッション管理システム
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <unordered_map>
#include <chrono>
#include <string>
#include <iostream>
struct Session {
std::string user_id;
std::chrono::steady_clock::time_point created_at;
std::chrono::steady_clock::time_point expires_at;
bool isValid() const {
return std::chrono::steady_clock::now() < expires_at;
}
};
class SessionManager {
private:
boost::uuids::random_generator uuid_gen;
std::unordered_map<std::string, Session> sessions;
std::chrono::minutes session_duration{30}; // 30分のセッション期間
public:
std::string createSession(const std::string& user_id) {
// セッションIDを生成
boost::uuids::uuid session_uuid = uuid_gen();
std::string session_id = boost::uuids::to_string(session_uuid);
// セッションを作成
auto now = std::chrono::steady_clock::now();
sessions[session_id] = {
user_id,
now,
now + session_duration
};
std::cout << "Created session " << session_id
<< " for user " << user_id << std::endl;
return session_id;
}
bool validateSession(const std::string& session_id) {
auto it = sessions.find(session_id);
if (it == sessions.end()) {
return false;
}
if (!it->second.isValid()) {
sessions.erase(it); // 期限切れセッションを削除
return false;
}
return true;
}
std::string getUserFromSession(const std::string& session_id) {
auto it = sessions.find(session_id);
return (it != sessions.end() && it->second.isValid()) ? it->second.user_id : "";
}
void invalidateSession(const std::string& session_id) {
sessions.erase(session_id);
std::cout << "Session " << session_id << " invalidated" << std::endl;
}
};
int main() {
SessionManager session_mgr;
// セッション作成
std::string session = session_mgr.createSession("user123");
// セッション検証
if (session_mgr.validateSession(session)) {
std::string user = session_mgr.getUserFromSession(session);
std::cout << "Valid session for user: " << user << std::endl;
}
// セッション無効化
session_mgr.invalidateSession(session);
return 0;
}
APIキー生成システム
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <unordered_map>
#include <vector>
#include <string>
#include <iostream>
enum class APIKeyScope {
READ_ONLY,
READ_WRITE,
ADMIN
};
struct APIKey {
std::string key;
std::string user_id;
APIKeyScope scope;
bool active;
APIKey(const std::string& k, const std::string& uid, APIKeyScope s)
: key(k), user_id(uid), scope(s), active(true) {}
};
class APIKeyManager {
private:
boost::uuids::random_generator uuid_gen;
std::unordered_map<std::string, APIKey> api_keys;
public:
std::string generateAPIKey(const std::string& user_id, APIKeyScope scope) {
// APIキーを生成(プレフィックス付き)
boost::uuids::uuid key_uuid = uuid_gen();
std::string api_key = "ak_" + boost::uuids::to_string(key_uuid);
// APIキーを登録
api_keys.emplace(api_key, APIKey(api_key, user_id, scope));
std::cout << "Generated API key: " << api_key
<< " for user: " << user_id << std::endl;
return api_key;
}
bool validateAPIKey(const std::string& api_key, APIKeyScope required_scope) {
auto it = api_keys.find(api_key);
if (it == api_keys.end() || !it->second.active) {
return false;
}
// スコープ確認(ADMIN > READ_WRITE > READ_ONLY)
int current_level = static_cast<int>(it->second.scope);
int required_level = static_cast<int>(required_scope);
return current_level >= required_level;
}
void revokeAPIKey(const std::string& api_key) {
auto it = api_keys.find(api_key);
if (it != api_keys.end()) {
it->second.active = false;
std::cout << "API key " << api_key << " revoked" << std::endl;
}
}
std::vector<std::string> listAPIKeysForUser(const std::string& user_id) {
std::vector<std::string> user_keys;
for (const auto& pair : api_keys) {
if (pair.second.user_id == user_id && pair.second.active) {
user_keys.push_back(pair.first);
}
}
return user_keys;
}
};
int main() {
APIKeyManager api_mgr;
// APIキー生成
std::string read_key = api_mgr.generateAPIKey("user123", APIKeyScope::READ_ONLY);
std::string admin_key = api_mgr.generateAPIKey("admin456", APIKeyScope::ADMIN);
// APIキー検証
if (api_mgr.validateAPIKey(read_key, APIKeyScope::READ_ONLY)) {
std::cout << "Read access granted" << std::endl;
}
if (!api_mgr.validateAPIKey(read_key, APIKeyScope::ADMIN)) {
std::cout << "Admin access denied for read-only key" << std::endl;
}
return 0;
}
UUIDの文字列変換と比較
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <boost/lexical_cast.hpp>
#include <iostream>
#include <string>
int main() {
boost::uuids::random_generator gen;
// UUID生成
boost::uuids::uuid id1 = gen();
boost::uuids::uuid id2 = gen();
// 文字列変換(複数の方法)
std::string str1 = boost::uuids::to_string(id1);
std::string str2 = boost::lexical_cast<std::string>(id1);
std::cout << "UUID to string: " << str1 << std::endl;
std::cout << "Lexical cast: " << str2 << std::endl;
// 文字列からUUID
boost::uuids::string_generator string_gen;
boost::uuids::uuid id3 = string_gen(str1);
// 比較
if (id1 == id3) {
std::cout << "UUIDs match after string conversion" << std::endl;
}
if (id1 != id2) {
std::cout << "Different UUIDs are not equal" << std::endl;
}
// UUID のサイズと生の バイト
std::cout << "UUID size: " << sizeof(boost::uuids::uuid) << " bytes" << std::endl;
std::cout << "UUID data: ";
for (auto byte : id1) {
std::cout << std::hex << static_cast<int>(byte) << " ";
}
std::cout << std::endl;
return 0;
}