Subversion Repositories oidplus

Rev

Rev 194 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
17 daniel-mar 1
<?php
2
 
90 daniel-mar 3
/*
4
 * UUID utils for PHP
5
 * Copyright 2011-2019 Daniel Marschall, ViaThinkSoft
194 daniel-mar 6
 * Version 2019-11-04
90 daniel-mar 7
 *
8
 * Licensed under the Apache License, Version 2.0 (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
11
 *
12
 *     http://www.apache.org/licenses/LICENSE-2.0
13
 *
14
 * Unless required by applicable law or agreed to in writing, software
15
 * distributed under the License is distributed on an "AS IS" BASIS,
16
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
 * See the License for the specific language governing permissions and
18
 * limitations under the License.
19
 */
17 daniel-mar 20
 
179 daniel-mar 21
if (file_exists(__DIR__ . '/mac_utils.inc.phps')) include_once __DIR__ . '/mac_utils.inc.phps';
208 daniel-mar 22
if (file_exists(__DIR__ . '/gmp_supplement.inc.php')) include_once __DIR__ . '/gmp_supplement.inc.php';
17 daniel-mar 23
 
24
define('UUID_NAMEBASED_NS_DNS',     '6ba7b810-9dad-11d1-80b4-00c04fd430c8');
25
define('UUID_NAMEBASED_NS_URL',     '6ba7b811-9dad-11d1-80b4-00c04fd430c8');
26
define('UUID_NAMEBASED_NS_OID',     '6ba7b812-9dad-11d1-80b4-00c04fd430c8');
27
define('UUID_NAMEBASED_NS_X500_DN', '6ba7b814-9dad-11d1-80b4-00c04fd430c8');
28
 
29
function uuid_valid($uuid) {
30
        $uuid = str_replace(array('-', '{', '}'), '', $uuid);
31
        $uuid = strtoupper($uuid);
32
 
33
        if (strlen($uuid) != 32) return false;
34
 
35
        $uuid = preg_replace('@[0-9A-F]@', '', $uuid);
36
 
37
        return ($uuid == '');
38
}
39
 
191 daniel-mar 40
# TODO: Don't echo
17 daniel-mar 41
function uuid_info($uuid) {
42
        if (!uuid_valid($uuid)) return false;
43
 
44
        # $uuid = str_replace(array('-', '{', '}'), '', $uuid);
45
        $uuid = strtoupper($uuid);
46
        $uuid = preg_replace('@[^0-9A-F]@', '', $uuid);
47
 
48
        $x = hexdec(substr($uuid, 16, 1));
49
             if ($x >= 14 /* 1110 */) $variant = 3;
50
        else if ($x >= 12 /* 1100 */) $variant = 2;
51
        else if ($x >=  8 /* 1000 */) $variant = 1;
52
        else if ($x >=  0 /* 0000 */) $variant = 0;
53
 
54
 
55
        switch ($variant) {
56
                case 0:
57
                        echo sprintf("%-24s %s\n", "Variant:", "[0xx] NCS (reserved for backward compatibility)");
58
 
59
                        /*
60
                         * Internal structure of variant #0 UUIDs
61
                         *
62
                         * The first 6 octets are the number of 4 usec units of time that have
63
                         * passed since 1/1/80 0000 GMT.  The next 2 octets are reserved for
64
                         * future use.  The next octet is an address family.  The next 7 octets
65
                         * are a host ID in the form allowed by the specified address family.
66
                         *
67
                         * Note that while the family field (octet 8) was originally conceived
68
                         * of as being able to hold values in the range [0..255], only [0..13]
69
                         * were ever used.  Thus, the 2 MSB of this field are always 0 and are
70
                         * used to distinguish old and current UUID forms.
71
                         *
72
                         * +--------------------------------------------------------------+
73
                         * |                    high 32 bits of time                      |  0-3  .time_high
74
                         * +-------------------------------+-------------------------------
75
                         * |     low 16 bits of time       |  4-5               .time_low
76
                         * +-------+-----------------------+
77
                         * |         reserved              |  6-7               .reserved
78
                         * +---------------+---------------+
79
                         * |    family     |   8                                .family
80
                         * +---------------+----------...-----+
81
                         * |            node ID               |  9-16           .node
82
                         * +--------------------------...-----+
83
                         *
84
                         */
85
 
86
                        // Example of an UUID: 333a2276-0000-0000-0d00-00809c000000
87
 
88
                        # TODO: See https://github.com/cjsv/uuid/blob/master/Doc
89
 
90
                        # Timestamp: Count of 4us intervals since 01 Jan 1980 00:00:00 GMT
91
                        # 1/0,000004 = 250000
92
                        # Seconds between 1970 and 1980 : 315532800
93
                        # 250000*315532800=78883200000000
94
                        $timestamp = substr($uuid, 0, 12);
95
                        $ts = gmp_init($timestamp, 16);
96
                        $ts = gmp_add($ts, gmp_init("78883200000000"));
193 daniel-mar 97
                        $ms = gmp_mod($ts, gmp_init("250000"));
17 daniel-mar 98
                        $ts = gmp_div($ts, gmp_init("250000"));
99
                        $ts = gmp_strval($ts);
100
                        $ms = gmp_strval($ms);
193 daniel-mar 101
                        $ts = gmdate('Y-m-d H:i:s', $ts)."'".str_pad($ms, 7, '0', STR_PAD_LEFT).' GMT';
102
                        echo sprintf("%-24s %s\n", "Timestamp:", "[0x$timestamp] $ts");
17 daniel-mar 103
 
104
                        $reserved = substr($uuid, 12, 4);
105
                        echo sprintf("%-24s %s\n", "Reserved:", "0x$reserved");
106
 
107
                        # Family 13 (dds) looks like node is 00 | nnnnnn 000000.
108
                        # Family 2 is presumably (ip).
109
                        # Not sure if anything else was used.
110
                        $family_hex = substr($uuid, 16, 2);
111
                        $family_dec = hexdec($family_hex);
112
                        if ($family_dec == 2) {
113
                                $family_ = 'IP';
114
                        } else if ($family_dec == 13) {
115
                                $family_ = 'DDS (Data Link)';
116
                        } else {
193 daniel-mar 117
                                $family_ = "Unknown ($family_dec)"; # There are probably no more families
17 daniel-mar 118
                        }
119
                        echo sprintf("%-24s %s\n", "Family:", "[0x$family_hex = $family_dec] $family_");
120
 
121
                        $nodeid = substr($uuid, 18, 14);
122
                        echo sprintf("%-24s %s\n", "Node ID:", "0x$nodeid");
123
                        # TODO: interprete node id (the family specifies it)
124
 
125
                        break;
126
                case 1:
127
                        echo sprintf("%-24s %s\n", "Variant:", "[10x] RFC 4122 (Leach-Mealling-Salz)");
128
 
129
                        $version = hexdec(substr($uuid, 12, 1));
130
                        switch ($version) {
131
                                case 1:
132
                                        echo sprintf("%-24s %s\n", "Version:", "[1] Time-based with unique random host identifier");
133
 
134
                                        # Timestamp: Count of 100ns intervals since 15 Oct 1582 00:00:00
135
                                        # 1/0,0000001 = 10000000
136
                                        $timestamp = substr($uuid, 13, 3).substr($uuid, 8, 4).substr($uuid, 0, 8);
137
                                        $ts = gmp_init($timestamp, 16);
138
                                        $ts = gmp_sub($ts, gmp_init("122192928000000000"));
193 daniel-mar 139
                                        $ms = gmp_mod($ts, gmp_init("10000000"));
17 daniel-mar 140
                                        $ts = gmp_div($ts, gmp_init("10000000"));
141
                                        $ts = gmp_strval($ts);
142
                                        $ms = gmp_strval($ms);
193 daniel-mar 143
                                        $ts = gmdate('Y-m-d H:i:s', $ts)."'".str_pad($ms, 7, '0', STR_PAD_LEFT).' GMT';
144
                                        echo sprintf("%-24s %s\n", "Timestamp:", "[0x$timestamp] $ts");
17 daniel-mar 145
 
146
                                        $x = hexdec(substr($uuid, 16, 4));
193 daniel-mar 147
                                        $dec = $x & 0x3FFF; // The highest 2 bits are used by "variant" (10x)
148
                                        $hex = substr($uuid, 16, 4);
149
                                        echo sprintf("%-24s %s\n", "Clock ID:", "[0x$hex] $dec");
17 daniel-mar 150
 
151
                                        $x = substr($uuid, 20, 12);
152
                                        $nodeid = '';
153
                                        for ($i=0; $i<6; $i++) {
154
                                                $nodeid .= substr($x, $i*2, 2);
155
                                                if ($i != 5) $nodeid .= ':';
156
                                        }
157
                                        echo sprintf("%-24s %s\n", "Node ID:", "$nodeid");
158
 
159
                                        if (function_exists('decode_mac')) {
160
                                                echo "\nIn case that this Node ID is a MAC address, here is the interpretation of that MAC address:\n";
161
                                                echo decode_mac($nodeid);
162
                                        }
163
 
164
                                        break;
165
                                case 2:
193 daniel-mar 166
                                        echo sprintf("%-24s %s\n", "Version:", "[2] DCE Security version");
17 daniel-mar 167
 
168
                                        # The time_low field (which represents an integer in the range [0, 232-1]) is interpreted as a local-ID; that is, an identifier (within the domain specified by clock_seq_low) meaningful to the local host. In the particular case of a POSIX host, when combined with a POSIX UID or POSIX GID domain in the clock_seq_low field (above), the time_low field represents a POSIX UID or POSIX GID, respectively.
169
                                        $x = substr($uuid, 0, 8);
170
                                        echo sprintf("%-24s %s\n", "Local ID:", "0x$x");
171
 
172
                                        # The clock_seq_low field (which represents an integer in the range [0, 28-1]) is interpreted as a local domain (as represented by sec_rgy_domain_t; see sec_rgy_domain_t ); that is, an identifier domain meaningful to the local host. (Note that the data type sec_rgy_domain_t can potentially hold values outside the range [0, 28-1]; however, the only values currently registered are in the range [0, 2], so this type mismatch is not significant.) In the particular case of a POSIX host, the value sec_rgy_domain_person is to be interpreted as the "POSIX UID domain", and the value sec_rgy_domain_group is to be interpreted as the "POSIX GID domain".
193 daniel-mar 173
                                        $x = substr($uuid, 18, 2);
174
                                        if ($x == '00') $domain_info = 'POSIX: User-ID / Non-POSIX: site-defined';
175
                                        else if ($x == '01') $domain_info = 'POSIX: Group-ID / Non-POSIX: site-defined';
176
                                        else $domain_info = 'site-defined';
177
                                        echo sprintf("%-24s %s\n", "Local Domain:", "0x$x ($domain_info)");
17 daniel-mar 178
 
179
                                        # Timestamp: Count of 100ns intervals since 15 Oct 1582 00:00:00
180
                                        # 1/0,0000001 = 10000000
193 daniel-mar 181
                                        $timestamp = substr($uuid, 13, 3).substr($uuid, 8, 4).'00000000';
17 daniel-mar 182
                                        $ts = gmp_init($timestamp, 16);
183
                                        $ts = gmp_sub($ts, gmp_init("122192928000000000"));
193 daniel-mar 184
                                        $ms = gmp_mod($ts, gmp_init("10000000"));
17 daniel-mar 185
                                        $ts = gmp_div($ts, gmp_init("10000000"));
186
                                        $ts = gmp_strval($ts);
187
                                        $ms = gmp_strval($ms);
193 daniel-mar 188
                                        $ts_min = gmdate('Y-m-d H:i:s', $ts)."'".str_pad($ms, 7, '0', STR_PAD_LEFT).' GMT';
17 daniel-mar 189
 
193 daniel-mar 190
                                        $timestamp = substr($uuid, 13, 3).substr($uuid, 8, 4).'FFFFFFFF';
191
                                        $ts = gmp_init($timestamp, 16);
192
                                        $ts = gmp_sub($ts, gmp_init("122192928000000000"));
193
                                        $ms = gmp_mod($ts, gmp_init("10000000"));
194
                                        $ts = gmp_div($ts, gmp_init("10000000"));
195
                                        $ts = gmp_strval($ts);
196
                                        $ms = gmp_strval($ms);
197
                                        $ts_max = gmdate('Y-m-d H:i:s', $ts)."'".str_pad($ms, 7, '0', STR_PAD_LEFT).' GMT';
17 daniel-mar 198
 
193 daniel-mar 199
                                        $timestamp = substr($uuid, 13, 3).substr($uuid, 8, 4).'xxxxxxxx';
200
                                        echo sprintf("%-24s %s\n", "Timestamp:", "[0x$timestamp] $ts_min - $ts_max");
201
 
202
                                        $x = hexdec(substr($uuid, 16, 2).'00');
203
                                        $dec_min = $x & 0x3FFF; // The highest 2 bits are used by "variant" (10x)
204
                                        $x = hexdec(substr($uuid, 16, 2).'FF');
205
                                        $dec_max = $x & 0x3FFF; // The highest 2 bits are used by "variant" (10x)
206
                                        $hex = substr($uuid, 16, 2).'xx';
207
                                        echo sprintf("%-24s %s\n", "Clock ID:", "[0x$hex] $dec_min - $dec_max");
208
 
17 daniel-mar 209
                                        $x = substr($uuid, 20, 12);
210
                                        $nodeid = '';
211
                                        for ($i=0; $i<6; $i++) {
212
                                                $nodeid .= substr($x, $i*2, 2);
213
                                                if ($i != 5) $nodeid .= ':';
214
                                        }
215
                                        echo sprintf("%-24s %s\n", "Node ID:", "$nodeid");
216
 
217
                                        if (function_exists('decode_mac')) {
218
                                                echo "\nIn case that this Node ID is a MAC address, here is the interpretation of that MAC address:\n";
219
                                                echo decode_mac($nodeid);
220
                                        }
221
 
222
                                        break;
223
                                case 3:
224
                                        echo sprintf("%-24s %s\n", "Version:", "[3] Name-based (MD5 hash)");
225
 
193 daniel-mar 226
                                        $hash = str_replace('-', '', strtolower($uuid));
227
                                        $hash[12] = '?'; // was overwritten by version
228
                                        $hash[16] = '?'; // was partially overwritten by variant
17 daniel-mar 229
 
193 daniel-mar 230
                                        echo sprintf("%-24s %s\n", "MD5(Namespace+Subject):", "$hash");
231
 
17 daniel-mar 232
                                        break;
233
                                case 4:
234
                                        echo sprintf("%-24s %s\n", "Version:", "[4] Random");
235
 
236
                                        $rand = '';
237
                                        for ($i=0; $i<16; $i++) {
238
                                                $bin = base_convert(substr($uuid, $i*2, 2), 16, 2);
239
                                                $bin = str_pad($bin, 8, "0", STR_PAD_LEFT);
240
 
241
                                                if ($i == 6) {
242
                                                        $bin[0] = 'x';
243
                                                        $bin[1] = 'x';
244
                                                } else if ($i == 8) {
245
                                                        $bin[0] = 'x';
246
                                                        $bin[1] = 'x';
247
                                                        $bin[2] = 'x';
248
                                                        $bin[3] = 'x';
249
                                                }
250
 
251
                                                $rand .= "$bin ";
252
                                        }
253
 
254
                                        echo sprintf("%-24s %s\n", "Random bits:", trim($rand));
255
 
256
                                        break;
257
                                case 5:
258
                                        echo sprintf("%-24s %s\n", "Version:", "[5] Name-based (SHA-1 hash)");
259
 
193 daniel-mar 260
                                        $hash = str_replace('-', '', strtolower($uuid));
261
                                        $hash[12] = '?'; // was overwritten by version
262
                                        $hash[16] = '?'; // was partially overwritten by variant
263
                                        $hash .= '????????'; // was cut off
17 daniel-mar 264
 
193 daniel-mar 265
                                        echo sprintf("%-24s %s\n", "SHA1(Namespace+Subject):", "$hash");
266
 
267
 
17 daniel-mar 268
                                        break;
269
                                default:
270
                                        echo sprintf("%-24s %s\n", "Version:", "[$version] Unknown");
271
                                        break;
272
                        }
273
 
274
                        break;
275
                case 2:
276
                        echo sprintf("%-24s %s\n", "Variant:", "[110] Reserved for Microsoft Corporation");
277
                        break;
278
                case 3:
279
                        echo sprintf("%-24s %s\n", "Variant:", "[111] Reserved for future use");
280
                        break;
281
        }
282
}
283
 
284
function uuid_canonize($uuid) {
285
        if (!uuid_valid($uuid)) return false;
286
        return oid_to_uuid(uuid_to_oid($uuid));
287
}
288
 
289
function oid_to_uuid($oid) {
290
        if (!is_uuid_oid($oid)) return false;
291
 
292
        if ($oid[0] == '.') {
293
                $oid = substr($oid, 1);
294
        }
295
        $ary = explode('.', $oid);
296
        $val = $ary[2];
297
 
298
        $x = gmp_init($val, 10);
299
        $y = gmp_strval($x, 16);
300
        $y = str_pad($y, 32, "0", STR_PAD_LEFT);
301
        return substr($y,  0, 8).'-'.
302
               substr($y,  8, 4).'-'.
303
               substr($y, 12, 4).'-'.
304
               substr($y, 16, 4).'-'.
305
               substr($y, 20, 12);
306
}
307
 
308
function is_uuid_oid($oid, $only_allow_root=false) {
194 daniel-mar 309
        if ($oid[0] == '.') $oid = substr($oid, 1); // remove leading dot
17 daniel-mar 310
 
311
        $ary = explode('.', $oid);
312
 
313
        if ($only_allow_root) {
314
                if (count($ary) != 3) return false;
315
        }
316
 
194 daniel-mar 317
        if ($ary[0] != '2') return false;
318
        if ($ary[1] != '25') return false;
17 daniel-mar 319
        for ($i=2; $i<count($ary); $i++) {
320
                $v = $ary[$i];
321
                if (!is_numeric($v)) return false;
194 daniel-mar 322
                if ($i == 2) {
323
                        // Must be in the range of 128 bit UUID
324
                        $test = gmp_init($v, 10);
325
                        if (strlen(gmp_strval($test, 16)) > 32) return false;
326
                }
17 daniel-mar 327
                if ($v < 0) return false;
328
        }
329
 
330
        return true;
331
}
332
 
333
function uuid_to_oid($uuid) {
334
        if (!uuid_valid($uuid)) return false;
335
 
336
        $uuid = str_replace(array('-', '{', '}'), '', $uuid);
337
        $x = gmp_init($uuid, 16);
191 daniel-mar 338
        return '2.25.'.gmp_strval($x, 10); # TODO: parameter with or without leading dot
17 daniel-mar 339
}
340
 
193 daniel-mar 341
function gen_uuid($prefer_timebased = true) {
342
        if ($prefer_timebased) $uuid = gen_uuid_timebased();
343
        if ($uuid === false) $uuid = gen_uuid_random();
344
        return $uuid;
17 daniel-mar 345
}
346
 
193 daniel-mar 347
// Version 1 (Time based) UUID
348
function gen_uuid_timebased() {
17 daniel-mar 349
        # On Debian: aptitude install php-uuid
350
        # extension_loaded('uuid')
351
        if (function_exists('uuid_create')) {
352
                # OSSP uuid extension like seen in php5-uuid at Debian 8
353
                /*
354
                $x = uuid_create($context);
193 daniel-mar 355
                uuid_make($context, UUID_MAKE_V1);
17 daniel-mar 356
                uuid_export($context, UUID_FMT_STR, $uuid);
357
                return trim($uuid);
358
                */
359
 
360
                # PECL uuid extension like seen in php-uuid at Debian 9
193 daniel-mar 361
                return trim(uuid_create(UUID_TYPE_TIME));
17 daniel-mar 362
        }
363
 
364
        # On Debian: aptitude install uuid-runtime
193 daniel-mar 365
        $out = array();
366
        exec('uuidgen -t', $out, $ec);
17 daniel-mar 367
        if ($ec == 0) return $out[0];
368
 
193 daniel-mar 369
        # TODO: Implement the time based generation routine ourselves!
370
        # At the moment we cannot determine the time based UUID
371
        return false;
372
}
373
 
