Bằng chứng đơn giản rằng GUID không phải là duy nhất [đã đóng]


323

Tôi muốn chứng minh rằng GUID không phải là duy nhất trong một chương trình thử nghiệm đơn giản. Tôi dự kiến ​​mã sau sẽ chạy trong nhiều giờ, nhưng nó không hoạt động. Làm thế nào tôi có thể làm cho nó hoạt động?

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());

Tôi đang sử dụng C #.


107
Là một nhà phát triển phần mềm, bạn sẽ nói gì nếu người dùng đến với bạn và nói "nó không hoạt động"?
JoshJordan

152
Đợi vài nghìn tỷ năm.
hobbs

67
Upmodded bởi vì đây là điều thú vị nhất mà tôi thấy trực tuyến ngày hôm nay.
jrockway

32
@jrockway - lol. Tôi đang gặp khó khăn trong việc tìm kiếm bất cứ điều gì về câu hỏi này về cơ bản là không sai. Càng nhìn lâu, nó càng buồn cười.
tylerl

243
Nó chỉ duy nhất trên toàn cầu, vì vậy nó chỉ duy nhất trên hành tinh của chúng ta. Nếu bạn muốn một id thực sự độc đáo, bạn cần sử dụng một id duy nhất trên toàn cầu (UUID). Tôi cho rằng bạn chỉ quan tâm đến sự độc đáo trong vũ trụ của chúng ta. :-)
tvanfosson

Câu trả lời:


407

Kai, tôi đã cung cấp một chương trình sẽ làm những gì bạn muốn bằng cách sử dụng các chủ đề. Nó được cấp phép theo các điều khoản sau: bạn phải trả cho tôi 0,0001 đô la mỗi giờ cho mỗi lõi CPU mà bạn chạy nó. Lệ phí được trả vào cuối mỗi tháng dương lịch. Vui lòng liên hệ với tôi để biết chi tiết tài khoản paypal của tôi một cách thuận tiện sớm nhất.

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];     // This indeed has no effect.

            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.
                // Actually, these are pointless too.
                //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?");
        }
    }
}

PS: Tôi muốn dùng thử thư viện mở rộng Parallel. Điều đó thật dễ dàng.

Và sử dụng OutOfMemoryException làm luồng điều khiển chỉ cảm thấy sai.

BIÊN TẬP

Chà, có vẻ như điều này vẫn thu hút phiếu bầu. Vì vậy, tôi đã sửa vấn đề GC.KeepAlive (). Và thay đổi nó để chạy với C # 4.

Và để làm rõ các điều khoản hỗ trợ của tôi: hỗ trợ chỉ khả dụng vào ngày 28/2/2010. Vui lòng sử dụng một cỗ máy thời gian để thực hiện các yêu cầu hỗ trợ vào ngày đó.

EDIT 2 Như mọi khi, GC làm việc tốt hơn tôi trong việc quản lý bộ nhớ; bất kỳ nỗ lực nào trước đây để làm điều đó bản thân tôi đã cam chịu thất bại.


120
Cái Console cuối cùng đó.WriteLine khiến tôi cười rất nhiều. Tôi nghĩ bạn nên ném một CommonlyAcceptedCosmologicTheoriesWrongExceptionthay thế.
R. Martinho Fernandes

17
việc đánh dấu điều này là Được chấp nhận cũng có nghĩa là @Kai chấp nhận các điều khoản do @ligos quy định?
kb.

3
Cài đặt reserveSomeRam = null;không thực sự hoàn thành bất cứ điều gì.
DevinB

4
@devinb hãy giải thích? có vẻ như nó đang giải phóng các byte mà nó đã được phân bổ trước đó để cho GC có thể Collect(). Tại sao nó không hoàn thành bất cứ điều gì?
huyền thoại

3
GuidCollisionDetector. Tên này có tiềm năng
Ufuk Hacıoğulları

226

Điều này sẽ chạy trong nhiều giờ hơn. Giả sử nó lặp ở tốc độ 1 GHz (điều đó sẽ không xảy ra - nó sẽ chậm hơn rất nhiều so với mức đó), nó sẽ chạy trong 10790283070806014188970 năm. Đó là khoảng 83 tỷ lần so với tuổi của vũ trụ.

Giả sử luật Moores nắm giữ, sẽ nhanh hơn rất nhiều nếu không chạy chương trình này, đợi vài trăm năm và chạy nó trên máy tính nhanh hơn hàng tỷ lần. Trên thực tế, bất kỳ chương trình nào mất nhiều thời gian để chạy hơn tốc độ CPU sẽ tăng gấp đôi (khoảng 18 tháng) sẽ hoàn thành sớm hơn nếu bạn đợi cho đến khi tốc độ CPU tăng lên và mua CPU mới trước khi chạy nó (trừ khi bạn viết nó để nó có thể bị đình chỉ và tiếp tục trên phần cứng mới).


27
chết tiệt - vì vậy có lẽ các chủ đề máy chủ tạo ra các hướng dẫn là một ý tưởng tốt hơn?
Kai

107
4 luồng trên bộ xử lý lõi tứ sẽ khiến nó chạy trong 20 tỷ lần tuổi của vũ trụ - vì vậy, điều đó sẽ giúp ích rất nhiều.
rjmunro

