Possible Duplicate:
How to generate 8 bytes unique id from GUID?
I need a unique key to identify a user at universal and key's length is just 8 byte, How can I do this in c# ?
Possible Duplicate:
How to generate 8 bytes unique id from GUID?
I need a unique key to identify a user at universal and key's length is just 8 byte, How can I do this in c# ?
the following code will generate cryptographically unique 8 character strings:
using System;
using System.Security.Cryptography;
using System.Text;
namespace JustForFun
{
public class UniqueId
{
public static string GetUniqueKey()
{
int maxSize = 8;
char[] chars = new char[62];
string a;
a = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
chars = a.ToCharArray();
int size = maxSize;
byte[] data = new byte[1];
RNGCryptoServiceProvider crypto = new RNGCryptoServiceProvider();
crypto.GetNonZeroBytes(data);
size = maxSize;
data = new byte[size];
crypto.GetNonZeroBytes(data);
StringBuilder result = new StringBuilder(size);
foreach (byte b in data)
{ result.Append(chars[b % (chars.Length - 1)]); }
return result.ToString();
}
}
}
8 bytes is a size of a long integer in .net. You may start with a key of zero, increasing it by one for each user as they come. That would generate unique keys for more users than there are people on the Earth. If this does not solve your problem, please tell us more about your constraints.
Generate a random long, and then convert it to a hex string.
Alternatively, just sequentially allocate from unsigned long
.
You could take a Guid.NewGuid().ToByteArray() and run it through some hashing algorithm with a resulting size of 8 Byte (= 64 Bit).
EDIT: There is a Google-developed Hash-Algo returning 64Bits (see http://code.google.com/p/cityhash/ ) which can be used on Guid.NewGuid().ToString() .
With an 8 byte value (64 bits) you will have 2^64 possible outcomes. That's quite a few but significantly less than a GUID which has 2 ^ 128 possible values.
You could do something this simple:
// generate 8 byte random value
Random rnd = new Random();
byte[] bytes = new byte[8];
rnd.NextBytes(bytes);
// displaying the value
string myRndID = BitConverter.ToString(bytes).Replace("-", "");
Console.WriteLine(myRndID);
For example:
XXXX YY ZZ
---- -- --
Random Value Node ID Days since epoch (of your definition)
Then:
Cat XXXX, YY and ZZ bytes together to create your pseudo-guID.
But that approach uses only random number generation. You could take a hint from the GUID algorithms (current and past) and populate some of the 8 bytes with a node ID value or a DateTime hash or something such combined with a random value to reduce the risk of collisions.
Still, the potential for collisions is there and if you do end up using an 8 byte pseudo-guID you should have a process defined for handling a collision.
The point of a GUID is to be "Globally" Unique, meaning that the likelihood of anybody ever coming up with the same unique identifier that someone else is already using for a different object must be so small that you're willing to bet your business on it. Smarter minds than mine have determined that 16 bytes, combined with the right algorithm, is sufficient to achieve this. Since 8 bytes gives you only a tiny, tiny fraction of the number of possibilities that 16 bytes would give, I wouldn't recommend using 8-byte GUIDs.
However, if you really want to, you could do something like this:
public struct SmallGuid
{
byte FirstByte;
byte SecondByte;
...
}
Then you could either generate random values for these bytes, or leverage the real Guid class, and pull half the bytes off of it to populate your SmallGuid.
See GUIDs are globally unique, but substrings of GUIDs aren't.
Hashing a GUID may work (but I'm not sure), but a better idea would be to come up with your own algorithm inspired by the GUID algorithm and based on the constraints of your system that you are aware of, for example: