Bukti sederhana bahwa GUID tidak unik [ditutup]

323

Saya ingin membuktikan bahwa GUID tidak unik dalam program pengujian sederhana. Saya berharap kode berikut akan berjalan selama berjam-jam, tetapi tidak berfungsi. Bagaimana saya bisa membuatnya bekerja?

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

Saya menggunakan C #.

Kai
sumber
107
Sebagai pengembang perangkat lunak, apa yang akan Anda katakan jika pengguna mendatangi Anda dan berkata "itu tidak berfungsi"?
JoshJordan
152
Tunggu beberapa triliun tahun.
hobbs
67
Upmodded karena ini adalah hal paling lucu yang pernah saya lihat online hari ini.
jrockway
32
@jrockway - lol. Saya mengalami kesulitan menemukan sesuatu tentang pertanyaan ini yang pada dasarnya tidak salah. Semakin lama saya melihatnya, semakin lucu.
tylerl
243
Ini hanya unik secara global, jadi hanya unik di planet kita. Jika Anda menginginkan id yang benar-benar unik, Anda perlu menggunakan id unik universal (UUID). Saya berasumsi bahwa Anda hanya tertarik pada keunikan di dalam alam semesta kita. :-)
tvanfosson

Jawaban:

407

Kai, saya telah menyediakan program yang akan melakukan apa yang Anda inginkan menggunakan utas. Ini dilisensikan dengan ketentuan berikut: Anda harus membayar saya $ 0,0001 per jam per inti CPU Anda menjalankannya. Biaya dibayarkan pada akhir setiap bulan kalender. Silakan hubungi saya untuk detail akun paypal saya pada kenyamanan Anda.

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: Saya ingin mencoba pustaka ekstensi Paralel. Itu mudah.

Dan menggunakan OutOfMemoryException sebagai aliran kontrol terasa salah.

EDIT

Yah, sepertinya ini masih menarik suara. Jadi saya telah memperbaiki masalah GC.KeepAlive (). Dan mengubahnya untuk dijalankan dengan C # 4.

Dan untuk memperjelas persyaratan dukungan saya: dukungan hanya tersedia pada 28 / Feb / 2010. Harap gunakan mesin waktu untuk membuat permintaan dukungan hanya pada hari itu.

EDIT 2 Seperti biasa, GC melakukan pekerjaan yang lebih baik daripada yang saya lakukan dalam mengelola memori; setiap upaya sebelumnya untuk melakukannya sendiri akan gagal.

ligos
sumber
120
Konsol terakhir itu. WriteLine membuatku tertawa sangat keras. Saya pikir Anda harus melempar CommonlyAcceptedCosmologicTheoriesWrongExceptionsaja.
R. Martinho Fernandes
17
apakah menandai ini sebagai Diterima juga berarti bahwa @ Kai menerima persyaratan yang ditentukan oleh @ligos?
kb.
3
Pengaturan reserveSomeRam = null;sebenarnya tidak mencapai apa-apa.
DevinB
4
@devinb tolong jelaskan? sepertinya membebaskan byte yang sebelumnya dialokasikan sehingga GC dapat Collect()melakukannya. Mengapa itu tidak mencapai apa-apa?
mythz
3
GuidCollisionDetector. Nama memiliki potensi
Ufuk Hacıoğulları
226

Ini akan berjalan lebih dari beberapa jam. Dengan asumsi loop pada 1 GHz (yang tidak akan - itu akan jauh lebih lambat dari itu), itu akan berjalan selama 107902830708060146089187070 tahun. Yaitu sekitar 83 miliar kali lebih lama dari usia alam semesta.

Dengan asumsi hukum Moores berlaku, akan jauh lebih cepat untuk tidak menjalankan program ini, menunggu beberapa ratus tahun dan menjalankannya di komputer yang milyaran kali lebih cepat. Faktanya, setiap program yang membutuhkan waktu lebih lama untuk berjalan daripada yang dibutuhkan kecepatan CPU menjadi dua kali lipat (sekitar 18 bulan) akan selesai lebih cepat jika Anda menunggu sampai kecepatan CPU meningkat dan membeli CPU baru sebelum menjalankannya (kecuali jika Anda menulisnya sehingga dapat ditangguhkan dan dilanjutkan pada perangkat keras baru).

rjmunro
sumber
27
sialan - jadi mungkin benang serveral yang menghasilkan pengarah adalah ide yang lebih baik?
Kai
107
4 utas pada prosesor quad core akan membuatnya berjalan dalam 20 miliar kali usia alam semesta - jadi ya, itu akan banyak membantu.
rjmunro
34
Saya curiga ini adalah troll, tetapi jika tidak demikian: utasnya tidak magis. Jika Anda dapat melakukan satu miliar operasi per detik pada satu utas, maka menuju ke sepuluh utas berarti masing-masing menjalankan 1/10 kali lebih sering. Setiap utas melakukan operasi 100 M per detik; jumlah total operasi per detik tidak bertambah. Cara meningkatkan jumlah operasi per detik adalah dengan membeli lebih banyak komputer. Misalkan Anda membeli satu miliar lebih komputer. Itu akan mengurangi masalah untuk hanya mengambil 10790283070806 tahun, yang masih lebih dari empat jam.
Eric Lippert
10
Saya pikir rjmunro mengasumsikan setiap utas akan berjalan pada inti yang terpisah; 83 miliar alam semesta / 4 inti memang kira-kira sama dengan 20 miliar alam semesta. Saatnya membeli saham Intel!
Dour High Arch
4
@Erik 83 miliar prosesor berarti bahwa Anda akan dapat melakukannya dalam waktu yang sudah ada sejauh ini. Jadi bahkan itu tidak cukup.
rjmunro
170

GUID secara teori tidak unik. Ini buktinya:

  • GUID adalah nomor 128 bit
  • Anda tidak dapat membuat 2 ^ 128 + 1 atau lebih GUID tanpa menggunakan kembali GUID lama

Namun, jika seluruh output daya matahari diarahkan untuk melakukan tugas ini, itu akan menjadi dingin jauh sebelum selesai.

GUID dapat dihasilkan menggunakan sejumlah taktik yang berbeda, beberapa di antaranya mengambil langkah-langkah khusus untuk menjamin bahwa mesin yang diberikan tidak akan menghasilkan GUID yang sama dua kali. Menemukan tabrakan dalam algoritma tertentu akan menunjukkan bahwa metode khusus Anda untuk menghasilkan GUID adalah buruk, tetapi tidak akan membuktikan apa pun tentang GUID secara umum.

tylerl
sumber
44
Prinsip Pigeonhole untuk menyelamatkan!
yfeldblum
22
+1 untuk komentar dingin matahari. Ada komentar yang menarik di suatu tempat tentang tidak ada gunanya kunci enkripsi> 256 bit. Untuk mengulangi semua nilai kunci yang mungkin akan membutuhkan lebih banyak energi daripada yang dimiliki seluruh alam semesta. Beralih sedikit dalam CPU membutuhkan energi dalam jumlah kecil (inilah yang menghasilkan panas) yang, ketika dikalikan 2 ^ 256 kali adalah jumlah yang sangat besar melebihi energi yang tersimpan di alam semesta, menggunakan E = mc2 alam semesta akan membutuhkan massa 2 ^ 227kg, matahari kita 2 ^ 101kg jadi itu 2 ^ 126 matahari!
Skizz
31
@ Skizz: Ini berlaku untuk serangan brute force saja. Ketika skema enkripsi "rusak", itu berarti bahwa skema itu dapat diselesaikan dalam waktu kurang dari brute force, tetapi waktu penyelesaiannya tetap sebanding dengan ukuran kunci.
Steven Sudit
1
@StevenSudit: sebanding dengan eksponen ukuran kunci (kecuali P == NP)
Ihar Bury
1
@Orlangur Proporsional dengan ukuran kunci yang diukur dalam bit.
Steven Sudit
137

Tentu saja GUID dapat bertabrakan. Karena GUID adalah 128-bit, hasilkan saja 2^128 + 1dari mereka dan dengan prinsip pigeonhole harus ada tabrakan.

Tetapi ketika kita mengatakan bahwa GUID adalah unik, yang sebenarnya kita maksudkan adalah ruang kuncinya sangat besar sehingga praktis mustahil untuk secara tidak sengaja menghasilkan GUID yang sama dua kali (dengan asumsi bahwa kita membuat GUID secara acak).

Jika Anda membuat urutan nGUID secara acak, maka kemungkinan setidaknya satu tabrakan kira-kira p(n) = 1 - exp(-n^2 / 2 * 2^128)(ini adalah masalah ulang tahun dengan jumlah kemungkinan ulang tahun yang mungkin 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

Untuk membuat angka-angka ini konkret 2^60 = 1.15e+18,. Jadi, jika Anda menghasilkan satu miliar GUID per detik, Anda butuh 36 tahun untuk menghasilkan 2^60GUID acak dan bahkan kemungkinan Anda mengalami tabrakan masih 1.95e-03. Anda lebih mungkin terbunuh pada titik tertentu dalam hidup Anda ( 4.76e-03) daripada Anda akan menemukan tabrakan selama 36 tahun ke depan. Semoga berhasil.

Jason
sumber
239
Jika Anda dibunuh pada titik tertentu dalam hidup Anda, kemungkinan itu akan berakhir.
Michael Myers
25
@mmyers: Poin luar biasa. Itu berarti peluang saya untuk dibunuh sekarang sangat rendah, karena ini bukan akhir dari hidup saya. Oh, tunggu ...
Steven Sudit
Juga, jika dua GUID kebetulan dibuat dalam waktu singkat, kemungkinan mereka digunakan dalam sistem yang sama sedikit. Karena itu, ini meningkatkan keunikan.
AMissico
Angka-angka ini dan referensi untuk masalah ulang tahun tidak ada artinya. Algoritme pembuatan GUID tidak menghasilkan nilai pada seluruh rentang dengan probabilitas yang sama. Sebenarnya IIRC algoritma asli menggunakan alamat MAC dari PC yang menghasilkan + waktu saat ini sebagai bagian dari hasil - yang mengurangi risiko tabrakan dengan Panduan yang dihasilkan pada PC lain, tetapi tentu saja mengurangi ruang kunci.
Joe
17
Anda berasumsi bahwa kemungkinan dibunuh adalah konstan untuk semua manusia. Tetapi jelas orang-orang yang menulis komentar sinis di posting forum adalah tipe orang yang lebih mungkin dibunuh daripada orang kebanyakan.
Jay
61

Jika Anda khawatir tentang keunikan, Anda selalu dapat membeli GUID baru sehingga Anda dapat membuang yang lama. Saya akan memasang beberapa di eBay jika Anda mau.

ctacke
sumber
13
Keren - berapa banyak untuk set lengkap, dari 0 hingga (2 ^ 128) -1?
Steve314
23
Dijual, $ 0,01 per 1k GUID. Saya akan melempar lonceng angin bambu jika Anda memesan dalam 60 menit ke depan.
ctacke
7
Perangkat saya lebih eksklusif dan berkualitas lebih tinggi. Mereka diperiksa dua kali dan diverifikasi yang membuat mereka bernilai $ 1 per GUID. Anda bahkan dapat membelinya dalam batch jika Anda tidak ingin melakukan investasi penuh dalam sekali jalan. Saya harus membebankan biaya tambahan $ 10 per batch.
Thomas
3
Saya akan mengatur Anda pada rencana bulanan dan memberi Anda panduan tanpa batas untuk harga yang tepat. ^ Orang-orang itu mencoba menipu Anda dan menjual kepada Anda harga mahal. Saya akan menjual Anda panduan berkualitas buatan China!
ErocM
47

Secara pribadi, saya pikir "Big Bang" disebabkan ketika dua GUID bertabrakan.

AMissico
sumber
4
Ingat saja, dibutuhkan pemrogram "khusus" untuk melakukan itu ...
AnthonyLambert
Saya ingin mendengar alasan Anda tentang teori Anda. Saya pikir kita bisa memulai agama baru berdasarkan ini dan merekrut T.Cruise!
ErocM
@ErocM; Lihat "Kosmologi Brane" ( en.wikipedia.org/wiki/Brane_cosmology ) dan "Membrane (M-Theory)" ( en.wikipedia.org/wiki/Membrane_(M-Theory) ). Idenya adalah jika dua bale menyentuh alam semesta baru dibuat. Oleh karena itu, Anda dapat menyimpulkan bahwa jika dua GUID bersentuhan, alam semesta baru diciptakan.
AMissico
2
Jika Timecop mengajari kita sesuatu adalah hal yang sama tidak dapat menempati ruang yang sama pada waktu tertentu. Jadi jika dua GUID dimana bertabrakan, mereka akan saling memakan dan ledakan yang dihasilkan akan menghasilkan lubang hitam, melahap seluruh alam semesta. Jadi pada kenyataannya, itu tidak akan menciptakan Semesta, itu akan menghancurkannya.
AJC
42

Anda dapat menunjukkan bahwa dalam waktu O (1) dengan varian dari algoritma bogosort kuantum .

Guid g1 = Guid.NewGuid();
Guid g2 = Guid.NewGuid();
if(g1 != g2) Universe.Current.Destroy();
R. Martinho Fernandes
sumber
21
Saya mendapatkan pengecualian saat memanggil Destroy (). Berdasarkan teks, saya pikir komputer saya tidak memiliki perangkat keras yang diperlukan untuk menghancurkan alam semesta saat ini. Apakah Anda tahu di mana saya bisa mendapatkannya?
Steven Sudit
11
@ Sebelas: Tidak, beberapa orang manajemen terlalu khawatir tentang seberapa buruk API akan terlihat ke publik, dan mendiktekannya untuk selalu gagal karena "alasan keamanan". Jika Anda melihat sumber metode ini hanya ada yang satu baris: throw new MundaneHardwareException();. Bagaimanapun, saya mendengar orang-orang di CERN memiliki semacam Big Hadron Thingy yang mungkin melakukan trik ...
R. Martinho Fernandes
7
@ Martinho: Ah, baiklah. Aku akan melihat ke dalam mengganti Universe.Current.Destroy()dengan Cern.Lhc.DestroyThisUniverse().
Steven Sudit
61
Saya tahu ada alasan saya memprogram di Haskell. Efek samping ini semakin menakutkan.
Edward KMETT
6
"Ada sebuah teori yang menyatakan bahwa jika ada orang yang menemukan apa sebenarnya alam semesta dan mengapa ia ada di sini, ia akan segera menghilang dan digantikan oleh sesuatu yang bahkan lebih tidak dapat dijelaskan. Ada teori lain yang menyatakan bahwa ini telah terjadi . " - Douglas Adams, The Hitchhiker's Guide to the Galaxy
Mike Pirnat
28

Dua GUID sangat mungkin unik (tidak sama).

Lihat entri SO ini , dan dari Wikipedia

Sementara setiap GUID yang dihasilkan tidak dijamin unik, jumlah total kunci unik (2 ^ 128 atau 3,4 × 10 ^ 38) sangat besar sehingga kemungkinan nomor yang sama dihasilkan dua kali sangat kecil. Sebagai contoh, perhatikan alam semesta yang dapat diamati, yang berisi sekitar 5 × 10 ^ 22 bintang; setiap bintang kemudian dapat memiliki 6,8 × 10 ^ 15 GUID yang unik secara universal.

Jadi mungkin Anda harus menunggu lebih dari miliaran tahun, dan berharap Anda menabrak satu sebelum alam semesta seperti yang kita tahu itu berakhir.

Graviton
sumber
jadi 2 ^ 128 bukan jumlah yang tepat dari kemungkinan panduan?
Kai
21
Ini. Menurut Anda mengapa 2 ^ 128 adalah angka kecil?
jrockway
Ya, 2 ^ 128 adalah jumlah yang benar dari kemungkinan panduan.
Graviton
3
Itu angka yang sangat besar. $ irb >> 2**128 => 340282366920938463463374607431768211456
adamJLev
45
@Infinity - Bahkan untuk Anda?
Austin Richardson
27

[Pembaruan:] Seperti komentar di bawah ini menunjukkan, GUID MS yang lebih baru adalah V4 dan tidak menggunakan alamat MAC sebagai bagian dari generasi GUID (saya belum melihat indikasi implementasi V5 dari MS, jadi jika ada yang memiliki tautan yang mengonfirmasi bahwa beri tahu saya). Namun dengan V4, waktu masih merupakan faktor, dan peluang terhadap duplikasi GUID tetap sangat kecil sehingga tidak relevan untuk penggunaan praktis apa pun. Anda tentu tidak akan pernah menghasilkan GUID duplikat dari hanya pengujian sistem tunggal seperti OP coba lakukan.

Sebagian besar jawaban ini kehilangan satu poin penting tentang implementasi GUID Microsoft. Bagian pertama dari GUID didasarkan pada timestamp dan bagian lain didasarkan pada alamat MAC dari kartu jaringan (atau nomor acak jika tidak ada NIC yang dipasang).

Jika saya memahami ini dengan benar, itu berarti bahwa satu-satunya cara yang dapat diandalkan untuk menduplikasi GUID adalah dengan menjalankan generasi GUID bersamaan pada beberapa mesin di mana alamat MAC adalah sama dan di mana jam pada kedua sistem pada waktu yang sama persis ketika generasi terjadi (stempel waktu didasarkan pada milidetik jika saya memahaminya dengan benar) .... bahkan kemudian ada banyak bit lain dalam jumlah yang acak, sehingga kemungkinannya masih sangat kecil.

Untuk semua tujuan praktis, GUID bersifat universal unik.

Ada deskripsi yang cukup bagus dari MS GUID di blog "The Old New Thing"

Stephen M. Redd
sumber
3
Itu sebenarnya bisa dilakukan ketika menggunakan virtualisasi. Anda bisa dan Anda mendapatkan duplikat panduan.
Goran
8
Raymond sudah ketinggalan zaman pada bagian Alamat MAC, Microsoft tidak menggunakannya lagi. Lihat en.wikipedia.org/wiki/GUID#Algorithm untuk perbedaan antara Panduan V1 dan V4.
Michael Stum
1
Ini bukan lagi masalahnya. Skema V5 saat ini hanya 128 bit kebaikan pseudorandom murni.
Edward KMETT
lucu bagaimana Anda menyatakan semua yang saya lakukan sebulan lebih lambat dari saya dan Anda mendapatkan 16 poin dan saya masih memiliki 0?
AnthonyLambert
1
Ya Tony, ada yang aneh dengan itu. Kembali ketika saya menjawab posting itu, hanya ada 3 atau 4 jawaban, dan saya tidak ingat melihat milik Anda ... jika saya punya, saya baru saja mengangkatnya. Saya biasanya tidak menjawab pertanyaan ketika sudah ada jawaban lain yang menutupinya dengan cukup baik (itulah sebabnya saya mungkin memiliki perwakilan keseluruhan yang agak rendah).
Stephen M. Redd
23

Berikut adalah metode ekstensi kecil yang bagus yang dapat Anda gunakan jika Anda ingin memeriksa keunikan panduan di banyak tempat dalam kode Anda.

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

Untuk menyebutnya, cukup hubungi Panduan. Unik setiap kali Anda menghasilkan panduan baru ...

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

... heck, saya bahkan merekomendasikan meneleponnya dua kali untuk memastikan itu benar di babak pertama.

KristoferA
sumber
2
Bagaimana ini memastikan yang this guidbelum pernah dihasilkan di tempat lain di dunia ini? : p Heck kita perlu kolam panduan dunia. :)
nawfal
19

Menghitung 2 ^ 128 - ambisius.

Mari kita bayangkan kita bisa menghitung 2 ^ 32 ID per detik per mesin - tidak terlalu ambisius, karena itu bahkan tidak 4,3 miliar per detik. Mari kita persembahkan 2 ^ 32 mesin untuk tugas itu. Selanjutnya, mari kita dapatkan 2 ^ 32 peradaban untuk masing-masing mendedikasikan sumber daya yang sama untuk tugas tersebut.

Sejauh ini, kita dapat menghitung 2 ^ 96 ID per detik, artinya kita akan menghitung selama 2 ^ 32 detik (sedikit lebih dari 136 tahun).

Sekarang, yang kita butuhkan adalah mendapatkan 4.294.967.296 peradaban untuk masing-masing mendedikasikan 4.294.967.296 mesin, masing-masing mesin mampu menghitung 4.294.967.296 ID per detik, murni untuk tugas ini selama 136 tahun ke depan - saya sarankan kita memulai tugas penting ini sekarang; -)

Steve314
sumber
17

Nah, jika waktu berjalan 83 miliar tahun tidak membuat Anda takut, berpikir bahwa Anda juga perlu menyimpan GUID yang dihasilkan di suatu tempat untuk memeriksa apakah Anda memiliki duplikat; menyimpan 2 ^ 128 angka 16-byte hanya akan mengharuskan Anda untuk mengalokasikan 4951760157141521099596496896 terabyte RAM dimuka, jadi bayangkan Anda memiliki komputer yang dapat menampung semua itu dan bahwa Anda entah bagaimana menemukan tempat untuk membeli DIMM terabyte dengan masing-masing 10 gram, digabungkan mereka akan timbang lebih dari 8 massa Bumi, sehingga Anda dapat dengan serius memindahkannya dari orbit saat ini, bahkan sebelum Anda menekan "Run". Berpikir dua kali!

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