34
Tôi nghi ngờ rằng đây là một trò troll, nhưng rất có thể nó không phải là: chủ đề không phải là phép thuật. Nếu bạn có thể thực hiện một tỷ thao tác mỗi giây trên một luồng, thì việc chuyển sang mười luồng có nghĩa là mỗi luồng chạy 1/10 như thường lệ. Mỗi luồng thực hiện 100 M hoạt động mỗi giây; tổng số thao tác mỗi giây không tăng. Cách để tăng số lượng hoạt động mỗi giây là mua thêm máy tính. Giả sử bạn đã mua thêm một tỷ máy tính. Điều đó sẽ giảm vấn đề chỉ mất 10790283070806 năm, vẫn còn hơn bốn giờ.
Eric Lippert

10
Tôi nghĩ rằng rjmunro đang giả định rằng mỗi luồng sẽ chạy trên một lõi riêng biệt; 83 tỷ vũ trụ / 4 lõi thực sự xấp xỉ bằng 20 tỷ vũ trụ. Đã đến lúc mua cổ phiếu Intel!
Dour High Arch

4
@Erik 83 tỷ bộ xử lý có nghĩa là bạn sẽ có thể làm điều đó trong khoảng thời gian vũ trụ tồn tại cho đến nay. Vì vậy, ngay cả điều đó là không đủ.
rjmunro

170

GUID về mặt lý thuyết là không độc đáo. Đây là bằng chứng của bạn:

  • GUID là số 128 bit
  • Bạn không thể tạo 2 ^ 128 + 1 hoặc nhiều GUID mà không sử dụng lại GUID cũ

Tuy nhiên, nếu toàn bộ sản lượng điện của mặt trời được hướng vào để thực hiện nhiệm vụ này, nó sẽ bị lạnh lâu trước khi hoàn thành.

GUID có thể được tạo bằng một số chiến thuật khác nhau, một số trong đó thực hiện các biện pháp đặc biệt để đảm bảo rằng một máy nhất định sẽ không tạo ra cùng một GUID hai lần. Tìm kiếm sự va chạm trong một thuật toán cụ thể sẽ cho thấy rằng phương pháp cụ thể của bạn để tạo GUID là xấu, nhưng sẽ không chứng minh bất cứ điều gì về GUID nói chung.


44
Nguyên tắc Pigeonhole để giải cứu!
yfeldblum

22
+1 cho mặt trời bình luận lạnh. Có một nhận xét thú vị ở đâu đó về sự vô nghĩa của các khóa mã hóa> 256 bit. Lặp đi lặp lại tất cả các giá trị quan trọng có thể sẽ tốn nhiều năng lượng hơn toàn bộ vũ trụ. Việc điều chỉnh một chút trong CPU đòi hỏi một lượng năng lượng nhỏ (đó là thứ tạo ra nhiệt), khi nhân lên gấp 2 ^ 256 lần là một con số thực sự lớn vượt quá năng lượng được lưu trữ trong vũ trụ, sử dụng E = mc2, vũ trụ sẽ cần khối lượng 2 ^ 227kg, mặt trời của chúng ta là 2 ^ 101kg vì vậy đó là 2 ^ 126 mặt trời!
Skizz

31
@Skizz: Điều này chỉ đúng với các cuộc tấn công vũ phu. Khi một sơ đồ mã hóa bị "phá vỡ", điều đó có nghĩa là nó có thể được giải quyết trong thời gian ngắn hơn so với lực lượng vũ phu, nhưng thời gian giải quyết vẫn tỷ lệ thuận với kích thước khóa.
Steven Sudit

1
@StevenSudit: tỷ lệ với số mũ của kích thước khóa (trừ khi P == NP)
Ihar Bury

1
@Orlangur Tỷ lệ thuận với kích thước khóa được đo bằng bit.
Steven Sudit

137

Tất nhiên GUID có thể va chạm. Vì GUID là 128 bit, chỉ cần tạo ra 2^128 + 1chúng và theo nguyên tắc pigeonhole thì phải có xung đột.

Nhưng khi chúng ta nói rằng GUID là duy nhất, điều chúng ta thực sự muốn nói là không gian khóa quá lớn đến nỗi thực tế không thể vô tình tạo ra cùng một GUID hai lần (giả sử rằng chúng ta đang tạo GUID một cách ngẫu nhiên).

Nếu bạn tạo một chuỗi nGUID ngẫu nhiên, thì xác suất xảy ra ít nhất một vụ va chạm p(n) = 1 - exp(-n^2 / 2 * 2^128)(đây là vấn đề sinh nhật với số ngày sinh có thể xảy ra 2^128).

   n     p(n)
2^30 1.69e-21
2^40 1.77e-15
2^50 1.86e-10
2^60 1.95e-03

Để làm cho những con số cụ thể 2^60 = 1.15e+18,. Vì vậy, nếu bạn tạo ra một tỷ GUID mỗi giây, bạn sẽ mất 36 năm để tạo 2^60GUID ngẫu nhiên và thậm chí sau đó xác suất bạn có va chạm vẫn còn 1.95e-03. Bạn có nhiều khả năng bị giết vào một lúc nào đó trong cuộc đời ( 4.76e-03) hơn là bạn sẽ tìm thấy một vụ va chạm trong 36 năm tới. Chúc may mắn.


239
Nếu bạn bị sát hại tại một số thời điểm trong cuộc sống của bạn, tỷ lệ cược là nó sẽ kết thúc.
Michael Myers

25
@mmyer: Điểm tuyệt vời. Điều đó có nghĩa là cơ hội bị sát hại của tôi ngay bây giờ rất thấp, vì đây không phải là kết thúc cuộc đời tôi. Ôi, đợi đã ...
Steven Sudit

Ngoài ra, nếu hai GUID được tạo ra trong một khoảng thời gian ngắn, khả năng chúng được sử dụng trong cùng một hệ thống là không đáng kể. Do đó, điều này làm tăng tính độc đáo.
AMissico

Những con số và tham chiếu đến vấn đề sinh nhật là vô nghĩa. Các thuật toán tạo GUID không tạo ra các giá trị trên toàn bộ phạm vi với xác suất bằng nhau. Trong thực tế IIRC, thuật toán ban đầu đã sử dụng địa chỉ MAC của PC tạo + thời gian hiện tại như một phần của kết quả - giúp giảm nguy cơ va chạm với Hướng dẫn được tạo trên các PC khác, nhưng tất nhiên làm giảm không gian khóa.
Joe

17
Bạn đang cho rằng xác suất bị sát hại là một hằng số đối với tất cả con người. Nhưng rõ ràng những người viết nhận xét snide trong các bài đăng trên diễn đàn là loại người có khả năng bị giết nhiều hơn người bình thường.
Jay

61

Nếu bạn lo lắng về tính độc đáo, bạn luôn có thể mua GUID mới để bạn có thể vứt bỏ những cái cũ của mình. Tôi sẽ đưa một số lên eBay nếu bạn muốn.


13
Tuyệt vời - bao nhiêu cho bộ hoàn chỉnh, từ 0 đến (2 ^ 128) -1?
Steve314

23
Đang bán, $ 0,01 trên 1k GUID. Tôi sẽ ném vào một số chuông gió tre nếu bạn đặt hàng trong 60 phút tới.
ctacke

7
Bộ của tôi là độc quyền hơn và chất lượng cao hơn. Chúng được kiểm tra và xác minh hai lần khiến chúng có giá trị $ 1 ​​mỗi GUID. Bạn thậm chí có thể mua chúng theo đợt nếu bạn không muốn đầu tư đầy đủ trong một lần. Tôi sẽ phải tính thêm $ 10 mỗi đợt.
Thomas

3
Tôi sẽ thiết lập cho bạn một kế hoạch hàng tháng và cung cấp cho bạn các hướng dẫn không giới hạn với mức giá phù hợp. ^ Những kẻ đó đang cố gắng lừa đảo bạn và bán cho bạn những giá trị quá cao. Tôi sẽ bán cho bạn những hướng dẫn chất lượng được sản xuất tại Trung Quốc!
ErocM

47

Cá nhân, tôi nghĩ rằng "Vụ nổ lớn" đã xảy ra khi hai GUID va chạm.


4
Chỉ cần nhớ Nó cần một loại lập trình viên "đặc biệt" để làm điều đó ...
AnthonyLambert

Tôi muốn nghe lý do của bạn để lý thuyết của bạn. Tôi nghĩ rằng chúng ta có thể bắt đầu một tôn giáo mới dựa trên điều này và tuyển dụng T.Cruise!
ErocM

@ErocM; Xem "Vũ trụ học Brane" ( en.wikipedia.org/wiki/Brane_cosmology ) và "Màng (Lý thuyết M)" ( en.wikipedia.org/wiki/Membrane_(M- Theory ) ). Ý tưởng là nếu hai cần cẩu chạm vào một vũ trụ mới được tạo ra. Do đó, bạn có thể suy luận rằng nếu hai GUID chạm vào nhau, một vũ trụ mới sẽ được tạo ra.
AMissico

2
Nếu Timecop dạy chúng ta bất cứ điều gì là cùng một vấn đề không thể chiếm cùng một không gian tại bất kỳ thời điểm nào. Vì vậy, nếu hai GUID va chạm vào nhau, chúng sẽ tiêu thụ lẫn nhau và vụ nổ kết quả sẽ tạo ra một lỗ đen, nuốt chửng toàn bộ vũ trụ. Vì vậy, trong thực tế, nó sẽ không tạo ra một Vũ trụ, nó sẽ phá hủy nó.
AJC

42

Bạn có thể chỉ ra rằng trong thời gian O (1) với một biến thể của thuật toán bogosort lượng tử .

Guid g1 = Guid.NewGuid();
Guid g2 = Guid.NewGuid();
if(g1 != g2) Universe.Current.Destroy();

21
Tôi nhận được một ngoại lệ khi gọi Hủy (). Dựa trên văn bản, tôi nghĩ rằng máy tính của tôi thiếu phần cứng cần thiết để phá hủy vũ trụ hiện tại. Bạn có biết nơi tôi có thể có được nó?
Steven Sudit

11
@Steven: Nah, một số người quản lý đã quá lo lắng về việc API đó sẽ gây ảnh hưởng xấu đến công chúng như thế nào và ra lệnh nó luôn thất bại vì "lý do bảo mật". Nếu bạn nhìn vào nguồn của phương thức thì chỉ có một dòng đó : throw new MundaneHardwareException();. Dù sao, tôi nghe nói những người ở CERN có một loại Big Hadron Thingy có thể thực hiện mánh khóe ...
R. Martinho Fernandes

7
@Martinho: À, ok. Tôi sẽ xem xét thay thế Universe.Current.Destroy()bằng Cern.Lhc.DestroyThisUniverse().
Steven Sudit

61
Tôi biết có một lý do tôi lập trình ở Haskell. Những tác dụng phụ đang trở nên đáng sợ.
Edward KMett

6
"Có một lý thuyết nói rằng nếu có ai từng khám phá chính xác Vũ trụ là gì và tại sao nó ở đây, nó sẽ biến mất ngay lập tức và được thay thế bằng một thứ thậm chí kỳ lạ hơn không thể giải thích được. Có một giả thuyết khác nói rằng điều này đã xảy ra . " - Douglas Adams, Hướng dẫn về thiên hà của Hitchhiker
Mike Pirnat

28

Bất kỳ hai GUID đều rất có thể là duy nhất (không bằng nhau).

Xem mục SO này và từ Wikipedia

Mặc dù mỗi GUID được tạo không được đảm bảo là duy nhất, nhưng tổng số khóa duy nhất (2 ^ 128 hoặc 3,4 × 10 ^ 38) lớn đến mức xác suất của cùng một số được tạo hai lần là rất nhỏ. Ví dụ, hãy xem xét vũ trụ quan sát được, chứa khoảng 5 × 10 ^ 22 sao; mỗi ngôi sao sau đó có thể có 6,8 × 10 ^ 15 GUID độc nhất trên toàn cầu.

Vì vậy, có lẽ bạn phải chờ thêm hàng tỷ năm nữa và hy vọng rằng bạn đã đánh một quả trước vũ trụ như chúng ta biết nó đã kết thúc.


vậy 2 ^ 128 không phải là số chính xác của các hướng dẫn có thể?
Kai

21
Nó là. Tại sao bạn nghĩ 2 ^ 128 là một con số nhỏ?
jrockway

Có, 2 ^ 128 là số lượng chính xác của các hướng dẫn có thể.
Graviton

3
Đó là một địa ngục của một số. $ irb >> 2**128 => 340282366920938463463374607431768211456
adamJLev

45
@ Vô dụng - Ngay cả với bạn?
Austin Richardson

27

[Cập nhật:] Như các ý kiến ​​dưới đây chỉ ra, MS GUID mới hơn là V4 và không sử dụng địa chỉ MAC như một phần của thế hệ GUID (mặc dù tôi chưa thấy bất kỳ dấu hiệu nào về việc triển khai V5 từ MS, vì vậy nếu có ai có liên kết xác nhận rằng cho tôi biết). Mặc dù vậy, thời gian vẫn là một yếu tố và tỷ lệ chống lại sự trùng lặp của GUID vẫn còn nhỏ đến mức không liên quan đến bất kỳ việc sử dụng thực tế nào. Bạn chắc chắn sẽ không bao giờ tạo ra một GUID trùng lặp chỉ từ một thử nghiệm hệ thống duy nhất như OP đang cố gắng thực hiện.

Hầu hết các câu trả lời này đều thiếu một điểm quan trọng về việc triển khai GUID của Microsoft. Phần đầu tiên của GUID dựa trên dấu thời gian và phần khác dựa trên địa chỉ MAC của card mạng (hoặc một số ngẫu nhiên nếu không cài đặt NIC).

Nếu tôi hiểu điều này một cách chính xác, điều đó có nghĩa là cách duy nhất đáng tin cậy để sao chép GUID là chạy các thế hệ GUID đồng thời trên nhiều máy trong đó các địa chỉ MAC giống nhau VÀ trong đó các đồng hồ trên cả hai hệ thống đều ở cùng một thời điểm khi tạo ra xảy ra (dấu thời gian dựa trên mili giây nếu tôi hiểu chính xác) .... thậm chí sau đó có rất nhiều bit khác trong số là ngẫu nhiên, do đó, tỷ lệ cược vẫn còn nhỏ.

Đối với tất cả các mục đích thực tế, GUID là duy nhất trên toàn cầu.

Có một mô tả khá hay về MS GUID tại blog "The Old New Thing"


3
Đó thực sự là có thể làm được khi sử dụng ảo hóa. Bạn có thể và bạn nhận được các hướng dẫn trùng lặp.
Goran

8
Raymond đã lỗi thời trên phần Địa chỉ MAC, Microsoft không sử dụng chúng nữa. Xem en.wikipedia.org/wiki/GUID#Alacticm để biết sự khác biệt giữa Hướng dẫn V1 và V4.
Michael Stum

1
Đây không còn là trường hợp. Sơ đồ V5 hiện tại chỉ là 128 bit của lòng tốt giả ngẫu nhiên thuần túy.
Edward KMett

thật buồn cười khi bạn nói mọi thứ tôi đã làm muộn hơn tôi một tháng và bạn được 16 điểm và tôi vẫn còn 0?
AnthonyLambert

1
Ya Tony, có một cái gì đó kỳ lạ với điều đó. Quay lại khi tôi trả lời bài đăng, chỉ có 3 hoặc 4 câu trả lời và tôi không nhớ đã nhìn thấy bài viết của bạn ... nếu tôi có, tôi chỉ cần nâng cấp nó. Tôi thường không trả lời các câu hỏi khi đã có câu trả lời khác đủ để trả lời đủ (đó là lý do tại sao tôi có một đại diện khá thấp có lẽ).
Stephen M. Redd

23

Đây là một phương thức mở rộng nhỏ tiện lợi mà bạn có thể sử dụng nếu bạn muốn kiểm tra tính duy nhất của hướng dẫn ở nhiều nơi trong mã của bạn.

internal static class GuidExt
{
    public static bool IsUnique(this Guid guid)
    {
        while (guid != Guid.NewGuid())
        { }
        return false;
    }
}

Để gọi nó, chỉ cần gọi Guid.IsUnique bất cứ khi nào bạn tạo một hướng dẫn mới ...

Guid g = Guid.NewGuid();
if (!g.IsUnique())
{
    throw new GuidIsNotUniqueException();
}

... Chết tiệt, tôi thậm chí còn khuyên bạn nên gọi nó hai lần để đảm bảo rằng nó đã đúng trong vòng đầu tiên.


2
Làm thế nào điều này đảm bảo rằng this guidchưa bao giờ được tạo ra ở bất cứ nơi nào khác trên thế giới này? : p Heck chúng ta cần một nhóm hướng dẫn thế giới. :)
nawfal

19

Đếm đến 2 ^ 128 - đầy tham vọng.

Hãy tưởng tượng rằng chúng ta có thể đếm 2 ^ 32 ID mỗi giây trên mỗi máy - không phải vậy tham vọng, vì nó thậm chí không 4,3 tỷ mỗi giây. Hãy dành 2 ^ 32 máy cho nhiệm vụ đó. Hơn nữa, chúng ta hãy lấy 2 ^ 32 nền văn minh cho mỗi tài nguyên dành cho cùng một nhiệm vụ.

Cho đến nay, chúng ta có thể đếm được 2 ^ 96 ID mỗi giây, nghĩa là chúng ta sẽ đếm được 2 ^ 32 giây (hơn 136 năm một chút).

Bây giờ, tất cả những gì chúng ta cần là để có được 4.294.967.296 nền văn minh cho mỗi cống hiến 4.294.967.296 máy, mỗi máy có khả năng đếm 4.294.967.296 ID mỗi giây, hoàn toàn cho nhiệm vụ này trong 136 năm tới hoặc lâu hơn - tôi đề nghị chúng ta bắt đầu ngay nhiệm vụ này trong 136 năm tới -)


17

Chà, nếu thời gian hoạt động 83 tỷ năm không làm bạn sợ, hãy nghĩ rằng bạn cũng sẽ cần lưu trữ các GUID được tạo ở đâu đó để kiểm tra xem bạn có trùng lặp hay không; lưu trữ 2 ^ 128 số 16 byte sẽ chỉ yêu cầu bạn phân bổ 4951760157141521099596496896 terabyte RAM phía trước, vì vậy hãy tưởng tượng bạn có một máy tính có thể phù hợp với tất cả những thứ đó và bằng cách nào đó bạn sẽ tìm thấy một nơi để mua DIMM terabyte với giá 10 gram mỗi cái nặng hơn 8 khối Trái đất, do đó bạn có thể nghiêm túc dịch chuyển nó khỏi quỹ đạo hiện tại, trước khi bạn nhấn "Chạy". Nghĩ kĩ!


12
for(begin; begin<end; begin)
    Console.WriteLine(System.Guid.NewGuid().ToString());

Bạn không tăng beginnên điều kiện begin < endluôn luôn đúng.


1
không - vì tôi không thể lặp lại bigint
Kai

3
Có thực sự quan trọng nếu anh ta lặp đi lặp lại mãi mãi so với vòng lặp 340282366920938463463374607431768211456 lần?
Jay

3
vậy ... bạn thà bị đấm 340282366920938463463374607431768211456 lần hay mãi mãi!?!?!?!?
ErocM

thực sự đây là những gì thực sự trả lời cho câu hỏi! và không có phiếu bầu nào cả: p
nawfal


9

Có lẽ bạn có lý do để tin rằng thuật toán tạo Guids không tạo ra các số thực sự ngẫu nhiên, nhưng thực tế là đang đi xe đạp với khoảng thời gian << 2 ^ 128.

ví dụ: phương pháp RFC4122 được sử dụng để lấy GUID để sửa các giá trị của một số bit.

Bằng chứng về việc đi xe đạp sẽ phụ thuộc vào kích thước có thể của thời kỳ.

Trong các khoảng thời gian nhỏ, bảng băm băm (GUID) -> GUID thay thế khi va chạm nếu GUID không khớp (chấm dứt nếu có) có thể là một cách tiếp cận. Cũng xem xét chỉ thực hiện thay thế một phần ngẫu nhiên của thời gian.

