使用 boost 检查 std::string 是否是有效的 uuid
Check if std::string is a valid uuid using boost
我想使用 boost 检查给定的字符串是否是有效的 UUID。
这是我通过查看 boost 网站上的文档得出的结论:
void validate_uuid(const std::string& value)
{
try
{
boost::uuids::string_generator stringGenerator;
(void)stringGenerator(value);
}
catch (const std::exception& ex)
{
// ...
}
}
然而,这并不总是有效。
如果我使用对于有效 UUID 来说太短的字符串调用该函数,则会按预期抛出异常。但是,如果我使用无效的 UUID(例如 00000000-0000-0000-0000-00000000000K
)调用该函数,则不会引发异常。
请有人解释为什么会这样。
此外,我已经看到使用 boost::lexical_cast 将字符串读取为 UUID,如发布的 here。我想知道我是否应该遵循这种方法。任何建议表示赞赏。
由于您已经使用了 boost,因此您可以使用正则表达式来检查您的字符串是否是有效的 UUID
例如,对于 UUID 版本 4,您可以使用以下代码
bool validate_uuid(const std::string& s)
{
static const boost::regex e("[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}");
return regex_match(s, e); // note: case sensitive now
}
(如本 answer and in the wiki 中所述,应该有一个有效的版本数字和另一个 "special" 数字)。
您的代码在验证方面没有任何作用。相反,它会根据传递的常量生成 UUID(如哈希函数)。
仔细一看我看错了。缺少的验证似乎是对版本的检查:
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <boost/uuid/string_generator.hpp>
#include <iostream>
bool is_valid_uuid(std::string const& maybe_uuid, boost::uuids::uuid& result) {
using namespace boost::uuids;
try {
result = string_generator()(maybe_uuid);
return result.version() != uuid::version_unknown;
} catch(...) {
return false;
}
}
int main() {
std::string maybe_uuid;
std::cout << "Enter a UUID: ";
while (std::cin >> maybe_uuid)
{
boost::uuids::uuid result;
bool is_valid = is_valid_uuid(maybe_uuid, result);
std::cout << "\n'" << maybe_uuid << "' valid: " << std::boolalpha << is_valid << "\n";
if (is_valid)
std::cout << "Parsed value: " << result << "\n";
}
}
来自 Coliru: echo 00000000-0000-{0,4}000-0000-000000000000 $(uuidgen) "{$(uuidgen)}" | ./a.out
的示例输出:
Enter a UUID:
'00000000-0000-0000-0000-000000000000' valid: false
'00000000-0000-4000-0000-000000000000' valid: true
Parsed value: 00000000-0000-4000-0000-000000000000
'a2c59f5c-6c9b-4800-afb8-282fc5e743cc' valid: true
Parsed value: a2c59f5c-6c9b-4800-afb8-282fc5e743cc
'{82a31d37-6fe4-4b80-b608-c63ec5ecd578}' valid: true
Parsed value: 82a31d37-6fe4-4b80-b608-c63ec5ecd578
这似乎更简单:
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <iostream>
#include <sstream>
int main()
{
std::string t1("01234567-89ab-cdef-0123-456789abcdef");
std::string t2("Test UUID");
boost::uuids::uuid u;
std::istringstream iss(t1);
iss >> u;
if (iss.good())
std::cerr << "'" << t1 << "' is a good UUID\n";
else
std::cerr << "'" << t1 << "' is not a good UUID\n";
iss.str(t2);
iss >> u;
if (iss.good())
std::cerr << "'" << t2 << "' is a good UUID\n";
else
std::cerr << "'" << t2 << "' is not a good UUID\n";
return 0;
}
$ g++ -I/usr/local/include -std=c++11 test1.cpp
$ a.out
'01234567-89ab-cdef-0123-456789abcdef' is a good UUID
'Test UUID' is not a good UUID
我想使用 boost 检查给定的字符串是否是有效的 UUID。
这是我通过查看 boost 网站上的文档得出的结论:
void validate_uuid(const std::string& value)
{
try
{
boost::uuids::string_generator stringGenerator;
(void)stringGenerator(value);
}
catch (const std::exception& ex)
{
// ...
}
}
然而,这并不总是有效。
如果我使用对于有效 UUID 来说太短的字符串调用该函数,则会按预期抛出异常。但是,如果我使用无效的 UUID(例如 00000000-0000-0000-0000-00000000000K
)调用该函数,则不会引发异常。
请有人解释为什么会这样。
此外,我已经看到使用 boost::lexical_cast 将字符串读取为 UUID,如发布的 here。我想知道我是否应该遵循这种方法。任何建议表示赞赏。
由于您已经使用了 boost,因此您可以使用正则表达式来检查您的字符串是否是有效的 UUID
例如,对于 UUID 版本 4,您可以使用以下代码
bool validate_uuid(const std::string& s)
{
static const boost::regex e("[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}");
return regex_match(s, e); // note: case sensitive now
}
(如本 answer and in the wiki 中所述,应该有一个有效的版本数字和另一个 "special" 数字)。
您的代码在验证方面没有任何作用。相反,它会根据传递的常量生成 UUID(如哈希函数)。
仔细一看我看错了。缺少的验证似乎是对版本的检查:
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <boost/uuid/string_generator.hpp>
#include <iostream>
bool is_valid_uuid(std::string const& maybe_uuid, boost::uuids::uuid& result) {
using namespace boost::uuids;
try {
result = string_generator()(maybe_uuid);
return result.version() != uuid::version_unknown;
} catch(...) {
return false;
}
}
int main() {
std::string maybe_uuid;
std::cout << "Enter a UUID: ";
while (std::cin >> maybe_uuid)
{
boost::uuids::uuid result;
bool is_valid = is_valid_uuid(maybe_uuid, result);
std::cout << "\n'" << maybe_uuid << "' valid: " << std::boolalpha << is_valid << "\n";
if (is_valid)
std::cout << "Parsed value: " << result << "\n";
}
}
来自 Coliru: echo 00000000-0000-{0,4}000-0000-000000000000 $(uuidgen) "{$(uuidgen)}" | ./a.out
的示例输出:
Enter a UUID:
'00000000-0000-0000-0000-000000000000' valid: false
'00000000-0000-4000-0000-000000000000' valid: true
Parsed value: 00000000-0000-4000-0000-000000000000
'a2c59f5c-6c9b-4800-afb8-282fc5e743cc' valid: true
Parsed value: a2c59f5c-6c9b-4800-afb8-282fc5e743cc
'{82a31d37-6fe4-4b80-b608-c63ec5ecd578}' valid: true
Parsed value: 82a31d37-6fe4-4b80-b608-c63ec5ecd578
这似乎更简单:
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <iostream>
#include <sstream>
int main()
{
std::string t1("01234567-89ab-cdef-0123-456789abcdef");
std::string t2("Test UUID");
boost::uuids::uuid u;
std::istringstream iss(t1);
iss >> u;
if (iss.good())
std::cerr << "'" << t1 << "' is a good UUID\n";
else
std::cerr << "'" << t1 << "' is not a good UUID\n";
iss.str(t2);
iss >> u;
if (iss.good())
std::cerr << "'" << t2 << "' is a good UUID\n";
else
std::cerr << "'" << t2 << "' is not a good UUID\n";
return 0;
}
$ g++ -I/usr/local/include -std=c++11 test1.cpp
$ a.out
'01234567-89ab-cdef-0123-456789abcdef' is a good UUID
'Test UUID' is not a good UUID