Anda tidak bertambah beginsehingga kondisinya begin < endselalu benar.

Nathan Taylor
sumber
1
tidak - karena saya tidak bisa mengulang bigint
Kai
3
Apakah benar-benar penting jika ia mengulang selamanya dibandingkan mengulangi 340282366920938463463374607431768211456 kali?
Jay
3
jadi ... apakah kamu lebih suka dipukul 340282366920938463463374607431768211456 kali atau selamanya!?!?!?
ErocM
sebenarnya inilah yang benar-benar menjawab pertanyaan itu! dan tidak ada suara sama sekali: p
nawfal
11

Jika tabrakan GUID menjadi perhatian, saya akan merekomendasikan menggunakan ScottGuID sebagai gantinya.

Matt Peterson
sumber
9

Agaknya Anda memiliki alasan untuk percaya bahwa algoritma untuk menghasilkan Guids tidak menghasilkan angka yang benar-benar acak, tetapi sebenarnya bersepeda dengan periode << 2 ^ 128.

misalnya metode RFC4122 digunakan untuk memperoleh GUID yang memperbaiki nilai beberapa bit.

Bukti bersepeda akan tergantung pada ukuran yang mungkin dari periode tersebut.

Untuk periode kecil, tabel hash hash (GUID) -> GUID dengan penggantian tabrakan jika GUID tidak cocok (terminasi jika terjadi) mungkin merupakan pendekatan. Pertimbangkan juga hanya melakukan penggantian sebagian kecil dari waktu.