Cuối cùng, nếu khoảng thời gian tối đa giữa các va chạm đủ lớn (và không được biết trước), bất kỳ phương pháp nào sẽ chỉ mang lại xác suất rằng sự va chạm sẽ được tìm thấy nếu nó tồn tại.

Lưu ý rằng nếu phương thức tạo Hướng dẫn dựa trên đồng hồ (xem RFC), thì có thể không xác định được liệu có xảy ra va chạm hay không vì (a) bạn sẽ không thể đợi đủ lâu để đồng hồ quấn tròn, hoặc (b) bạn không thể yêu cầu đủ Hướng dẫn trong tích tắc đồng hồ để buộc va chạm.

Ngoài ra, bạn có thể hiển thị mối quan hệ thống kê giữa các bit trong Hướng dẫn hoặc tương quan giữa các bit giữa các Hướng dẫn. Một mối quan hệ như vậy có thể làm cho rất có khả năng thuật toán bị lỗi mà không nhất thiết có thể tìm thấy một sự va chạm thực sự.

Tất nhiên, nếu bạn chỉ muốn chứng minh rằng Guids có thể va chạm, thì một bằng chứng toán học, không phải là một chương trình, là câu trả lời.


8

Tôi không hiểu tại sao không ai đề cập đến việc nâng cấp card đồ họa của bạn ... Chắc chắn nếu bạn có NVIDIA Quadro FX 4800 cao cấp hoặc thứ gì đó (192 lõi CUDA) thì điều này sẽ nhanh hơn ...

Tất nhiên, nếu bạn có thể mua một vài chiếc NVIDIA Qadro Plex 2200 S4 (ở mức 960 lõi CUDA mỗi cái), phép tính này sẽ thực sự hét lên. Có lẽ NVIDIA sẽ sẵn sàng cho bạn mượn một vài thứ để "Trình diễn công nghệ" như một người đóng thế PR?

Chắc chắn họ muốn trở thành một phần của tính toán lịch sử này ...


hmmmm ..... Tôi có thể chạy nó trên lưới 10.000 nút của chúng tôi tại nơi làm việc.
AnthonyLambert

8

Nhưng bạn phải chắc chắn rằng bạn có một bản sao, hoặc bạn chỉ quan tâm nếu có thể có một bản sao. Để chắc chắn rằng bạn có hai người có cùng ngày sinh, bạn cần có 365 người (không tính năm nhuận). Để có nhiều hơn 50% cơ hội có hai người có cùng ngày sinh, bạn chỉ cần 23 người. Đó là vấn đề sinh nhật .

Nếu bạn có 32 bit, bạn chỉ cần 77.163 giá trị để có cơ hội trùng lặp lớn hơn 50%. Dùng thử:

Random baseRandom = new Random(0);

int DuplicateIntegerTest(int interations)
{
    Random r = new Random(baseRandom.Next());
    int[] ints = new int[interations];
    for (int i = 0; i < ints.Length; i++)
    {
        ints[i] = r.Next();
    }
    Array.Sort(ints);
    for (int i = 1; i < ints.Length; i++)
    {
        if (ints[i] == ints[i - 1])
            return 1;
    }
    return 0;
}

void DoTest()
{
    baseRandom = new Random(0);
    int count = 0;
    int duplicates = 0;
    for (int i = 0; i < 1000; i++)
    {
        count++;
        duplicates += DuplicateIntegerTest(77163);
    }
    Console.WriteLine("{0} iterations had {1} with duplicates", count, duplicates);
}

1000 iterations had 737 with duplicates

Bây giờ 128 bit là rất nhiều, vì vậy bạn vẫn đang nói một số lượng lớn các mặt hàng vẫn cho bạn khả năng va chạm thấp. Bạn sẽ cần số lượng bản ghi sau cho các tỷ lệ cược nhất định bằng cách sử dụng xấp xỉ:

  • 0,8 tỷ đồng cho 1/1000 khả năng xảy ra va chạm
  • 21,7 tỷ tỷ đồng cho 50% khả năng xảy ra va chạm
  • 39,6 tỷ tỷ đồng cho 90% khả năng xảy ra va chạm

Có khoảng 1E14 email được gửi mỗi năm, vì vậy sẽ có khoảng 400.000 năm ở cấp độ này trước khi bạn có 90% cơ hội có hai với cùng một GUID, nhưng điều đó khác rất nhiều so với việc bạn cần chạy máy tính 83 tỷ nhân đôi tuổi của vũ trụ hoặc mặt trời sẽ lạnh đi trước khi tìm thấy bản sao.


7

Không phải tất cả các bạn đang thiếu một điểm chính?

Tôi nghĩ rằng GUID được tạo bằng hai thứ khiến cho khả năng chúng là độc nhất toàn cầu khá cao. Một là chúng được gieo bằng địa chỉ MAC của máy bạn đang bật và hai chúng sử dụng thời gian chúng được tạo cộng với một số ngẫu nhiên.

Vì vậy, trừ khi bạn chạy nó trên máy thực tế và chạy tất cả những gì bạn đoán trong khoảng thời gian nhỏ nhất mà máy sử dụng để biểu thị thời gian trong GUID, bạn sẽ không bao giờ tạo ra cùng một số cho dù bạn có bao nhiêu lần đoán sử dụng cuộc gọi hệ thống.

