我想生成一个长的UUID- 类似于gmail使用的会话密钥。它应该至少为256个字符,并且不超过512个字符。它可以包含所有字母数字字符和一些特殊字符(键盘上功能键下方的字符)。这已经完成了吗?还是有样品?
C ++或C#
更新:GUID是不够的。我们已经遇到了冲突,需要对此进行补救。512是目前的最大值,因为它将阻止我们更改已经发货的东西。
更新2:对于坚持GUID的独特性的人来说,如果有人想猜测您的下一个会话ID,则不必计算未来1万亿年的组合。他们所要做的就是限制时间因素,并且将在数小时内完成。
根据您的update2,即使msdn引用了Guid,也可以断定它是正确的。这是一种使用具有加密功能的随机数生成器来创建ID的方法。
static long counter; //store and load the counter from persistent storage every time the program loads or closes. public static string CreateRandomString(int length) { long count = System.Threading.Interlocked.Increment(ref counter); int PasswordLength = length; String _allowedChars = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ23456789"; Byte[] randomBytes = new Byte[PasswordLength]; RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider(); rng.GetBytes(randomBytes); char[] chars = new char[PasswordLength]; int allowedCharCount = _allowedChars.Length; for (int i = 0; i < PasswordLength; i++) { while(randomBytes[i] > byte.MaxValue - (byte.MaxValue % allowedCharCount)) { byte[] tmp = new byte[1]; rng.GetBytes(tmp); randomBytes[i] = tmp[0]; } chars[i] = _allowedChars[(int)randomBytes[i] % allowedCharCount]; } byte[] buf = new byte[8]; buf[0] = (byte) count; buf[1] = (byte) (count >> 8); buf[2] = (byte) (count >> 16); buf[3] = (byte) (count >> 24); buf[4] = (byte) (count >> 32); buf[5] = (byte) (count >> 40); buf[6] = (byte) (count >> 48); buf[7] = (byte) (count >> 56); return Convert.ToBase64String(buf) + new string(chars); }
编辑我知道有一些偏差,因为allowedCharCount不能被255整除,如果该偏差落在其余部分的无芒数中,您可以摆脱偏差并获得一个新的随机数。
allowedCharCount
EDIT2-这不能保证唯一,您可以持有一个静态的64位(或更高,如果需要)单调计数器,将其编码为base46,并将其作为id的前4-5个字符。
更新-现在保证是唯一的
更新2:算法现在速度较慢,但消除了偏差。
编辑:我刚刚运行了一个测试,我想让您知道ToBase64String可以返回非字母数字字符(例如1编码为"AQAAAAAAAAA="),以便您知道。
"AQAAAAAAAAA="
新版本:
从本页上的MattDotson的答案中得出的结论,如果您不太担心键空间,可以采用这种方式进行操作,这样可以更快地运行很多。
public static string CreateRandomString(int length) { length -= 12; //12 digits are the counter if (length <= 0) throw new ArgumentOutOfRangeException("length"); long count = System.Threading.Interlocked.Increment(ref counter); Byte[] randomBytes = new Byte[length * 3 / 4]; RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider(); rng.GetBytes(randomBytes); byte[] buf = new byte[8]; buf[0] = (byte)count; buf[1] = (byte)(count >> 8); buf[2] = (byte)(count >> 16); buf[3] = (byte)(count >> 24); buf[4] = (byte)(count >> 32); buf[5] = (byte)(count >> 40); buf[6] = (byte)(count >> 48); buf[7] = (byte)(count >> 56); return Convert.ToBase64String(buf) + Convert.ToBase64String(randomBytes); }