Pada akhirnya jika periode maksimum antara tumbukan cukup besar (dan tidak diketahui sebelumnya) metode apa pun hanya akan menghasilkan probabilitas bahwa tumbukan akan ditemukan jika ada.

Perhatikan bahwa jika metode menghasilkan Guids berbasis jam (lihat RFC), maka mungkin tidak mungkin untuk menentukan apakah tabrakan ada karena (a) Anda tidak akan bisa menunggu cukup lama untuk jam untuk membungkus putaran, atau (b) Anda tidak bisa meminta cukup Panduan dalam tanda centang jam untuk memaksa tabrakan.

Atau Anda mungkin dapat menunjukkan hubungan statistik antara bit dalam Guid, atau korelasi bit antara Guids. Hubungan seperti itu mungkin membuatnya sangat mungkin bahwa algoritma itu cacat tanpa harus mampu menemukan tabrakan yang sebenarnya.

Tentu saja, jika Anda hanya ingin membuktikan bahwa Guids dapat bertabrakan, maka bukti matematis, bukan program, adalah jawabannya.

MZB
sumber
8

Saya tidak mengerti mengapa tidak ada yang menyebutkan peningkatan kartu grafis Anda ... Tentunya jika Anda mendapatkan NVIDIA Quadro FX 4800 yang canggih atau sesuatu (192 core CUDA) ini akan lebih cepat ...

Tentu saja jika Anda mampu membeli beberapa NVIDIA Qadro Plex 2200 S4s (masing-masing pada 960 CUDA core), perhitungan ini akan sangat menjerit. Mungkin NVIDIA akan bersedia meminjamkan Anda sedikit untuk "Demonstrasi Teknologi" sebagai aksi PR?

Tentunya mereka ingin menjadi bagian dari perhitungan bersejarah ini ...

Dad
sumber
hmmmm ..... Saya bisa menjalankannya di 10.000 node grid kami di kantor
AnthonyLambert
8

Tapi apakah Anda harus memastikan Anda memiliki duplikat, atau apakah Anda hanya peduli jika ada dapat menjadi duplikat. Untuk memastikan bahwa Anda memiliki dua orang dengan ulang tahun yang sama, Anda membutuhkan 366 orang (tidak termasuk tahun kabisat). Agar ada lebih dari 50% kemungkinan memiliki dua orang dengan ulang tahun yang sama, Anda hanya perlu 23 orang. Itu masalah ulang tahun .

Jika Anda memiliki 32 bit, Anda hanya perlu 77.163 nilai untuk memiliki kemungkinan duplikat lebih dari 50%. Cobalah:

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

Sekarang 128 bit banyak, jadi Anda masih berbicara sejumlah besar item masih memberi Anda kemungkinan tabrakan yang rendah. Anda membutuhkan jumlah rekaman berikut untuk peluang yang diberikan menggunakan perkiraan:

  • 0,8 miliar miliar untuk 1/1000 kemungkinan tabrakan terjadi
  • 21,7 miliar miliar untuk kemungkinan tabrakan 50%
  • 39,6 miliar miliar untuk 90% kemungkinan tabrakan terjadi

Ada sekitar 1E14 email yang dikirim per tahun sehingga akan menjadi sekitar 400.000 tahun pada tingkat ini sebelum Anda memiliki 90% kemungkinan memiliki dua dengan GUID yang sama, tetapi itu jauh berbeda dari mengatakan Anda perlu menjalankan komputer 83 miliar kali zaman alam semesta atau bahwa matahari akan menjadi dingin sebelum menemukan duplikat.

Jason Goemaat
sumber
7

Bukankah kalian semua kehilangan satu poin utama?

Saya pikir GUID dibuat menggunakan dua hal yang membuat peluang mereka menjadi unik secara global cukup tinggi. Salah satunya adalah mereka diunggulkan dengan alamat MAC mesin yang Anda aktifkan dan dua mereka menggunakan waktu mereka dihasilkan ditambah nomor acak.

Jadi, kecuali Anda menjalankannya di mesin yang sebenarnya dan menjalankan semua yang Anda tebak dalam jumlah waktu terkecil yang digunakan mesin untuk mewakili waktu dalam GUID Anda tidak akan pernah menghasilkan nomor yang sama tidak peduli berapa banyak tebakan yang Anda lakukan menggunakan panggilan sistem.

Saya kira jika Anda tahu cara sebenarnya GUID dibuat sebenarnya akan mempersingkat waktu untuk menebak secara substansial.

Tony