Tôi đoán nếu bạn biết cách thực hiện GUID thực sự sẽ rút ngắn thời gian đoán khá đáng kể.

Tony


3
Không phải tất cả các GUID được tạo theo cách này. Ngay cả khi chúng là như vậy, Kai chỉ cần đợi cho đến khi dấu thời gian được sử dụng để tạo kết thúc GUID trong khoảng thời gian đủ cho lần sử dụng để tạo GUID được sử dụng lại.
Dour High Arch

3
Các hướng dẫn không được dựa trên địa chỉ mac kể từ năm 2000 hoặc 2001. Kể từ một trong các gói dịch vụ cho NT4 và / hoặc Win2k, chúng đã thay đổi thuật toán hoàn toàn. Bây giờ chúng được tạo bởi một trình tạo số ngẫu nhiên, trừ một vài bit xác định loại hướng dẫn đó là gì.
KristoferA

4
không phải tất cả các GUID đều đến từ các nền tảng windows ...
AnthonyLambert

OP đề cập đến C #, vì vậy đó là Windows. Bên cạnh đó, V4 GUID có phải là thứ chỉ dành cho Windows không?
Steven Sudit

5
@Martinho: À, nhưng bài kiểm tra đơn vị của Mono cho Guid, trong GuidTest.cs, chứa một phương thức tạo hai GUID mới và kiểm tra xem chúng có bằng nhau không, nếu chúng bằng nhau. Khi Mono xây dựng thành công, chúng tôi có thể hoàn toàn chắc chắn rằng GUID của nó là duy nhất! :-)
Steven Sudit

6

Bạn có thể băm các GUID. Bằng cách đó, bạn sẽ nhận được một kết quả nhanh hơn nhiều.

Ồ, tất nhiên, chạy nhiều luồng cùng một lúc cũng là một ý tưởng hay, theo cách đó, bạn sẽ tăng cơ hội điều kiện cuộc đua tạo ra cùng một GUID hai lần trên các luồng khác nhau.


6

GUID là 124 bit vì 4 bit giữ số phiên bản.


lý do không thêm điều này như một bình luận: không ai đề cập đến nó và tôi không biết tôi nên nói điều này với ai. :)
Behrooz

Hooooraaaay tôi đã làm điều đó. Trong một số ứng dụng "thực sự" tôi đã viết, tôi đã có một vụ va chạm Guid trong một bảng có ~ 260k Hàng. (MSSQL 2008 R2 Express).
Behrooz

6
  1. Đi đến phòng thí nghiệm cryogenics ở thành phố New York.
  2. Đóng băng bản thân trong (khoảng) 1990 năm.
  3. Nhận một công việc tại Planet Express.
  4. Mua một CPU hoàn toàn mới. Xây dựng một máy tính, chạy chương trình và đặt nó ở nơi an toàn với một máy chuyển động giả vĩnh viễn như máy ngày tận thế.
  5. Chờ cho đến khi máy thời gian được phát minh.
  6. Nhảy tới tương lai bằng cỗ máy thời gian. Nếu bạn đã mua CPU 128 bit 1YHz, hãy truy cập3,938,453,320 days 20 hours 15 minutes 38 seconds 463 ms 463 μs 374 ns 607 ps sau khi bạn bắt đầu chạy chương trình.
  7. ...?
  8. LỢI NHUẬN!!!

... Phải mất ít nhất 10,783,127vài năm ngay cả khi bạn có CPU 1YHz 1,000,000,000,000,000(hoặc1,125,899,906,842,624 nếu bạn thích sử dụng tiền tố nhị phân) nhanh hơn CPU 1GHz.

Vì vậy, thay vì chờ tính toán xong, sẽ tốt hơn nếu nuôi chim bồ câu bị mất nhà vì người khác n con bồ câu đã lấy nhà của chúng. :

Hoặc, bạn có thể đợi cho đến khi máy tính lượng tử 128 bit được phát minh. Sau đó, bạn có thể chứng minh rằng GUID không phải là duy nhất, bằng cách sử dụng chương trình của bạn trong thời gian hợp lý (có thể).


Tôi đã chờ đợi một siêu anh hùng tham khảo trong câu trả lời này - thất bại bởi poster: p - tuyệt vời không kém.
IbrarMumtaz

4

Bạn đã thử begin = begin + new BigInteger((long)1)thay thế bắt đầu ++ chưa?


2
không ai đã bỏ phiếu cho câu trả lời thực sự trả lời câu hỏi: P
nawfal

4

Nếu số lượng UUID được tạo theo luật Moore, ấn tượng về việc không bao giờ hết GUID trong tương lai gần là sai.

Với 2 ^ 128 UUID, sẽ chỉ mất 18 tháng * Log2 (2 ^ 128) ~ = 192 năm, trước khi chúng tôi hết tất cả các UUID.

Và tôi tin rằng (không có bằng chứng thống kê nào cho đến nay) trong vài năm qua kể từ khi áp dụng UUID hàng loạt, tốc độ chúng ta tạo ra UUID đang tăng nhanh hơn so với luật của Moore. Nói cách khác, có lẽ chúng ta có ít hơn 192 năm cho đến khi chúng ta phải đối phó với khủng hoảng UUID, điều đó sớm hơn rất nhiều so với sự kết thúc của vũ trụ.

