<p>What is the best way to generate a Unique ID from two (or more) short ints in C++?  I am trying to uniquely identify vertices in a graph.  The vertices contain two to four short ints as data, and ideally the ID would be some kind of a hash of them.  Prefer portability and uniqueness over speed or ease.  </p>

<p>There are a lot of great answers here, I will be trying them all tonight to see what fits my problem the best.  A few more words on what I'm doing.  </p>

<p>The graph is a collection of samples from an audio file.   I use the graph as a Markov Chain to generate a new audio file from the old file.  Since each vertex stores a few samples and points to another sample, and the samples are all short ints, it seemed natural to generate an ID from the data.  Combining them into a long long sounds good, but maybe something as simple as just a 0 1 2 3 <code>generateID</code> is all I need.  not sure how much space is necessary to guarantee uniqueness, if each vertex stores 2 16 bit samples, there are 2^32 possible combinations correct?  and so if each vertex stores 4 samples, there are 2^64 possible combinations?  </p>

<p>Library and platform specific solutions not really relevant to this question.  I don't want anyone else who might compile my program to have to download additional libraries or change the code to suit their OS.  </p>

[{'answer_id': 65551, 'author': 'Fire Lancer', 'author_id': 6266, 'author_profile': 'https://Stackoverflow.com/users/6266', 'pm_score': 0, 'selected': False, 'text': '<p>Well the only way to guarantee the ID is unique, is to make have more id combinations than what your gettings ids from</p>\n\n<p>eg for 2 shorts (assuming 16bit), you should use a 32bit int  </p>\n\n<pre><code>int ID = ((int)short1 &lt;&lt; 16) | short2;\n</code></pre>\n\n<p>and for 4 shorts you would need a 64bit int, etc...</p>\n\n<p>With basically anything else collisions (multiple things may get the same id) are pretty much guaranteed.</p>\n\n<p>However a different approach (which I think would be better)to get ids would be to hand them out as vertices are inserted:</p>\n\n<pre><code>unsigned LastId = 0;//global\n\nunsigned GetNewId(){return ++LastId;}\n</code></pre>\n\n<p>This also has the effect of allowing you to add more/different data to each vertex. However if you expect to create more than 2^32 vertices without resetting it, this is probably not the best method.</p>\n'}, {'answer_id': 65552, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 0, 'selected': False, 'text': '<p>use a long long so you can store all 4 possibilities, then bitshift each short:</p>\n\n<p>((long long)shortNumberX) &lt;&lt; 0, 4, 8, or 12</p>\n\n<p>make sure you cast before shifting, or your data could drop off the end.</p>\n\n<p>Edit: forgot to add, you should OR them together.</p>\n'}, {'answer_id': 65589, 'author': 'Doug T.', 'author_id': 8123, 'author_profile': 'https://Stackoverflow.com/users/8123', 'pm_score': 4, 'selected': True, 'text': '<p>A simple solution is to use a 64 bit integer where the lower 16 bits is the first vertex coordinate, next 16 bits is the second, and so on. This will be unique for all your vertices, though not very compact.</p>\n\n<p>So here\'s some half-assed code to do this. Hopefully I got the casts right.</p>\n\n<pre><code>uint64_t generateId( uint16_t v1, uint16_t v2, uint16_t v3, uint16_t v4)\n{ \n   uint64_t id;\n   id = v1 | (((uint64_t)v2) &lt;&lt; 16) | (((uint64_t)v3) &lt;&lt; 32) | (((uint64_t)v4) &lt;&lt; 48);\n   return id;\n}\n</code></pre>\n\n<p>Optionally this could be done with a union (great idea from Leon Timmermans, see comment). Very clean this way:</p>\n\n<pre class="lang-cpp prettyprint-override"><code>struct vertex\n{\n    uint16_t v1;\n    uint16_t v2;\n    uint16_t v3;\n    uint16_t v4;\n};\n\nunion vertexWithId\n{\n    vertex v;\n    uint64_t id;\n};\n\nint main()\n{\n    vertexWithId vWithId;\n    // Setup your vertices\n    vWithId.v.v1 = 2;\n    vWithId.v.v2 = 5;\n\n    // Your id is automatically setup for you!\n    std::cout &lt;&lt; "Id is " &lt;&lt; vWithId.id &lt;&lt; std::endl;\n    return 0;\n}\n</code></pre>\n'}, {'answer_id': 65599, 'author': 'Jeroen Dirks', 'author_id': 7743, 'author_profile': 'https://Stackoverflow.com/users/7743', 'pm_score': 3, 'selected': False, 'text': '<p>Sometimes the simplest things works best.</p>\n\n<p>Can you just add an id field to the Vertex object and assign it a number in order of construction?</p>\n\n<pre><code>static int sNextId = 0;\nint getNextId() { return ++sNextId; }\n</code></pre>\n'}, {'answer_id': 65632, 'author': 'basszero', 'author_id': 287, 'author_profile': 'https://Stackoverflow.com/users/287', 'pm_score': -1, 'selected': False, 'text': "<p>off the cuff I'd say use prime numbers,</p>\n\n<pre><code>id = 3 * value1 + 5 * value2 + .... + somePrime * valueN\n</code></pre>\n\n<p>Make sure you don't overflow your id space (long? long long?). Since you've got a fixed number of values just crap some random primes. Don't bother generating them, there are enough available in lists to get you going for awhile.</p>\n\n<p>I'm a little sketchy on the proof though, maybe someone more mathmatical can hook me up. Probably has something to do with unique prime factorization of a number.</p>\n"}, {'answer_id': 65835, 'author': 'David Dolson', 'author_id': 8566, 'author_profile': 'https://Stackoverflow.com/users/8566', 'pm_score': 0, 'selected': False, 'text': '<p>If you prefer the portability, then <a href="http://www.boost.org/doc/libs/1_35_0/libs/tuple/doc/tuple_users_guide.html" rel="nofollow noreferrer">boost::tuple</a> is nice:</p>\n\n<p>You would want a tuple of 4 items:</p>\n\n<pre><code>typedef boost::tuple&lt;uint16,uint16,uint16,uint16&gt; VertexID;\n</code></pre>\n\n<p>You can assign like this:</p>\n\n<pre><code>VertexID id = boost::make_tuple(1,2,3,4);\n</code></pre>\n\n<p>The boost tuple already has support for comparison, equality, etc., so it is easy to use in containers and algorithms.</p>\n'}, {'answer_id': 65884, 'author': 'xtofl', 'author_id': 6610, 'author_profile': 'https://Stackoverflow.com/users/6610', 'pm_score': 0, 'selected': False, 'text': '<p>The definition of the "ID" in the question isn\'t really clear: do you need to use it as a key for fast Vertex lookup? You could define a comparator for the <code>std::map</code> (see below for an example)</p>\n\n<p>Do you need to be able to differentiate between two Vertex objects with the same coordinates (but different in another field)?  Define some \'id factory\' (cfr. the singleton pattern) that generates e.g. a sequence of ints, unrelated to the values of the Vertex objects. - Much in the way Fire Lancer suggests (but beware of thread-safety issues!)</p>\n\n<p>In my opinion, two vertices with identical coordinates are identical.  So why would you even need an extra ID?</p>\n\n<p>As soon as you define a \'<a href="http://en.wikipedia.org/wiki/Strict_weak_ordering" rel="nofollow noreferrer">strict weak ordering</a>\' on this type, you can use it as a key in e.g. an <code>std::map</code>, </p>\n\n<pre><code>struct Vertex {\n  typedef short int Value;\n  Value v1, v2;\n\n  bool operator&lt;( const Vertex&amp; other ) const {\n    return v1 &lt; other.v1 || ( v1 == other.v1 &amp;&amp; v2 &lt; other.v2 ) ;\n};\n\nVertex x1 = { 1, 2 };\nVertex x2 = { 1, 3 };\nVertex y1 = { 1, 2 }; // too!\n\ntypedef std::set&lt;Vertex&gt; t_vertices;\n\nt_vertices vertices;\nvertices.insert( x1 );\nvertices.insert( x2 );\nvertices.insert( y1 ); // won\'t do a thing since { 1, 2 } is already in the set.\n\ntypedef std::map&lt;Vertex, int&gt; t_vertex_to_counter;\nt_vertex_to_counter count;\ncount[ x1 ]++;\nassert( count[x1] == 1 );\nassert( count[y1] == 1 );\ncount[ x2 ]++;\ncount[ y1 ]++; \nassert( count[x1] == 2 );\nassert( count[y1] == 2 );\n</code></pre>\n'}, {'answer_id': 66031, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 0, 'selected': False, 'text': '<p>If you are on Windows, you could use<a href="http://msdn.microsoft.com/en-us/library/ms688568(VS.85).aspx" rel="nofollow noreferrer">CoCreateGUID</a> API, on Linux you can use /proc/sys/kernel/random/uuid, you can also look at \'libuuid\'.</p>\n'}, {'answer_id': 69113, 'author': 'bk1e', 'author_id': 8090, 'author_profile': 'https://Stackoverflow.com/users/8090', 'pm_score': 0, 'selected': False, 'text': '<p>If you\'re building a hash table in which to store your vertices, I can think of a couple of ways to avoid collisions:</p>\n\n<ol>\n<li>Generate IDs directly from the input data without throwing any bits away, and use a hash table that is large enough to hold all possible IDs. With 64-bit IDs, the latter will be extremely problematic: you will have to use a table that is smaller than your range of IDs, therefore you will have to deal with collisions. Even with 32-bit IDs, you would need well over 4GB of RAM to pull this off without collisions.</li>\n<li>Generate IDs sequentially as you read in the vertices. Unfortunately, this makes it very expensive to search for previously read vertices in order to update their probabilities, since a sequential ID generator is not a hash function. If the amount of data used to construct the Markov chain is significantly smaller than the amount of data that the Markov chain is used to generate (or if they are both small), this may not be an issue.</li>\n</ol>\n\n<p>Alternatively, you could use a hash table implementation that handles collisions for you (such as <a href="http://en.cppreference.com/w/cpp/container/unordered_map" rel="nofollow noreferrer">unordered_map</a>/<a href="http://www.sgi.com/tech/stl/hash_map.html" rel="nofollow noreferrer">hash_map</a>), and concentrate on the rest of your application.</p>\n'}, {'answer_id': 67500572, 'author': 'Arslan Tariq', 'author_id': 15904952, 'author_profile': 'https://Stackoverflow.com/users/15904952', 'pm_score': 0, 'selected': False, 'text': '<p>Try using this:</p>\n<pre><code>int generateID()\n{\n    static int s_itemID{ 0 };\n    return s_itemID++; // makes copy of s_itemID,\n                         increments the real s_itemID, \n                         then returns the value in the copy\n}\n</code></pre>\n<p>This from <a href="https://www.learncpp.com/cpp-tutorial/static-local-variables/" rel="nofollow noreferrer">here</a>.</p>\n'}, {'answer_id': 67506389, 'author': 'Mubashar M', 'author_id': 6085943, 'author_profile': 'https://Stackoverflow.com/users/6085943', 'pm_score': 0, 'selected': False, 'text': '<p>Implementing your own hashing can be tedious and prone to some issues which are hard to debug and resolve when you have rolled out or partially rolled out your system. A much better implementation for Unique Ids is already present in windows API. You can see more details <a href="https://learn.microsoft.com/en-us/windows/win32/api/guiddef/ns-guiddef-guid" rel="nofollow noreferrer">here</a>;</p>\n<p><a href="https://learn.microsoft.com/en-us/windows/win32/api/guiddef/ns-guiddef-guid" rel="nofollow noreferrer">https://learn.microsoft.com/en-us/windows/win32/api/guiddef/ns-guiddef-guid</a></p>\n'}]
['https://Stackoverflow.com/questions/65524', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/8264/']