374
// Version 2 (DCE Security) UUID
375
function gen_uuid_dce($domain, $id) {
376
        # Start with a version 1 UUID
377
        $uuid = gen_uuid_timebased();
378
 
379
        # Add ID
380
        $uuid = str_pad(dechex($id), 8, '0', STR_PAD_LEFT) . substr($uuid, 8);
381
 
382
        # Add domain
383
        $uuid = substr($uuid,0,21) . str_pad(dechex($domain), 2, '0', STR_PAD_LEFT) . substr($uuid, 23);
384
 
385
        # Change version to 2
386
        $uuid[14] = '2';
387
 
388
        return $uuid;
389
}
390
 
391
// Version 3 (MD5 name based) UUID
392
function gen_uuid_md5_namebased($namespace_uuid, $name) {
393
        if (!uuid_valid($namespace_uuid)) return false;
394
        $namespace_uuid = uuid_canonize($namespace_uuid);
395
        $namespace_uuid = str_replace('-', '', $namespace_uuid);
396
        $namespace_uuid = hex2bin($namespace_uuid);
397
 
398
        $hash = md5($namespace_uuid.$name);
399
        $hash[12] = '3'; // Set version: 3 = MD5
400
        $hash[16] = dechex(hexdec($hash[16]) & 0x3 | 0x8); // Set variant to "10xx" (RFC4122)
401
 
402
        return substr($hash,  0, 8).'-'.
403
               substr($hash,  8, 4).'-'.
404
               substr($hash, 12, 4).'-'.
405
               substr($hash, 16, 4).'-'.
406
               substr($hash, 20, 12);
407
}
408
 
