Giter Site home page Giter Site logo

sole's Introduction

sole

  • Sole is a lightweight C++11 library to generate universally unique identificators (UUID).
  • Sole provides interface for UUID versions 0, 1 and 4.
  • Sole rebuilds UUIDs from hexadecimal and base62 cooked strings as well.
  • Sole is tiny, header-only, cross-platform.
  • Sole is zlib/libpng licensed.

Some theory

  • UUID version 1 (48-bit MAC address + 60-bit clock with a resolution of 100 ns)
  • UUID version 4 (122-bits of randomness)
  • Use v1 if you are worried about leaving it up to probabilities.
  • Use v4 if you are worried about security issues and determinism.

About custom version 0

  • UUID version 0 (16-bit PID + 48-bit MAC address + 60-bit clock with a resolution of 100ns since Unix epoch)
  • Format is EPOCH_LOW-EPOCH_MID-VERSION(0)|EPOCH_HI-PID-MAC

Public API

  • sole::uuid 128-bit UUID base type that allows comparison and sorting. std::ostream << friendly. .str() to get a cooked hex string. .base62() to get a cooked base62 string. .pretty() to get a pretty decomposed report.
  • sole::uuid0() creates an UUID v0.
  • sole::uuid1() creates an UUID v1.
  • sole::uuid4() creates an UUID v4.
  • sole::rebuild() rebuilds an UUID from given string or 64-bit tuple.

Showcase

~sole> cat sample.cc
#include <iostream>
#include "sole.hpp"

int main() {
    sole::uuid u0 = sole::uuid0(), u1 = sole::uuid1(), u4 = sole::uuid4();

    std::cout << "uuid v0 string : " << u0 << std::endl;
    std::cout << "uuid v0 base62 : " << u0.base62() << std::endl;
    std::cout << "uuid v0 pretty : " << u0.pretty() << std::endl << std::endl;

    std::cout << "uuid v1 string : " << u1 << std::endl;
    std::cout << "uuid v1 base62 : " << u1.base62() << std::endl;
    std::cout << "uuid v1 pretty : " << u1.pretty() << std::endl << std::endl;

    std::cout << "uuid v4 string : " << u4 << std::endl;
    std::cout << "uuid v4 base62 : " << u4.base62() << std::endl;
    std::cout << "uuid v4 pretty : " << u4.pretty() << std::endl << std::endl;

    u1 = sole::rebuild("F81D4FAE-7DEC-11D0-A765-00A0C91E6BF6");
    std::cout << "uuid v1 rebuilt: " << u1 << " -> " << u1.pretty() << std::endl;

    u4 = sole::rebuild("GITheR4tLlg-BagIW20DGja");
    std::cout << "uuid v4 rebuilt: " << u4 << " -> " << u4.pretty() << std::endl;
}

~sole> g++ sample.cc -std=c++11 -lrt && ./a.out
uuid v0 string : 00aed2f9-c5f8-0030-0fd8-00ffb77bd832
uuid v0 base62 : 3dNJHWv0aW-1MKpXy7mEmf
uuid v0 pretty : version=0,timestamp="03/07/2013 12:19:43",mac=00ffb77bd832,pid=4056,

uuid v1 string : 14314b83-e3ca-11e2-8b83-00ffb77bd832
uuid v1 base62 : 1jU2TXBD9t4-BycINxiP5Jh
uuid v1 pretty : version=1,timestamp="03/07/2013 12:19:43",mac=00ffb77bd832,clock_seq=2947,

uuid v4 string : fa237b32-d580-42db-aeb9-b09a1d90067e
uuid v4 base62 : LTTsO5t3jMR-F03eZqkMchC
uuid v4 pretty : version=4,randbits=fa237b32d58002db2eb9b09a1d90067e,

