Rev 13 | Rev 16 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 13 | Rev 14 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | <?php |
1 | <?php |
2 | 2 | ||
3 | /* |
3 | /* |
4 | * UUID utils for PHP |
4 | * UUID utils for PHP |
5 | * Copyright 2011-2020 Daniel Marschall, ViaThinkSoft |
5 | * Copyright 2011 - 2020 Daniel Marschall, ViaThinkSoft |
6 | * Version 2020-09-12 |
6 | * Version 2020-11-14 |
7 | * |
7 | * |
8 | * Licensed under the Apache License, Version 2.0 (the "License"); |
8 | * Licensed under the Apache License, Version 2.0 (the "License"); |
9 | * you may not use this file except in compliance with the License. |
9 | * you may not use this file except in compliance with the License. |
10 | * You may obtain a copy of the License at |
10 | * You may obtain a copy of the License at |
11 | * |
11 | * |
Line 18... | Line 18... | ||
18 | * limitations under the License. |
18 | * limitations under the License. |
19 | */ |
19 | */ |
20 | 20 | ||
21 | # This library requires either the GMP extension (or BCMath if gmp_supplement.inc.php is present) |
21 | # This library requires either the GMP extension (or BCMath if gmp_supplement.inc.php is present) |
22 | 22 | ||
23 | if (file_exists(__DIR__ . '/mac_utils.inc.phps')) include_once __DIR__ . '/mac_utils.inc.phps'; |
23 | if (file_exists(__DIR__ . '/mac_utils.inc.phps')) include_once __DIR__ . '/mac_utils.inc.phps'; // optionally used for uuid_info() |
24 | if (file_exists(__DIR__ . '/gmp_supplement.inc.php')) include_once __DIR__ . '/gmp_supplement.inc.php'; |
24 | if (file_exists(__DIR__ . '/gmp_supplement.inc.php')) include_once __DIR__ . '/gmp_supplement.inc.php'; |
25 | 25 | ||
26 | define('UUID_NAMEBASED_NS_DNS', '6ba7b810-9dad-11d1-80b4-00c04fd430c8'); |
26 | define('UUID_NAMEBASED_NS_DNS', '6ba7b810-9dad-11d1-80b4-00c04fd430c8'); |
27 | define('UUID_NAMEBASED_NS_URL', '6ba7b811-9dad-11d1-80b4-00c04fd430c8'); |
27 | define('UUID_NAMEBASED_NS_URL', '6ba7b811-9dad-11d1-80b4-00c04fd430c8'); |
28 | define('UUID_NAMEBASED_NS_OID', '6ba7b812-9dad-11d1-80b4-00c04fd430c8'); |
28 | define('UUID_NAMEBASED_NS_OID', '6ba7b812-9dad-11d1-80b4-00c04fd430c8'); |
Line 339... | Line 339... | ||
339 | $x = gmp_init($uuid, 16); |
339 | $x = gmp_init($uuid, 16); |
340 | return '2.25.'.gmp_strval($x, 10); # TODO: parameter with or without leading dot |
340 | return '2.25.'.gmp_strval($x, 10); # TODO: parameter with or without leading dot |
341 | } |
341 | } |
342 | 342 | ||
343 | function gen_uuid($prefer_timebased = true) { |
343 | function gen_uuid($prefer_timebased = true) { |
344 | if ($prefer_timebased) $uuid = gen_uuid_timebased(); |
344 | $uuid = $prefer_timebased ? gen_uuid_timebased() : false; |
345 | if ($uuid === false) $uuid = gen_uuid_random(); |
345 | if ($uuid === false) $uuid = gen_uuid_random(); |
346 | return $uuid; |
346 | return $uuid; |
347 | } |
347 | } |
348 | 348 | ||
349 | // Version 1 (Time based) UUID |
349 | // Version 1 (Time based) UUID |
350 | function gen_uuid_timebased() { |
350 | function gen_uuid_timebased() { |
351 | # On Debian: aptitude install php-uuid |
351 | # On Debian: apt-get install php-uuid |
352 | # extension_loaded('uuid') |
352 | # extension_loaded('uuid') |
353 | if (function_exists('uuid_create')) { |
353 | if (function_exists('uuid_create')) { |
354 | # OSSP uuid extension like seen in php5-uuid at Debian 8 |
354 | # OSSP uuid extension like seen in php5-uuid at Debian 8 |
355 | /* |
355 | /* |
356 | $x = uuid_create($context); |
356 | $x = uuid_create($context); |
Line 361... | Line 361... | ||
361 | 361 | ||
362 | # PECL uuid extension like seen in php-uuid at Debian 9 |
362 | # PECL uuid extension like seen in php-uuid at Debian 9 |
363 | return trim(uuid_create(UUID_TYPE_TIME)); |
363 | return trim(uuid_create(UUID_TYPE_TIME)); |
364 | } |
364 | } |
365 | 365 | ||
366 | # On Debian: aptitude install uuid-runtime |
366 | # On Debian: apt-get install uuid-runtime |
- | 367 | if (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') { |
|
367 | $out = array(); |
368 | $out = array(); |
368 | $ec = -1; |
369 | $ec = -1; |
369 | exec('uuidgen -t', $out, $ec); |
370 | exec('uuidgen -t 2>/dev/null', $out, $ec); |
370 | if ($ec == 0) return $out[0]; |
371 | if ($ec == 0) return $out[0]; |
- | 372 | } |
|
- | 373 | ||
- | 374 | # If we hadn't any success yet, then implement the time based generation routine ourselves! |
|
- | 375 | # Based on https://github.com/fredriklindberg/class.uuid.php/blob/master/class.uuid.php |
|
- | 376 | ||
- | 377 | $uuid = array( |
|
- | 378 | 'time_low' => 0, /* 32-bit */ |
|
- | 379 | 'time_mid' => 0, /* 16-bit */ |
|
- | 380 | 'time_hi' => 0, /* 16-bit */ |
|
- | 381 | 'clock_seq_hi' => 0, /* 8-bit */ |
|
- | 382 | 'clock_seq_low' => 0, /* 8-bit */ |
|
- | 383 | 'node' => array() /* 48-bit */ |
|
- | 384 | ); |
|
- | 385 | ||
- | 386 | /* |
|
- | 387 | * Get current time in 100 ns intervals. The magic value |
|
- | 388 | * is the offset between UNIX epoch and the UUID UTC |
|
- | 389 | * time base October 15, 1582. |
|
- | 390 | */ |
|
- | 391 | $tp = gettimeofday(); |
|
- | 392 | $time = ($tp['sec'] * 10000000) + ($tp['usec'] * 10) + 0x01B21DD213814000; |
|
371 | 393 | ||
- | 394 | $uuid['time_low'] = $time & 0xffffffff; |
|
- | 395 | /* Work around PHP 32-bit bit-operation limits */ |
|
- | 396 | $high = intval($time / 0xffffffff); |
|
- | 397 | $uuid['time_mid'] = $high & 0xffff; |
|
- | 398 | $uuid['time_hi'] = (($high >> 16) & 0xfff) | (1/*TimeBased*/ << 12); |
|
- | 399 | ||
- | 400 | /* |
|
372 | # TODO: Implement the time based generation routine ourselves! |
401 | * We don't support saved state information and generate |
- | 402 | * a random clock sequence each time. |
|
- | 403 | */ |
|
- | 404 | $uuid['clock_seq_hi'] = 0x80 | mt_rand(0, 64); |
|
- | 405 | $uuid['clock_seq_low'] = mt_rand(0, 255); |
|
- | 406 | ||
- | 407 | /* |
|
- | 408 | * Node should be set to the 48-bit IEEE node identifier |
|
- | 409 | */ |
|
- | 410 | $mac = get_mac_address(); |
|
- | 411 | if ($mac) { |
|
- | 412 | $node = str_replace(':','',$mac); |
|
- | 413 | for ($i = 0; $i < 6; $i++) { |
|
- | 414 | $uuid['node'][$i] = hexdec(substr($node, $i*2, 2)); |
|
- | 415 | } |
|
- | 416 | ||
- | 417 | /* |
|
- | 418 | * Now output the UUID |
|
- | 419 | */ |
|
- | 420 | return sprintf( |
|
- | 421 | '%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x', |
|
- | 422 | ($uuid['time_low']), ($uuid['time_mid']), ($uuid['time_hi']), |
|
- | 423 | $uuid['clock_seq_hi'], $uuid['clock_seq_low'], |
|
- | 424 | $uuid['node'][0], $uuid['node'][1], $uuid['node'][2], |
|
- | 425 | $uuid['node'][3], $uuid['node'][4], $uuid['node'][5]); |
|
- | 426 | } |
|
- | 427 | ||
373 | # At the moment we cannot determine the time based UUID |
428 | # We cannot generate the timebased UUID! |
374 | return false; |
429 | return false; |
375 | } |
430 | } |
376 | 431 | ||
- | 432 | function get_mac_address() { |
|
- | 433 | static $detected_mac = false; |
|
- | 434 | ||
- | 435 | if ($detected_mac !== false) { // false NOT null! |
|
- | 436 | return $detected_mac; |
|
- | 437 | } |
|
- | 438 | ||
- | 439 | // TODO: This should actually be part of mac_utils.inc.php, but we need it |
|
- | 440 | // here, and mac_utils.inc.php shall only be optional. What to do? |
|
- | 441 | if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { |
|
- | 442 | // Windows |
|
- | 443 | $cmds = array( |
|
- | 444 | "ipconfig /all", // faster |
|
- | 445 | "getmac" |
|
- | 446 | ); |
|
- | 447 | foreach ($cmds as $cmd) { |
|
- | 448 | $out = array(); |
|
- | 449 | $ec = -1; |
|
- | 450 | exec($cmd, $out, $ec); |
|
- | 451 | if ($ec == 0) { |
|
- | 452 | $out = implode("\n",$out); |
|
- | 453 | $m = array(); |
|
- | 454 | if (preg_match("/([0-9a-f]{2}\\-[0-9a-f]{2}\\-[0-9a-f]{2}\\-[0-9a-f]{2}\\-[0-9a-f]{2}\\-[0-9a-f]{2})/ismU", $out, $m)) { |
|
- | 455 | $detected_mac = str_replace('-', ':', strtolower($m[1])); |
|
- | 456 | return $detected_mac; |
|
- | 457 | } |
|
- | 458 | } |
|
- | 459 | } |
|
- | 460 | } else if (strtoupper(PHP_OS) == 'DARWIN') { |
|
- | 461 | // Mac OS X |
|
- | 462 | $cmds = array( |
|
- | 463 | "networksetup -listallhardwareports 2>/dev/null", |
|
- | 464 | "netstat -i 2>/dev/null" |
|
- | 465 | ); |
|
- | 466 | foreach ($cmds as $cmd) { |
|
- | 467 | $out = array(); |
|
- | 468 | $ec = -1; |
|
- | 469 | exec($cmd, $out, $ec); |
|
- | 470 | if ($ec == 0) { |
|
- | 471 | $out = implode("\n",$out); |
|
- | 472 | $m = array(); |
|
- | 473 | if (preg_match("/([0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2})/ismU", $out, $m)) { |
|
- | 474 | $detected_mac = $m[1]; |
|
- | 475 | return $detected_mac; |
|
- | 476 | } |
|
- | 477 | } |
|
- | 478 | } |
|
- | 479 | } else { |
|
- | 480 | // Linux |
|
- | 481 | foreach (glob('/sys/class/net/'.'*'.'/address') as $x) { |
|
- | 482 | if (!strstr($x,'/lo/')) { |
|
- | 483 | $detected_mac = trim(file_get_contents($x)); |
|
- | 484 | return $detected_mac; |
|
- | 485 | } |
|
- | 486 | } |
|
- | 487 | $cmds = array( |
|
- | 488 | "netstat -ie 2>/dev/null", |
|
- | 489 | "ifconfig 2>/dev/null" // only available for root (because it is in sbin) |
|
- | 490 | ); |
|
- | 491 | foreach ($cmds as $cmd) { |
|
- | 492 | $out = array(); |
|
- | 493 | $ec = -1; |
|
- | 494 | exec($cmd, $out, $ec); |
|
- | 495 | if ($ec == 0) { |
|
- | 496 | $out = implode("\n",$out); |
|
- | 497 | $m = array(); |
|
- | 498 | if (preg_match("/([0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2})/ismU", $out, $m)) { |
|
- | 499 | $detected_mac = $m[1]; |
|
- | 500 | return $detected_mac; |
|
- | 501 | } |
|
- | 502 | } |
|
- | 503 | } |
|
- | 504 | } |
|
- | 505 | ||
- | 506 | $detected_mac = null; |
|
- | 507 | return $detected_mac; |
|
- | 508 | } |
|
- | 509 | ||
377 | // Version 2 (DCE Security) UUID |
510 | // Version 2 (DCE Security) UUID |
378 | function gen_uuid_dce($domain, $id) { |
511 | function gen_uuid_dce($domain, $id) { |
379 | # Start with a version 1 UUID |
512 | # Start with a version 1 UUID |
380 | $uuid = gen_uuid_timebased(); |
513 | $uuid = gen_uuid_timebased(); |
381 | 514 | ||
Line 409... | Line 542... | ||
409 | substr($hash, 20, 12); |
542 | substr($hash, 20, 12); |
410 | } |
543 | } |
411 | 544 | ||
412 | // Version 4 (Random) UUID |
545 | // Version 4 (Random) UUID |
413 | function gen_uuid_random() { |
546 | function gen_uuid_random() { |
414 | # On Debian: aptitude install php-uuid |
547 | # On Debian: apt-get install php-uuid |
415 | # extension_loaded('uuid') |
548 | # extension_loaded('uuid') |
416 | if (function_exists('uuid_create')) { |
549 | if (function_exists('uuid_create')) { |
417 | # OSSP uuid extension like seen in php5-uuid at Debian 8 |
550 | # OSSP uuid extension like seen in php5-uuid at Debian 8 |
418 | /* |
551 | /* |
419 | $x = uuid_create($context); |
552 | $x = uuid_create($context); |
Line 424... | Line 557... | ||
424 | 557 | ||
425 | # PECL uuid extension like seen in php-uuid at Debian 9 |
558 | # PECL uuid extension like seen in php-uuid at Debian 9 |
426 | return trim(uuid_create(UUID_TYPE_RANDOM)); |
559 | return trim(uuid_create(UUID_TYPE_RANDOM)); |
427 | } |
560 | } |
428 | 561 | ||
- | 562 | if (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') { |
|
429 | # On Debian: aptitude install uuid-runtime |
563 | # On Debian: apt-get install uuid-runtime |
430 | $out = array(); |
564 | $out = array(); |
431 | $ec = -1; |
565 | $ec = -1; |
432 | exec('uuidgen -r', $out, $ec); |
566 | exec('uuidgen -r 2>/dev/null', $out, $ec); |
433 | if ($ec == 0) return $out[0]; |
567 | if ($ec == 0) return $out[0]; |
434 | 568 | ||
435 | # On Debian Jessie: UUID V4 (Random) |
569 | # On Debian Jessie: UUID V4 (Random) |
436 | if (file_exists('/proc/sys/kernel/random/uuid')) { |
570 | if (file_exists('/proc/sys/kernel/random/uuid')) { |
437 | return file_get_contents('/proc/sys/kernel/random/uuid'); |
571 | return file_get_contents('/proc/sys/kernel/random/uuid'); |
438 | } |
572 | } |
- | 573 | } |
|
439 | 574 | ||
440 | # Make the UUID by ourselves |
575 | # Make the UUID by ourselves |
441 | # Source: http://rogerstringer.com/2013/11/15/generate-uuids-php |
576 | # Source: http://rogerstringer.com/2013/11/15/generate-uuids-php |
442 | return sprintf( '%04x%04x-%04x-%04x-%04x-%04x%04x%04x', |
577 | return sprintf( '%04x%04x-%04x-%04x-%04x-%04x%04x%04x', |
443 | mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), |
578 | mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), |