Jadi saya telah melakukan beberapa penggalian di sekitar dan saya telah mencoba untuk mengumpulkan fungsi yang menghasilkan UUID v4 yang valid dalam PHP. Ini adalah yang terdekat yang bisa saya datangi. Pengetahuan saya tentang hex, desimal, biner, operator bitwise PHP dan sejenisnya hampir tidak ada. Fungsi ini menghasilkan UUID v4 yang valid hingga satu area. UUID v4 harus dalam bentuk:
xxxxxxxx- xxxx- 4 xxx- y xxx-xxxxxxxxxxxx
di mana y adalah 8, 9, A, atau B. Di sinilah fungsi gagal karena tidak mematuhi itu.
Saya berharap seseorang dengan pengetahuan lebih dari saya di bidang ini dapat membantu saya dan membantu saya memperbaiki fungsi ini sehingga mematuhi aturan itu.
Fungsinya sebagai berikut:
<?php
function gen_uuid() {
$uuid = array(
'time_low' => 0,
'time_mid' => 0,
'time_hi' => 0,
'clock_seq_hi' => 0,
'clock_seq_low' => 0,
'node' => array()
);
$uuid['time_low'] = mt_rand(0, 0xffff) + (mt_rand(0, 0xffff) << 16);
$uuid['time_mid'] = mt_rand(0, 0xffff);
$uuid['time_hi'] = (4 << 12) | (mt_rand(0, 0x1000));
$uuid['clock_seq_hi'] = (1 << 7) | (mt_rand(0, 128));
$uuid['clock_seq_low'] = mt_rand(0, 255);
for ($i = 0; $i < 6; $i++) {
$uuid['node'][$i] = mt_rand(0, 255);
}
$uuid = sprintf('%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x',
$uuid['time_low'],
$uuid['time_mid'],
$uuid['time_hi'],
$uuid['clock_seq_hi'],
$uuid['clock_seq_low'],
$uuid['node'][0],
$uuid['node'][1],
$uuid['node'][2],
$uuid['node'][3],
$uuid['node'][4],
$uuid['node'][5]
);
return $uuid;
}
?>
Terima kasih kepada siapa pun yang dapat membantu saya.
$newId = exec('uuidgen -r');
Jawaban:
Diambil dari komentar ini di manual PHP, Anda dapat menggunakan ini:
sumber
Alih-alih memecahnya menjadi bidang individu, lebih mudah untuk menghasilkan blok data acak dan mengubah posisi byte individu. Anda juga harus menggunakan generator nomor acak yang lebih baik daripada mt_rand ().
Menurut RFC 4122 - Bagian 4.4 , Anda perlu mengubah bidang ini:
time_hi_and_version
(bit 4-7 dari oktet 7),clock_seq_hi_and_reserved
(bit 6 & 7 dari 9 oktet)Semua 122 bit lainnya harus cukup acak.
Pendekatan berikut menghasilkan 128 bit data acak menggunakan
openssl_random_pseudo_bytes()
, membuat permutasi pada oktet dan kemudian menggunakanbin2hex()
danvsprintf()
untuk melakukan pemformatan akhir.Dengan PHP 7, menghasilkan urutan byte acak bahkan lebih sederhana menggunakan
random_bytes()
:sumber
$data = file_get_contents('/dev/urandom', NULL, NULL, 0, 16);
$data = $data ?? random_bytes( 16 );
Sekarang Anda BISA menentukan sumber data acak Anda sendiri, atau biarkan fungsi melakukannya untuk Anda. :-)Siapa pun yang menggunakan dependensi komposer , Anda mungkin ingin mempertimbangkan perpustakaan ini: https://github.com/ramsey/uuid
Tidak ada yang lebih mudah dari ini:
sumber
pada sistem unix, gunakan kernel sistem untuk menghasilkan uuid untuk Anda.
Kredit Samveen di https://serverfault.com/a/529319/210994
sumber
/dev/random
yang memblokir jika kumpulan entropi habis./dev/urandom
, yang menurut saya tidak akan melelahkan, tetapi berisiko mengembalikan uuids duplikat. Saya kira itu tradeoff; apakah Anda benar-benar membutuhkan id unik yang dipengaruhi oleh entropi sistem?Dalam pencarian saya untuk membuat u4 v4, saya datang pertama ke halaman ini, kemudian menemukan ini di http://php.net/manual/en/function.com-create-guid.php
kredit: pavel.volyntsev
Sunting: untuk memperjelas, fungsi ini akan selalu memberi Anda v4 uuid (PHP> = 5.3.0).
Ketika fungsi com_create_guid tersedia (biasanya hanya di Windows), ia akan menggunakannya dan menghapus kurung kurawal.
Jika tidak ada (Linux), itu akan kembali ke fungsi opensl_random_pseudo_bytes acak yang kuat ini, kemudian akan menggunakan vsprintf untuk memformatnya menjadi v4 uuid.
sumber
Jawaban saya didasarkan pada komentar pengguna uniqid komentar tetapi menggunakan fungsi openssl_random_pseudo_bytes untuk menghasilkan string acak, bukan membaca dari
/dev/urandom
sumber
Jika Anda menggunakan,
CakePHP
Anda dapat menggunakan metode merekaCakeText::uuid();
dari kelas CakeText untuk menghasilkan uFC RFC4122.sumber
Sedikit variasi pada jawaban Jack untuk menambahkan dukungan untuk PHP <7:
sumber
Terinspirasi oleh jawaban broofa di sini .
Atau jika tidak dapat menggunakan fungsi anonim.
sumber
mt_rand()
tidak dijamin keacakan.Setelah mencari hal yang persis sama dan hampir mengimplementasikan versi ini sendiri, saya pikir layak menyebutkan bahwa, jika Anda melakukan ini dalam kerangka WordPress , WP memiliki fungsi super-praktis sendiri untuk hal ini:
$myUUID = wp_generate_uuid4();
Anda dapat membaca deskripsi dan sumbernya di sini .
sumber
false
🤷Bagaimana kalau menggunakan mysql untuk menghasilkan uuid untuk Anda?
sumber
UUID()
Fungsi MySQL menciptakan v1 uuids.sumber
Dari tom, di http://www.php.net/manual/en/function.uniqid.php
sumber
/dev/urandom
harus baik -/dev/random
hanya digunakan untuk pembuatan kunci kriptografi jangka panjang.mt_rand()
jika tidak ada pelamun yang tersedia.random_bytes()
di PHP 7 dan pergilah :-)Saya yakin ada cara yang lebih elegan untuk melakukan konversi dari biner ke desimal untuk bagian
4xxx
danyxxx
. Tetapi jika Anda ingin menggunakanopenssl_random_pseudo_bytes
sebagai penghasil angka yang aman secara crytografis, inilah yang saya gunakan:sumber
Gunakan Symfony Polyfill / Uuid
Kemudian Anda bisa menghasilkan uuid sebagai fungsi php asli:
Lebih lanjut tentang hal itu, baca di posting resmi Symfony - https://symfony.com/blog/introducing-the-new-symfony-uuid-polyfill
sumber