GUID
GUID in C
var uuid = Guid.NewGuid().ToString();
// 9af7f46a-ea52-4aa3-b8c3-9fd484c2af12
var uuidN = Guid.NewGuid().ToString("N");
// e0a953c3ee6040eaa9fae2b667060e09
var uuidD = Guid.NewGuid().ToString("D");
// 9af7f46a-ea52-4aa3-b8c3-9fd484c2af12
var uuidB = Guid.NewGuid().ToString("B");
// {734fd453-a4f8-4c5d-9c98-3fe2d7079760}
var uuidP = Guid.NewGuid().ToString("P");
// (ade24d16-db0f-40af-8794-1e08e2040df3)
var uuidX = Guid.NewGuid().ToString("X");
// {0x3fa412e3,0x8356,0x428f,{0xaa,0x34,0xb7,0x40,0xda,0xaf,0x45,0x6f}}
GUID in JS
https://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid
function uuidv4() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
function guidGenerator() {
var S4 = function() {
return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
};
return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
}
function uuidv4() {
return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
);
}
function generateUUID() { // Public Domain/MIT
var d = new Date().getTime();//Timestamp
var d2 = (performance && performance.now && (performance.now()*1000)) || 0;
//Time in microseconds since page-load or 0 if unsupported
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16;//random number between 0 and 16
if(d > 0){//Use timestamp until depleted
r = (d + r)%16 | 0;
d = Math.floor(d/16);
} else {//Use microseconds since page-load if supported
r = (d2 + r)%16 | 0;
d2 = Math.floor(d2/16);
}
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
});
}
function broofa() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
return v.toString(16);
});
}
function e1() {
var u='',i=0;
while(i++<36) {
var c='xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'[i-1],r=Math.random()*16|0,v=c=='x'?r:(r&0x3|0x8);
u+=(c=='-'||c=='4')?c:v.toString(16)
}
return u;
}
function e4() {
var h=['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'];
var k=['x','x','x','x','x','x','x','x','-','x','x','x','x','-','4','x','x','x','-','y','x','x','x','-','x','x','x','x','x','x','x','x','x','x','x','x'];
var u='',i=0,rb=Math.random()*0xffffffff|0;
while(i++<36) {
var c=k[i-1],r=rb&0xf,v=c=='x'?r:(r&0x3|0x8);
u+=(c=='-'||c=='4')?c:h[v];rb=i%8==0?Math.random()*0xffffffff|0:rb>>4
}
return u
}
function dateGenerator() {
var myDate = new Date();
var month = myDate.getMonth() + 1;
var strDate = myDate.getDate();
if (month >= 1 && month <= 9) {
month = "0" + month;
}
if (strDate >= 0 && strDate <= 9) {
strDate = "0" + strDate;
}
return myDate.getFullYear() + "" + (month) + "" + strDate + "" + myDate.getHours() + "" + myDate.getMinutes() + "" + myDate.getSeconds() + "" + myDate.getMilliseconds();
}
简单证明GUID(全局唯一标识符)并不唯一
原文地址:http://www.cnblogs.com/jeffwongishandsome/archive/2011/05/02/2034403.html
GUID是什么,大家理所当然地应该都知道(百度百科介绍的GUID)。在.net framework中,微软为开发者提供了一个GUID结构,这个结构想必很多人在开发中应该已经用过,下面我们再来看一下它的备注说明:
GUID 是一个 128 位整数(16 字节),可用于所有需要唯一标识符的计算机和网络。此标识符重复的可能性非常小
。
注意标注,标识符是有重复的可能的,只不过重复的概率小之又小。到这里你我可能都会产生疑问,重复的可能性到底有多小呢?如何证明有重复呢?在stackoverflow上,一个善于思考勇于发现并提出问题挑战权威的C#开发先驱抛出了一个有趣的问答题:“Simple proof that GUID is not unique”(本文的标题就是按照英文原文标题直译过来的)。
在英文原文中,提问者说他想在一个测试程序中简单证明一下GUID并不唯一,然后给出了如下代码实现:
BigInteger begin = new BigInteger((long)0);
BigInteger end = new BigInteger("340282366920938463463374607431768211456",10); //2^128
for(begin; begin<end; begin++) Console.WriteLine(System.Guid.NewGuid().ToString());
令人感到遗憾的是,“it's not working”(实际上,拷贝这份代码到VS中,编译无法通过,BigInteger的构造函数根本不存在,for循环的地方写得也不对,估计是伪代码)。
接着,我们看到了投票次数最多的正确答案:
using System;
using System.Collections.Generic;
using System.Linq;
namespace GuidCollisionDetector
{
class Program
{
static void Main(string[] args)
{
var reserveSomeRam = new byte[1024 * 1024 * 100];
Console.WriteLine("{0:u} - Building a bigHeapOGuids.", DateTime.Now);
// Fill up memory with guids.
var bigHeapOGuids = new HashSet<Guid>();
try
{
do
{
bigHeapOGuids.Add(Guid.NewGuid());
}
while (true);
}
catch (OutOfMemoryException)
{
// Release the ram we allocated up front.
GC.KeepAlive(reserveSomeRam);
GC.Collect();
}
Console.WriteLine("{0:u} - Built bigHeapOGuids, contains {1} of them.", DateTime.Now, bigHeapOGuids.LongCount());
// Spool up some threads to keep checking if there's a match.
// Keep running until the heat death of the universe.
for (long k = 0; k < Int64.MaxValue; k++)
{
for (long j = 0; j < Int64.MaxValue; j++)
{
Console.WriteLine("{0:u} - Looking for collisions with {1} thread(s)....", DateTime.Now, Environment.ProcessorCount);
System.Threading.Tasks.Parallel.For(0, Int32.MaxValue, (i) =>
{
if (bigHeapOGuids.Contains(Guid.NewGuid()))
throw new ApplicationException("Guids collided! Oh my gosh!");
});
Console.WriteLine("{0:u} - That was another {1} attempts without a collision.", DateTime.Now, ((long)Int32.MaxValue) * Environment.ProcessorCount);
}
}
Console.WriteLine("Umm... why hasn't the universe ended yet?");
}
}
}
楼猪第一次看到代码的时候,精神抖擞热情洋溢地分析如下:
-
定义一个字节数组reserveSomeRam,分配一块内存空间;
-
通过HashSet对象填充GUID,直至内存不足,通过GC的KeepAlive和Collect方法,释放出预留给reserveSomeRam的内存空间,保证程序有继续运行的微小内存空间(此时,楼猪惊呼,好一段惊世骇俗奇技淫巧的NB代码啊);
-
通过两个for循环,配合并行库,通过HashSet的Contains函数证明新产生的GUID有可能产生重复(这里主要就是CPU运算的事情了,完全用不到reserveSomeRam那一块的内存,充分地利用了CPU和内存,这种思想这种境界真是令人感到匪夷所思望尘莫及,牛)。
但是看到代码中的“throw new ApplicationException("Guids collided! Oh my gosh!");”和Console.WriteLine("Umm... why hasn't the universe ended yet?");,楼猪有一种穿越的感觉。
接着楼猪仔细看了一下这个正确答案的正文回答的细节,发现这家伙从头到尾都是一种煞有介事一本正经的口气,又是版权,又是要钱,又是坐着时光机回到2010年2月28号获得技术支持的…恍然大悟,kao,真是TM的太好玩太会扯淡了。
忍耐不住好奇,怀着强烈的求知欲望,楼猪看完了所有回答,有人用数学方法证明…祝你好运;有人寄希望于未来的量子计算机显灵;有人提议组织志愿者现在就开始他们伟大的136年证明之旅;有人提议升级显卡,NVIDIA 可能会贷款赞助这个历史性的计算;有人说他可以帮忙,已经被证明了,他曾经获得过某一个GUID数字……楼猪久违地又蛋疼了。
比较起来,个人感觉还是这个回答比较靠谱:
Well if the running time of 83 billion years does not scare you, think that you will also need to store the generated GUIDs somewhere to check if you have a duplicate; storing 2^128 16-byte numbers would only require you to allocate 4951760157141521099596496896 terabytes of RAM upfront, so imagining you have a computer which could fit all that and that you somehow find a place to buy terabyte DIMMs at 10 grams each, combined they will weigh more than 8 Earth masses, so you can seriously shift it off the current orbit, before you even press "Run". Think twice!
大致意思就是说,跑完证明程序,需要大概830亿年时间和4951760157141521099596496896 TB(1TB=1024GB)的内存空间(假设每个DIMM内存有10克重,所有的内存换算成重量,大概是8个地球的重量之和)。从看似有限而又无限的时间和空间上证明,GUID重复这种概率发生的可能性实在是太太太小了,可以认为基本不可能。有一个回复说,“Personally, I think the "Big Bang" was caused when two GUIDs collided.”,即:两个GUID重复之日,宇宙大爆炸之时。
实际上,楼猪现在也是这么认为的。
您有好的方法证明GUID会重复吗?
发表评论