AnthonyLambert
sumber
3
Tidak semua GUID dibuat dengan cara ini. Bahkan jika mereka, Kai hanya perlu menunggu sampai stempel waktu yang digunakan untuk membuat GUID membungkus waktu yang cukup untuk yang ia gunakan untuk membuat GUID digunakan lagi.
Dour High Arch
3
Panduan belum didasarkan pada alamat mac sejak 2000 atau 2001. Pada salah satu paket layanan untuk NT4 dan / atau Win2k mereka mengubah algoritme sama sekali. Mereka sekarang dihasilkan oleh generator angka acak, minus beberapa bit yang mengidentifikasi jenis panduan itu.
KristoferA
4
tidak semua GUIDs datang dari jendela platform ...
AnthonyLambert
OP menyebutkan C #, jadi itu Windows. Selain itu, apakah V4 GUID adalah hal yang hanya Windows?
Steven Sudit
5
@ Martinho: Ah, tapi unit test Mono untuk Guid, di GuidTest.cs, berisi metode yang menciptakan dua GUID baru dan memeriksa mereka untuk kesetaraan, gagal jika mereka sama. Saat Mono berhasil membangun, kita dapat benar-benar yakin bahwa GUIDnya unik! :-)
Steven Sudit
6

Anda bisa hash GUID. Dengan begitu, Anda harus mendapatkan hasil yang jauh lebih cepat.

Oh, tentu saja, menjalankan beberapa utas pada saat yang sama juga merupakan ide yang baik, dengan cara itu Anda akan meningkatkan kemungkinan kondisi balapan menghasilkan GUID yang sama dua kali pada utas yang berbeda.

Michael Stum
sumber
6

GUID adalah 124 bit karena 4 bit menampung nomor versi.

Behrooz
sumber
alasan untuk tidak menambahkan ini sebagai komentar: tidak ada yang menyebutkannya, dan saya tidak tahu kepada siapa saya harus mengatakan ini. :)
Behrooz
Hooooraaaay saya melakukannya. Dalam beberapa aplikasi "nyata" yang saya tulis, saya mendapat tabrakan Guid di tabel dengan ~ 260k Rows. (MSSQL 2008 R2 Express).
Behrooz
6
  1. Pergi ke lab cryogenics di New York City.
  2. Bekukan diri Anda selama (kira-kira) 1990 tahun.
  3. Dapatkan pekerjaan di Planet Express.
  4. Beli CPU baru. Bangun komputer, jalankan program, dan letakkan di tempat yang aman dengan mesin gerakan semu abadi seperti mesin kiamat.
  5. Tunggu sampai mesin waktu ditemukan.
  6. Lompat ke masa depan menggunakan mesin waktu. Jika Anda membeli CPU 1YHz 128bit, kunjungi3,938,453,320 days 20 hours 15 minutes 38 seconds 463 ms 463 μs 374 ns 607 ps setelah Anda mulai menjalankan program.
  7. ...?
  8. KEUNTUNGAN!!!

... Butuh setidaknya 10,783,127bertahun-tahun bahkan jika Anda memiliki 1YHz CPU yang 1,000,000,000,000,000(atau 1,125,899,906,842,624jika Anda lebih suka menggunakan awalan biner) kali lebih cepat dari CPU 1GHz.

