Reputation: 9770
Is there a way to generate every time a 100% new GUID without any chance to collide within entire application?
Since I cannot answer my question in eight hours, I come up with the solution:
internal static class GuidGenerator
{
private static readonly HashSet<Guid> _guids = new HashSet<Guid>();
internal static Guid GetOne()
{
Guid result;
lock (_guids)
while (!_guids.Add(result = Guid.NewGuid())) ;
return result;
}
internal static void Utilize(Guid guid)
{
lock (_guids)
_guids.Remove(guid);
}
}
Is this code solves the problem within the app?
EDIT: Uh, its getting complicated. Thread safety kills the speed.
Upvotes: 5
Views: 39242
Reputation: 1
GUID http://msdn.microsoft.com/en-us/library/system.guid.newguid.aspx
Edit - I agree with what @David Heffernan says. You can use the mechanism in place for generating the best unique identifier, but there are very few things in this universe that you can count on 100%.
Upvotes: 0
Reputation: 21
Storing current GUIDs is impractical for anything but a small number of GUIDs - which would have an incredibly low chance of collision anyway.
In a real-world scenario where you're generating probably millions or even billions of GUIDS on a regular basis, the overhead for storing 128 bit values to ensure unique GUIDs becomes impractical. (16 bytes per GUID)
For a mere 10,000,000,000 GUIDs, you need 160,000,000,000 bytes = 156,250,000 Kbytes = 152,588 Mbytes = 149 Gbytes
Lookup times in a large table will also make generating new unique GUIDs slow to a virtual crawl (in CPU time scale), particularly as new GUIDs collide with existing values causing the generation of new GUIDs - which then need to be checked, etc.
Generating a 'random' 128 bit value, or even using something like (current time * processor clock) will probably be 'close enough' - only 45 bits are enough to store millisecond counts for 1,000 years. 128 bits gives you 9,671,406,556,917,033,397,649,408 times that many values.
Regardless of what you do, collisions WILL occur with 128 bit values, even if using a counter.
Upvotes: 2
Reputation: 1499760
Sure. A GUID is just a 128-bit value. So use a 128-bit integer (e.g. represented by two ulong
values) and increment it. When you've reached the maximum value for the 128-bit integer type, you've generated all possible GUIDs. For example:
public IEnumerable<Guid> GetAllGuids()
{
unchecked
{
byte[] buffer = new byte[16];
ulong x = 0UL;
do
{
byte[] high = BitConverter.GetBytes(x);
Array.Copy(high, 0, buffer, 0, 8);
ulong y = 0UL;
do
{
y++;
byte[] low = BitConverter.GetBytes(y);
Array.Copy(low, 0, buffer, 8, 8);
yield return new Guid(buffer);
} while (y != 0UL);
x++;
} while (x != 0UL);
}
}
Notes:
ulong
values is a pain - I don't like using do...while
...Of course, this is in no way random...
In practice, as others have mentioned, the chances of collisions from Guid.NewGuid
are incredibly small.
Upvotes: 18
Reputation: 1227
If you need unique GUID in your context, just start with 00000000-0000-0000-0000-000000000000 and use incrementation. All generaged GUIDs will be unique unless you reach FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF
Upvotes: 3
Reputation: 99957
No, there isn't any way to generate absolutely unique GUIDs. There are only 3.40282367 × 1038 possible GUIDs so as galaxies collide so will these identifiers. Even for a single application, it depends on how many GUIDs the application has. Unless your app is bigger than all of Google's indexers combined, you don't need to lose sleep over this. Just use Guid.NewGuid()
.
Upvotes: 26
Reputation: 108790
Not 100%. But if your GUID generator works well, the collision probability is very very small. This can practically count as 0.
A randomly generated (kind 4) guid has about 120 random bits. From the birthday problem you can see that collisions get likely once you generate about 2^60 or 10^18 GUIDs, which is a damn lot.
So simply using Guid.NewGuid()
should be good enough.
Your proposed solution isn't a good idea IMO:
Your code itself looks correct to me. i.e. if you register all GUIDs and your hardware works perfectly, and the software has no other bugs you are guaranteed no collisions.
And of course it's not threadsafe either, which is unexpected for a static method.
Upvotes: 7
Reputation: 47363
If you use a finite number of characters, then according to the Pigeonhole( also called Dirichlet
) principle there is always a chance you will receive a collision.
Upvotes: 4
Reputation:
You can use Guid.NewGuid()
. It will generate the GUID for you, and I don't believe you'll have confliction with another GUID.
Upvotes: 2
Reputation: 17808
var newGuid = Guid.NewGuid();
http://msdn.microsoft.com/en-us/library/system.guid.newguid.aspx
Edit - I agree with what @David Heffernan says. You can use the mechanism in place for generating the best unique identifier, but there are very few things in this universe that you can count on 100%.
Upvotes: 3
Reputation: 612794
It depends what you want. If you want uniqueness amongst GUIDs that you generate, that can be achieved. Just maintain a list of GUIDs and whenever you need to create a new one, do this is a loop until you find one that is not in your list.
If you want some sort of global uniqueness, whereby global means out of all GUIDs in use across the entire planet, then that can never be achieved.
Upvotes: 2
Reputation: 27803
Guid.NewGuid() is the least likely way to generate a GUID that won't collide with another. There is no way to be 100% sure unless you generate a GUID and look at existing GUIDs to make sure they do not exist.
Upvotes: 1