Nhưng vì chúng tôi chắc chắn sẽ không sử dụng chúng vào cuối năm 2012, chúng tôi sẽ để nó cho các loài khác lo lắng về vấn đề này.


3

Tỷ lệ của một lỗi trong mã tạo GUID cao hơn nhiều so với tỷ lệ của thuật toán tạo ra xung đột. Tỷ lệ lỗi trong mã của bạn để kiểm tra GUID thậm chí còn lớn hơn. Bỏ cuộc.


2

Chương trình, mặc dù có lỗi, cho thấy bằng chứng rằng GUID không phải là duy nhất. Những người cố gắng chứng minh điều ngược lại đang thiếu điểm. Tuyên bố này chỉ chứng minh việc triển khai yếu một số biến thể GUID.

GUID không cần thiết là duy nhất theo định nghĩa, nó rất độc đáo theo định nghĩa. Bạn chỉ cần tinh chỉnh ý nghĩa của cao. Tùy thuộc vào phiên bản, người triển khai (MS hoặc người khác), sử dụng VM, v.v. định nghĩa của bạn về những thay đổi cao. (xem liên kết trong bài trước)

Bạn có thể rút ngắn bảng 128 bit để chứng minh quan điểm của mình. Giải pháp tốt nhất là sử dụng công thức băm để rút ngắn bảng của bạn với các bản sao và sau đó sử dụng toàn bộ giá trị khi hàm băm va chạm và dựa vào đó tạo lại GUID. Nếu chạy từ các vị trí khác nhau, bạn sẽ lưu trữ cặp băm / khóa đầy đủ của mình ở một vị trí trung tâm.

Ps: Nếu mục tiêu chỉ là tạo ra số x giá trị khác nhau, hãy tạo bảng băm có chiều rộng này và chỉ cần kiểm tra giá trị băm.


2

Không phải p ** s trên lửa trại ở đây, nhưng nó thực sự xảy ra, và vâng, tôi hiểu trò đùa mà bạn đã cho anh chàng này, nhưng về nguyên tắc, GUID là duy nhất, tôi đã va vào chủ đề này vì có một lỗi trong trình giả lập WP7, có nghĩa là mỗi lần khởi động, nó đưa ra CÙNG HƯỚNG DẪN lần đầu tiên được gọi! Vì vậy, trong lý thuyết bạn không thể có xung đột, nếu có vấn đề tạo GUI nói trên, thì bạn có thể nhận được các bản sao

http://forums.create.msdn.com/forums/p/92086/597310.aspx#597310


1

Do một phần của thế hệ Guid dựa trên thời gian của máy hiện tại, nên lý thuyết của tôi để có một Guid trùng lặp là:

  1. Thực hiện cài đặt Windows sạch
  2. Tạo một kịch bản khởi động đặt lại thời gian đến 2010-01-01 12:00:00 ngay khi Windows khởi động.
  3. Ngay sau tập lệnh khởi động, nó kích hoạt ứng dụng của bạn để tạo Hướng dẫn.
  4. Sao chép cài đặt Windows này, để bạn loại trừ bất kỳ sự khác biệt tinh tế nào có thể xảy ra trong các lần khởi động tiếp theo.
  5. Hình ảnh lại ổ cứng với hình ảnh này và khởi động máy một vài lần.

0

Đối với tôi .. thời gian để một lõi đơn tạo ra UUIDv1 đảm bảo nó sẽ là duy nhất. Ngay cả trong tình huống đa lõi nếu trình tạo UUID chỉ cho phép tạo một UUID tại một thời điểm cho tài nguyên cụ thể của bạn (hãy nhớ rằng nhiều tài nguyên hoàn toàn có thể sử dụng cùng một UUID nhưng không chắc là tài nguyên vốn là một phần của địa chỉ) sẽ có quá nhiều UUID để kéo dài bạn cho đến khi dấu thời gian cháy hết. Tại thời điểm đó tôi thực sự nghi ngờ bạn sẽ quan tâm.


0

Đây cũng là một giải pháp:

int main()
{
  QUuid uuid;
  while ( (uuid = QUuid::createUuid()) != QUuid::createUuid() ) { }
  std::cout << "Aha! I've found one! " << qPrintable( uuid.toString() ) << std::endl;
}

Lưu ý: yêu cầu Qt, nhưng tôi đảm bảo rằng nếu bạn để nó chạy đủ lâu, nó có thể tìm thấy một.

(Lưu ý lưu ý: thực ra, bây giờ khi tôi nhìn vào nó, có thể có điều gì đó về thuật toán tạo ngăn chặn hai uuids được tạo sau đó va chạm với nhau - nhưng tôi hơi nghi ngờ về điều đó).


0

Giải pháp duy nhất để chứng minh GUID không phải là duy nhất là có World GUID Pool. Mỗi khi GUID được tạo ở đâu đó, nó sẽ được đăng ký cho tổ chức. Hoặc heck, chúng tôi có thể bao gồm một tiêu chuẩn hóa mà tất cả các trình tạo GUID cần phải đăng ký tự động và vì nó cần kết nối internet hoạt động!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.