uuid v1 rebuilt : f81d4fae-7dec-11d0-a765-00a0c91e6bf6 -> version=1,timestamp="03/02/1997 18:43:12",mac=00a0c91e6bf6,clock_seq=10085,
uuid v4 rebuilt : bdd55e2f-6f6b-4088-8703-ddedba9456a2 -> version=4,randbits=bdd55e2f6f6b0088703ddedba9456a2,

Special notes

  • clang/g++ users: both -std=c++11 and -lrt may be required when compiling sole.cpp

Changelog

  • v1.0.4 (2022/04/09): Fix potential threaded issues (fix #18, PR #39) and a socket leak (fix #38)
  • v1.0.3 (2022/01/17): Merge fixes by @jasonwinterpixel(emscripten) + @jj-tetraquark(get_any_mac)
  • v1.0.2 (2021/03/16): Merge speed improvements by @vihangm
  • v1.0.1 (2017/05/16): Improve UUID4 and base62 performance; Fix warnings
  • v1.0.0 (2016/02/03): Initial semver adherence; Switch to header-only; Remove warnings

sole's People

Contributors

amincheloh avatar divinity76 avatar filippsen avatar jasonwinterpixel avatar jj-tetraquark avatar lazebnyv avatar mistertea avatar r-lyeh avatar r-lyeh-archived avatar samcoppini avatar vihangm avatar ybalrid avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sole's Issues

uuid4 seems unsafe base on C++ standards

I have found the following content on std::random_device:

std::random_device is a uniformly-distributed integer random number generator that produces non-deterministic random numbers.
std::random_device may be implemented in terms of an implementation-defined pseudo-random number engine if a non-deterministic source (e.g. a hardware device) is not available to the implementation. In this case each std::random_device object may generate the same number sequence.

I am writing a cross platform game and wanting a good UUID, and the fact that these could come out as the same number on some devices (I am thinking Android in particular) is a bit terrifying. Please let me know if I am wrong and there is a better assurance that this couldn't happen.

clang warning on exit-time declaration

This code at around line 367:
inline std::string uuid::base62() const {
static const std::string base62 =
"0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
return rebase( ab, base62 ) + "-" + rebase( cd, base62 );
}

and this code at around line 737:
static const std::string base62 =
"0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";

shows clang warning as below:

warning: declaration requires an exit-time destructor [-Wexit-time-destructors]
static const std::string base62 =
^

screen shot 2016-06-29 at 5 26 08 pm

The IDE I used is "Xcode Version 7.3.1"

Warning: possible misuse of comma operator here

While compiling my code on XCode, I get this warning.

sole.hpp:724:12: warning: possible misuse of comma operator here [-Wcomma]
                u.ab = ab, u.cd = cd;
                         ^
sole.hpp:724:3: note: cast expression to void to silence warning
                u.ab = ab, u.cd = cd;
                ^~~~~~~~~
                static_cast<void>( )
1 warning generated.

error: call to 'clock_gettime' is ambiguous

In sole.hpp you have:

    $lelse( $belse( // if not linux, if not bsd... valid for apple/win32
        inline int clock_gettime( int /*clk_id*/, struct timespec* t ) {
            struct timeval now;
            int rv = gettimeofday(&now, NULL);
            if( rv ) return rv;
            t->tv_sec  = now.tv_sec;
            t->tv_nsec = now.tv_usec * 1000;
            return 0;
        }
    ))

It looks like the intention is that you define clock_gettime on all versions of all non-Linux non-BSD operating systems. That's a bit of a problem on macOS because although OS X 10.11 and earlier did not have clock_gettime, macOS 10.12 and later do.

EternalTerminal includes sole and building EternalTerminal 6.0.13 on macOS 10.13 works. I'm not sure how it works since you have a definition of clock_gettime and the operating system also has one, but somehow it works.

EternalTerminal also uses getline which didn't exist until Mac OS X 10.7, so the build failed on Mac OS X 10.6. In MacPorts we have a library of functions that can be included on older systems to provide compatibility implementations of things like getline and clock_gettime. But when I do that for EternalTerminal, the build fails because the implementation of clock_gettime in the compatibility library conflicts with the implementation in sole.

https://trac.macports.org/ticket/60779

In file included from .../build/cotire/et-lib_CXX_prefix.cxx:4:
In file included from .../EternalTerminal-6.0.13/src/base/Headers.hpp:87:
.../EternalTerminal-6.0.13/src/base/sole.hpp:455:9: error: call to 'clock_gettime' is ambiguous
        clock_gettime(0 /*CLOCK_REALTIME*/, &tp);
        ^~~~~~~~~~~~~
/opt/local/include/LegacySupport/time.h:39:12: note: candidate function
extern int clock_gettime( clockid_t clk_id, struct timespec *ts );
           ^
.../EternalTerminal-6.0.13/src/base/sole.hpp:439:20: note: candidate function
        inline int clock_gettime( int /*clk_id*/, struct timespec* t ) {
                   ^
.../EternalTerminal-6.0.13/src/base/sole.hpp:225:18: note: expanded from macro '$belse'
#define $belse   $yes
                 ^
1 error generated.

Full build log: https://build.macports.org/builders/ports-10.6_x86_64-builder/builds/54980/steps/install-port/logs/stdio

I wonder if there is a way that sole could only define its clock_gettime if the OS (or the MacPorts legacy support library) doesn't already define it.

msys2 compile warinig

compile waring on msys2

/sole.hpp:138:0: error: ignoring #pragma comment  [-Werror=unknown-pragmas]
 #   pragma comment(lib,"iphlpapi.lib")

uuid4 does not seem to be thread safe.

uuid4() constructor uses a static variable : static std::random_device rd;
I don't think that random_device is guaranteed to be thread safe.
If that's the case, a potential fix could be to add the thread_local qualifier to the variable declaration.

Better performance for uuid4

I was doing some performance profiling and it seems that sole is the slowest bit in our code.

I notice the code is just doing:

std::random_device rd;
std::uniform_int_distribution<uint64_t> dist(0, (uint64_t)(~0));

The performance was better when I added static:

static std::random_device rd;
static std::uniform_int_distribution<uint64_t> dist(0, (uint64_t)(~0));

Not sure if there is any side effects but seems to work fine for us.

Support forward declaration

I'm having trouble doing forward declaration. Is it currently possible? Otherwise, can it be supported?

I use a json library which has "Json::Value". They have a special import "json-forwards.h" that people can use. You could do something similar.

-Wunused-value compiler warning

Hey great library. One minor issue (which I have locally fixed) is that on gcc version:

gcc (GCC) 4.9.2 20150212 (Red Hat 4.9.2-6)

I had to manually disable a -Wunused-value compiler warning. So for those who require warning-free compilations, you would have to edit the sole.cpp file to disable this warning:

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-value"
$linux({
    struct ifreq ifr;

    int s = socket(PF_INET, SOCK_DGRAM, 0);
    if (s == -1) return ("cannot open socket"), false;

    std::strcpy(ifr.ifr_name, "eth0");
    int rc = ioctl(s, SIOCGIFHWADDR, &ifr);
    close(s);
    if (rc < 0) return ("cannot get MAC address"), false;
    struct sockaddr* sa = reinterpret_cast<struct sockaddr*>(&ifr.ifr_addr);
    _node.resize( sizeof(sa->sa_data) );
    std::memcpy(_node.data(), sa->sa_data, _node.size() );
    return true;
})
#pragma GCC diagnostic pop

Not sure if you care to fix this or not, but just letting you know. Thanks!

error: type of thread-local variable has non-trivial destruction

#include "sole.hpp" produces the following compile error on Linux. Sole version is 1.0.4.

In file included from /home/conan/w/prod/BuildSingleReference/conan-center-index/recipes/sole/all/test_package/test_package.cpp:2:
/home/conan/w/prod/BuildSingleReference/.conan/data/sole/1.0.4/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include/sole.hpp:668:78: error: type of thread-local variable has non-trivial destruction
        static $msvc(__declspec(thread)) $melse(__thread) std::random_device rd;
                                                                             ^
/home/conan/w/prod/BuildSingleReference/.conan/data/sole/1.0.4/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include/sole.hpp:668:78: note: use 'thread_local' to allow this
/home/conan/w/prod/BuildSingleReference/.conan/data/sole/1.0.4/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include/sole.hpp:669:99: error: initializer for thread-local variable must be a constant expression
        static $msvc(__declspec(thread)) $melse(__thread) std::uniform_int_distribution<uint64_t> dist(0, (uint64_t)(~0));
                                                                                                  ^~~~~~~~~~~~~~~~~~~~~~~
/home/conan/w/prod/BuildSingleReference/.conan/data/sole/1.0.4/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include/sole.hpp:669:99: note: use 'thread_local' to allow this
2 errors generated.

Compiler setup:

CC and CXX: clang, clang++ 
Found clang 11.1
clang>=8, using the major as version
Default settings
	os=Linux
	os_build=Linux
	arch=x86_64
	arch_build=x86_64
	compiler=clang
	compiler.version=11
	compiler.libcxx=libstdc++
	build_type=Release

Test file:

#include <iostream>
#include "sole.hpp"

int main() {
    sole::uuid u0 = sole::uuid0(), u1 = sole::uuid1(), u4 = sole::uuid4();

    std::cout << "uuid v0 string : " << u0 << std::endl;
    std::cout << "uuid v0 base62 : " << u0.base62() << std::endl;
    std::cout << "uuid v0 pretty : " << u0.pretty() << std::endl << std::endl;

    std::cout << "uuid v1 string : " << u1 << std::endl;
    std::cout << "uuid v1 base62 : " << u1.base62() << std::endl;
    std::cout << "uuid v1 pretty : " << u1.pretty() << std::endl << std::endl;

    std::cout << "uuid v4 string : " << u4 << std::endl;
    std::cout << "uuid v4 base62 : " << u4.base62() << std::endl;
    std::cout << "uuid v4 pretty : " << u4.pretty() << std::endl << std::endl;

    u1 = sole::rebuild("F81D4FAE-7DEC-11D0-A765-00A0C91E6BF6");
    std::cout << "uuid v1 rebuilt: " << u1 << " -> " << u1.pretty()
              << std::endl;

    u4 = sole::rebuild("GITheR4tLlg-BagIW20DGja");
    std::cout << "uuid v4 rebuilt: " << u4 << " -> " << u4.pretty()
              << std::endl;
}

Related: conan-io/conan-center-index#11275

Github url in the comments

May I suggest adding your Github URL in your library header comments? That way it is easier to track where the library comes from :)

Compile error in C++17

if use command line option /std:c++latest (c++17) in Visual Studio 2017,
compile error occurred about std::unary_function.

so i just remove the code public std::unary_function < ... > and it works.
like this

namespace std {
    template<>
    class hash< sole::uuid >/* public unary_function< sole::uuid, size_t > */ {
    public:
        // hash functor: hash uuid to size_t value by pseudorandomizing transform
        size_t operator()( const sole::uuid &uuid ) const {
            if( sizeof(size_t) > 4 ) {
                return size_t( uuid.ab ^ uuid.cd );
            } else {
                uint64_t hash64 = uuid.ab ^ uuid.cd;
                return size_t( uint32_t( hash64 >> 32 ) ^ uint32_t( hash64 ) );
            }
        }
    };
}

is it right?

Add method to check if string is a valid guid

I want to check if a guid string is valid. Currently I've been doing sole::rebuild(guidString) but maybe there is a more optimised way.
An extra method like sole::isValid would come in handy.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.