Jadi, daripada menunggu penghitungan selesai, lebih baik memberi makan merpati yang kehilangan tempat tinggal karena nmerpati lain membawa pulang. :(

Atau, Anda dapat menunggu hingga komputer kuantum 128-bit ditemukan. Maka Anda dapat membuktikan bahwa GUID tidak unik, dengan menggunakan program Anda dalam waktu yang wajar (mungkin).

JiminP
sumber
Saya sedang menunggu referensi pahlawan super dalam jawaban ini - gagal oleh poster: p - mengagumkan tidak kurang.
IbrarMumtaz
4

Sudahkah Anda mencoba begin = begin + new BigInteger((long)1)menggantikan ++?

RCIX
sumber
2
tidak ada yang memilih jawaban yang benar - benar menjawab pertanyaan: P
nawfal
4

Jika jumlah UUID yang dihasilkan mengikuti hukum Moore, kesan tidak pernah kehabisan GUID di masa mendatang adalah salah.

Dengan 2 ^ 128 UUID, hanya butuh 18 bulan * Log2 (2 ^ 128) ~ = 192 tahun, sebelum kita kehabisan semua UUID.

Dan saya percaya (tanpa bukti statistik apa pun) dalam beberapa tahun terakhir sejak adopsi massal UUID, kecepatan kita menghasilkan UUID meningkat jauh lebih cepat daripada yang didiktekan hukum Moore. Dengan kata lain, kita mungkin memiliki waktu kurang dari 192 tahun sampai kita harus berurusan dengan krisis UUID, itu jauh lebih cepat daripada akhir jagat raya.

Tapi karena kita pasti tidak akan kehabisan pada akhir 2012, kita akan menyerahkannya pada spesies lain untuk khawatir tentang masalahnya.

Bill Yang
sumber
3

Peluang bug dalam kode penghasil GUID jauh lebih tinggi daripada peluang algoritma menghasilkan tabrakan. Peluang bug dalam kode Anda untuk menguji GUID bahkan lebih besar. Menyerah.

Mark tebusan
sumber
2

Program, meskipun kesalahannya, menunjukkan bukti bahwa GUID tidak unik. Mereka yang mencoba membuktikan yang sebaliknya tidak ada gunanya. Pernyataan ini hanya membuktikan lemahnya implementasi beberapa variasi GUID.

GUID tidak perlu unik menurut definisi, itu sangat unik menurut definisi. Anda hanya memperhalus arti dari sangat. Tergantung pada versi, implementator (MS atau yang lain), penggunaan VM, dll definisi Anda sangat berubah. (lihat tautan di posting sebelumnya)

Anda dapat mempersingkat tabel 128 bit Anda untuk membuktikan maksud Anda. Solusi terbaik adalah dengan menggunakan rumus hash untuk mempersingkat tabel Anda dengan duplikat, dan kemudian menggunakan nilai penuh setelah hash bertabrakan dan berdasarkan itu menghasilkan kembali GUID. Jika berjalan dari lokasi yang berbeda, Anda akan menyimpan pasangan hash / kunci penuh Anda di lokasi pusat.

Ps: Jika tujuannya hanya untuk menghasilkan x jumlah nilai yang berbeda, buat tabel hash dengan lebar ini dan cukup periksa pada nilai hash.

ydebilloez
sumber
2

Tidak p ** s di api unggun di sini, tapi itu benar-benar terjadi, dan ya, saya mengerti bercanda Anda telah memberikan orang ini, tetapi GUID hanya unik pada prinsipnya, saya menabrak utas ini karena ada bug di emulator WP7 yang berarti setiap kali boot itu memberikan PANDUAN SAMA pertama kali disebut! Jadi, di mana secara teori Anda tidak dapat memiliki konflik, jika ada masalah menghasilkan kata GUI, maka Anda bisa mendapatkan duplikat

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

Ben
sumber
1

Karena bagian dari generasi Guid didasarkan pada waktu mesin saat ini, teori saya untuk mendapatkan duplikat Guid adalah:

  1. Lakukan instalasi Windows yang bersih
  2. Buat skrip startup yang me-reset waktu ke 2010-01-01 12:00:00 seperti Windows boot up.
  3. Tepat setelah skrip startup, itu memicu aplikasi Anda untuk menghasilkan Guid.
  4. Mengkloning instalasi Windows ini, sehingga Anda mengesampingkan perbedaan halus yang mungkin terjadi pada boot-up berikutnya.
  5. Bayangkan kembali hard drive dengan gambar ini dan boot-up mesin beberapa kali.
realworldcoder
sumber
0

Bagi saya .. waktu yang diperlukan untuk satu inti untuk menghasilkan jaminan UUIDv1 akan unik. Bahkan dalam situasi multi-inti jika generator UUID hanya memungkinkan satu UUID dihasilkan pada satu waktu untuk sumber daya spesifik Anda (ingatlah bahwa banyak sumber daya dapat sepenuhnya menggunakan UUID yang sama namun tidak mungkin karena sumber daya itu secara inheren merupakan bagian dari alamat) maka Anda akan memiliki lebih dari cukup UUID untuk bertahan hingga cap waktu habis. Pada titik mana saya benar-benar ragu Anda akan peduli.

lebih panas
sumber
0

Ini solusinya juga:

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

Catatan: membutuhkan Qt, tetapi saya jamin jika Anda membiarkannya berjalan cukup lama, mungkin akan menemukannya.

(Catatan: sebenarnya, sekarang saya sedang melihatnya, mungkin ada sesuatu tentang algoritma generasi yang mencegah dua uuids yang dihasilkan kemudian bertabrakan - tapi saya agak ragu).

Scott
sumber
0

Satu-satunya solusi untuk membuktikan GUID tidak unik adalah dengan memiliki World GUID Pool. Setiap kali GUID dibuat di suatu tempat, itu harus didaftarkan ke organisasi. Atau, kami mungkin menyertakan standardisasi bahwa semua generator GUID perlu mendaftarkannya secara otomatis dan untuk itu diperlukan koneksi internet aktif!

nawfal
sumber