409
// Version 4 (Random) UUID
410
function gen_uuid_random() {
411
        # On Debian: aptitude install php-uuid
412
        # extension_loaded('uuid')
413
        if (function_exists('uuid_create')) {
414
                # OSSP uuid extension like seen in php5-uuid at Debian 8
415
                /*
416
                $x = uuid_create($context);
417
                uuid_make($context, UUID_MAKE_V4);
418
                uuid_export($context, UUID_FMT_STR, $uuid);
419
                return trim($uuid);
420
                */
421
 
422
                # PECL uuid extension like seen in php-uuid at Debian 9
423
                return trim(uuid_create(UUID_TYPE_RANDOM));
17 daniel-mar 424
        }
425
 
193 daniel-mar 426
        # On Debian: aptitude install uuid-runtime
427
        $out = array();
428
        exec('uuidgen -r', $out, $ec);
429
        if ($ec == 0) return $out[0];
17 daniel-mar 430
 
193 daniel-mar 431
        # On Debian Jessie: UUID V4 (Random)
17 daniel-mar 432
        if (file_exists('/proc/sys/kernel/random/uuid')) {
433
                return file_get_contents('/proc/sys/kernel/random/uuid');
434
        }
435
 
193 daniel-mar 436
        # Make the UUID by ourselves
437
        # Source: http://rogerstringer.com/2013/11/15/generate-uuids-php
438
        return sprintf( '%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
439
                mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ),
440
                mt_rand( 0, 0xffff ),
441
                mt_rand( 0, 0x0fff ) | 0x4000,
442
                mt_rand( 0, 0x3fff ) | 0x8000,
443
                mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff )
444
        );
17 daniel-mar 445
}
446
 
193 daniel-mar 447
// Version 5 (SHA1 name based) UUID
448
function gen_uuid_sha1_namebased($namespace_uuid, $name) {
449
        $namespace_uuid = str_replace('-', '', $namespace_uuid);
450
        $namespace_uuid = hex2bin($namespace_uuid);
451
 
452
        $hash = sha1($namespace_uuid.$name);
453
        $hash[12] = '5'; // Set version: 5 = SHA1
454
        $hash[16] = dechex(hexdec($hash[16]) & 0x3 | 0x8); // Set variant to "10xx" (RFC4122)
455
 
456
        return substr($hash,  0, 8).'-'.
457
               substr($hash,  8, 4).'-'.
458
               substr($hash, 12, 4).'-'.
459
               substr($hash, 16, 4).'-'.
460
               substr($hash, 20, 12);
461
}
462
 
17 daniel-mar 463
function uuid_numeric_value($uuid) {
464
        $oid = uuid_to_oid($uuid);
465
        if (!$oid) return false;
466
        return substr($oid, strlen('2.25.'));
467
}
468
 
469
function uuid_c_syntax($uuid) {
470
        $uuid = str_replace('{', '', $uuid);
471
        return '{ 0x' . substr($uuid, 0, 8) .
472
                ', 0x' . substr($uuid, 9, 4) .
473
                ', 0x' . substr($uuid, 14, 4) .
474
                ', { 0x' . substr($uuid, 19, 2).
475
                ', 0x' . substr($uuid, 21, 2) .
476
                ', 0x' . substr($uuid, 24, 2) .
477
                ', 0x' . substr($uuid, 26, 2) .
478
                ', 0x' . substr($uuid, 28, 2) .
479
                ', 0x' . substr($uuid, 30, 2) .
480
                ', 0x' . substr($uuid, 32, 2) .
481
                ', 0x' . substr($uuid, 34, 2) . ' } }';
482
}
483
 
484
# ---
485
 
486
// http://php.net/manual/de/function.hex2bin.php#113057
487
if ( !function_exists( 'hex2bin' ) ) {
488
    function hex2bin( $str ) {
489
        $sbin = "";
490
        $len = strlen( $str );
491
        for ( $i = 0; $i < $len; $i += 2 ) {
492
            $sbin .= pack( "H*", substr( $str, $i, 2 ) );
493
        }
494
 
495
        return $sbin;
496
    }
497
}