Subversion Repositories uuid_mac_utils

Rev

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

Rev Author Line No. Line
31 daniel-mar 1
<?php
2 daniel-mar 2
 
31 daniel-mar 3
/*
4
* UUID & MAC Utils
5
* Copyright 2017 - 2023 Daniel Marschall, ViaThinkSoft
69 daniel-mar 6
* Version 2023-09-23
31 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
*/
20
 
21
include_once __DIR__.'/includes/uuid_utils.inc.php';
22
 
72 daniel-mar 23
const AUTO_NEW_UUIDS = 15;
31 daniel-mar 24
 
25
?><!DOCTYPE html>
26
<html lang="en">
27
 
2 daniel-mar 28
<head>
29
        <meta charset="iso-8859-1">
30
        <link rel="stylesheet" type="text/css" href="style.css">
31
        <title>UUID &amp; MAC Utils by Daniel Marschall</title>
35 daniel-mar 32
        <meta name=viewport content="width=device-width, initial-scale=1">
2 daniel-mar 33
</head>
34
 
35
<body>
36
 
25 daniel-mar 37
<h1>UUID &amp; MAC Utils by Daniel Marschall</h1>
2 daniel-mar 38
 
12 daniel-mar 39
<p><a href="https://github.com/danielmarschall/uuid_mac_utils/">View the source code</a></p>
2 daniel-mar 40
 
31 daniel-mar 41
<h2>Overview</h2>
2 daniel-mar 42
 
31 daniel-mar 43
<ul>
44
    <li><a href="#gen_uuid">Generate random and/or time-based UUIDs</a><ul>
45
            <li><a href="#gen_uuidv7"><font color="green">New:</font> Generate Unix Epoch Time (version 7) UUID</a></li>
46
            <li><a href="#gen_uuidv6"><font color="green">New:</font> Generate reordered time-based (version 6) UUID</a></li>
47
            <li><a href="#gen_uuidv4">Generate random (version 4) UUID</a></li>
48
            <li><a href="#gen_uuidv1">Generate time-based (version 1) UUID</a></li>
49
        </ul></li>
50
    <li><a href="#gen_other_uuid">Generate other UUID types</a><ul>
53 daniel-mar 51
            <li><a href="#gen_uuid_ncs">NCS (variant 0) UUID</a></li>
31 daniel-mar 52
            <li><a href="#gen_uuidv2">Generate DCE Security (version 2) UUID</a></li>
61 daniel-mar 53
            <li><a href="#gen_uuidv35">Generate name-based (version 3 / 5 / <font color="green">New: 8</font>) UUID</a></li>
54
            <li><a href="#gen_uuidv8"><font color="green">New:</font> Generate Custom (version 8) UUID</a></li>
31 daniel-mar 55
        </ul></li>
56
    <li><a href="#interpret_uuid">Interpret a UUID</a></li>
41 daniel-mar 57
    <li><a href="#interpret_mac">Interpret a MAC address (MAC / EUI / ELI / SAI / AAI)</a><ul>
58
        <li><a href="#gen_aai">Generate an AAI</a></li>
59
    </ul></li>
31 daniel-mar 60
</ul>
2 daniel-mar 61
 
31 daniel-mar 62
<h2 id="gen_uuid">Generate random and/or time-based UUIDs</h2>
30 daniel-mar 63
 
62 daniel-mar 64
<h3 id="gen_uuidv7"><font color="green">New:</font> Generate Unix Epoch Time (version 7) UUID &#11088;</h3>
31 daniel-mar 65
 
72 daniel-mar 66
<p><i>A UUIDv7 measures time in the Unix Epoch with an accuracy
67
between 1ms and 245ns, depending on how many bits are spent for the timestamp (48-60 bits).
68
The rest of the UUID (62-74 bits) is filled with random data.
69
The timestamp is at the front of the UUID, therefore the UUIDs are monotonically increasing,
70
which is good for ordering them and using them for database indexes.
71
Since this UUID version does not contain a MAC address, it is
72
recommended due to the improved privacy.</i></p>
31 daniel-mar 73
 
35 daniel-mar 74
<script>
75
function show_uuidv7_info() {
76
        document.getElementById("uuidv7_info_button").style.display = "none";
77
        document.getElementById("uuidv7_info").style.display = "block";
78
}
79
</script>
62 daniel-mar 80
<p><a id="uuidv7_info_button" href="javascript:show_uuidv7_info()">Show format</a>
35 daniel-mar 81
<pre id="uuidv7_info" style="display:none">Variant 1, Version 7 UUID:
37 daniel-mar 82
- 48 bit <abbr title="Count of 1ms intervals passed since 1 Jan 1970 00:00:00 GMT">Unix Time in milliseconds</abbr>
35 daniel-mar 83
-  4 bit Version (fix 0x7)
70 daniel-mar 84
- 12 bit Data
35 daniel-mar 85
-  2 bit Variant (fix 0b10)
70 daniel-mar 86
- 62 bit Data
35 daniel-mar 87
 
70 daniel-mar 88
Structure of data (74 bits):
89
- OPTIONAL : Sub-millisecond timestamp fraction (0-12 bits)
90
- OPTIONAL : Carefully seeded counter
91
- Random generated bits for any remaining space
92
 
93
Time resolution for various sub-millisecond bits:
31 daniel-mar 94
<?php
70 daniel-mar 95
for ($num_ms_frac_bits=0; $num_ms_frac_bits<=12; $num_ms_frac_bits++) {
96
        $resolution_ns = 1000000 / pow(2,$num_ms_frac_bits);
97
        if ($resolution_ns >= 1000000) $resolution_ns_hf = ($resolution_ns/1000000)." ms";
98
        else if ($resolution_ns >= 1000) $resolution_ns_hf = ($resolution_ns/1000)." &micro;s";
99
        else $resolution_ns_hf = "$resolution_ns ns";
100
        echo "$num_ms_frac_bits bits fraction = $resolution_ns_hf\n";
101
}
102
?>
72 daniel-mar 103
 
104
This implementation outputs:
105
- 12 bits sub-millisecond timestamp (~245ns resolution)
106
- no counter
107
- 62 bits random data
70 daniel-mar 108
</pre></p>
109
 
110
<?php
31 daniel-mar 111
if (AUTO_NEW_UUIDS > 0) { /** @phpstan-ignore-line */
35 daniel-mar 112
        echo '<p>Here are '.AUTO_NEW_UUIDS.' UUIDs that were created just for you! (Reload the page to get more)</p>';
31 daniel-mar 113
 
114
        echo '<pre>';
70 daniel-mar 115
        for ($i=0; $i<AUTO_NEW_UUIDS; $i++) {
31 daniel-mar 116
                $uuid = gen_uuid_v7();
117
                echo '<a href="interprete_uuid.php?uuid='.$uuid.'">'.$uuid.'</a><br>';
118
        }
119
        echo '</pre>';
120
}
121
?>
122
 
2 daniel-mar 123
<form method="GET" action="interprete_uuid.php">
31 daniel-mar 124
    <input type="hidden" name="version" value="7">
125
    <input type="hidden" name="uuid" value="CREATE"> <input type="submit" value="Create and display another UUID">
2 daniel-mar 126
</form>
127
 
32 daniel-mar 128
<h3 id="gen_uuidv6"><font color="green">New:</font> Generate reordered time-based (version 6) UUID &#9200;</h3>
2 daniel-mar 129
 
31 daniel-mar 130
<p><i>Like UUIDv1, this kind of UUID is made of the MAC address of the generating computer,
131
        the time, and a clock sequence. However, the components in UUIDv6 are reordered (time is at the beginning),
72 daniel-mar 132
        so that UUIDs are monotonically increasing,
133
        which is good for ordering them and using them for database indexes..</i></p>
2 daniel-mar 134
 
35 daniel-mar 135
<script>
136
function show_uuidv6_info() {
137
        document.getElementById("uuidv6_info_button").style.display = "none";
138
        document.getElementById("uuidv6_info").style.display = "block";
139
}
140
</script>
62 daniel-mar 141
<p><a id="uuidv6_info_button" href="javascript:show_uuidv6_info()">Show format</a>
35 daniel-mar 142
<pre id="uuidv6_info" style="display:none">Variant 1, Version 6 UUID:
37 daniel-mar 143
- 48 bit High <abbr title="Count of 100ns intervals passed since 15 Oct 1582 00:00:00 GMT">Time</abbr>
35 daniel-mar 144
-  4 bit Version (fix 0x6)
37 daniel-mar 145
- 12 bit Low <abbr title="Count of 100ns intervals passed since 15 Oct 1582 00:00:00 GMT">Time</abbr>
35 daniel-mar 146
-  2 bit Variant (fix 0b10)
147
-  6 bit Clock Sequence High
148
-  8 bit Clock Sequence Low
149
- 48 bit MAC Address</pre></p>
150
 
31 daniel-mar 151
<?php
152
if (AUTO_NEW_UUIDS > 0) { /** @phpstan-ignore-line */
35 daniel-mar 153
        echo '<p>Here are '.AUTO_NEW_UUIDS.' UUIDs that were created just for you! (Reload the page to get more)</p>';
31 daniel-mar 154
 
155
        echo '<pre>';
70 daniel-mar 156
        for ($i=0; $i<AUTO_NEW_UUIDS; $i++) {
31 daniel-mar 157
                $uuid = gen_uuid_v6();
158
                echo '<a href="interprete_uuid.php?uuid='.$uuid.'">'.$uuid.'</a><br>';
159
        }
160
        echo '</pre>';
161
}
162
?>
163
 
2 daniel-mar 164
<form method="GET" action="interprete_uuid.php">
31 daniel-mar 165
    <input type="hidden" name="version" value="6">
166
    <input type="hidden" name="uuid" value="CREATE"> <input type="submit" value="Create and display another UUID">
30 daniel-mar 167
</form>
168
 
31 daniel-mar 169
<h3 id="gen_uuidv4">Generate random (version 4) UUID &#x1F3B2;</h3>
30 daniel-mar 170
 
35 daniel-mar 171
<p><i>A UUIDv4 is made of 122 random&nbsp;bits. No other information is encoded in this kind of UUID.</i></p>
30 daniel-mar 172
 
35 daniel-mar 173
<script>
174
function show_uuidv4_info() {
175
        document.getElementById("uuidv4_info_button").style.display = "none";
176
        document.getElementById("uuidv4_info").style.display = "block";
177
}
178
</script>
62 daniel-mar 179
<p><a id="uuidv4_info_button" href="javascript:show_uuidv4_info()">Show format</a>
35 daniel-mar 180
<pre id="uuidv4_info" style="display:none">Variant 1, Version 4 UUID:
181
- 48 bit Random High
182
-  4 bit Version (fix 0x4)
183
- 12 bit Random Mid
184
-  2 bit Variant (fix 0b10)
185
- 62 bit Random Low</pre></p>
186
 
31 daniel-mar 187
<?php
188
if (AUTO_NEW_UUIDS > 0) { /** @phpstan-ignore-line */
35 daniel-mar 189
        echo '<p>Here are '.AUTO_NEW_UUIDS.' UUIDs that were created just for you! (Reload the page to get more)</p>';
31 daniel-mar 190
 
191
        echo '<pre>';
70 daniel-mar 192
        for ($i=0; $i<AUTO_NEW_UUIDS; $i++) {
31 daniel-mar 193
                $uuid = gen_uuid_v4();
194
                echo '<a href="interprete_uuid.php?uuid='.$uuid.'">'.$uuid.'</a><br>';
195
        }
196
        echo '</pre>';
197
}
198
?>
199
 
30 daniel-mar 200
<form method="GET" action="interprete_uuid.php">
31 daniel-mar 201
    <input type="hidden" name="version" value="4">
202
    <input type="hidden" name="uuid" value="CREATE"> <input type="submit" value="Create and display another UUID">
30 daniel-mar 203
</form>
204
 
32 daniel-mar 205
<h3 id="gen_uuidv1">Generate time-based (version 1) UUID &#9200;</h3>
30 daniel-mar 206
 
31 daniel-mar 207
<p><i>A UUIDv1 is made of the MAC address of the generating computer,
208
the time, and a clock sequence.</i></p>
30 daniel-mar 209
 
35 daniel-mar 210
<script>
211
function show_uuidv1_info() {
212
        document.getElementById("uuidv1_info_button").style.display = "none";
213
        document.getElementById("uuidv1_info").style.display = "block";
214
}
215
</script>
62 daniel-mar 216
<p><a id="uuidv1_info_button" href="javascript:show_uuidv1_info()">Show format</a>
35 daniel-mar 217
<pre id="uuidv1_info" style="display:none">Variant 1, Version 1 UUID:
37 daniel-mar 218
- 32 bit Low <abbr title="Count of 100ns intervals passed since 15 Oct 1582 00:00:00 GMT">Time</abbr>
219
- 16 bit Mid <abbr title="Count of 100ns intervals passed since 15 Oct 1582 00:00:00 GMT">Time</abbr>
35 daniel-mar 220
-  4 bit Version (fix 0x1)
37 daniel-mar 221
- 12 bit High <abbr title="Count of 100ns intervals passed since 15 Oct 1582 00:00:00 GMT">Time</abbr>
35 daniel-mar 222
-  2 bit Variant (fix 0b10)
223
-  6 bit Clock Sequence High
224
-  8 bit Clock Sequence Low
225
- 48 bit MAC Address</pre></p>
226
 
31 daniel-mar 227
<?php
228
if (AUTO_NEW_UUIDS > 0) { /** @phpstan-ignore-line */
35 daniel-mar 229
    echo '<p>Here are '.AUTO_NEW_UUIDS.' UUIDs that were created just for you! (Reload the page to get more)</p>';
31 daniel-mar 230
 
231
    echo '<pre>';
70 daniel-mar 232
    for ($i=0; $i<AUTO_NEW_UUIDS; $i++) {
31 daniel-mar 233
        $uuid = gen_uuid_v1();
234
        echo '<a href="interprete_uuid.php?uuid='.$uuid.'">'.$uuid.'</a><br>';
235
    }
236
    echo '</pre>';
237
}
238
?>
239
 
30 daniel-mar 240
<form method="GET" action="interprete_uuid.php">
31 daniel-mar 241
    <input type="hidden" name="version" value="1">
242
    <input type="hidden" name="uuid" value="CREATE"> <input type="submit" value="Create and display another UUID">
30 daniel-mar 243
</form>
244
 
31 daniel-mar 245
<h2 id="gen_other_uuid">Generate other UUID types</h2>
30 daniel-mar 246
 
47 daniel-mar 247
<p><i>The following types of UUIDs are less common and/or require special knowledge. Please only use the following
30 daniel-mar 248
generators if you know what you are doing.</i></p>
249
 
53 daniel-mar 250
<h3 id="gen_uuid_ncs">NCS (variant 0) UUID</h3>
30 daniel-mar 251
 
53 daniel-mar 252
<p>The <abbr title="Network Computing System">NCS</abbr> UUIDs are a legacy format
253
initially designed by Apollo Computer that cannot be generated anymore, because the
30 daniel-mar 254
amount of available timestamp bits was exhausted on <strong>5 September 2015</strong>.
53 daniel-mar 255
As an example, here is the last possible NCS UUID (all bits of the timestamp are set to 1) for IP address 127.0.0.1:
34 daniel-mar 256
<a href="interprete_uuid.php?uuid=ffffffff-ffff-0000-027f-000001000000"><code>ffffffff-ffff-0000-027f-000001000000</code></a>.</p>
30 daniel-mar 257
 
35 daniel-mar 258
<script>
259
function show_uuidnce_info() {
260
        document.getElementById("uuidnce_info_button").style.display = "none";
261
        document.getElementById("uuidnce_info").style.display = "block";
262
}
263
</script>
62 daniel-mar 264
<p><a id="uuidnce_info_button" href="javascript:show_uuidnce_info()">Show format</a>
35 daniel-mar 265
<pre id="uuidnce_info" style="display:none">Variant 0 UUID:
37 daniel-mar 266
- 32 bit High <abbr title="Count of 4&#xB5;s intervals passed since 1 Jan 1980 00:00:00 GMT">Time</abbr>
267
- 16 bit Low <abbr title="Count of 4&#xB5;s intervals passed since 1 Jan 1980 00:00:00 GMT">Time</abbr>
35 daniel-mar 268
- 16 bit Reserved
269
-  1 bit Variant (fix 0b0)
37 daniel-mar 270
-  7 bit <abbr title="socket_$unspec (0x0)
271
socket_$unix (0x1)
272
socket_$internet (0x2)
273
socket_$implink (0x3)
274
socket_$pup (0x4)
275
socket_$chaos (0x5)
276
socket_$ns (0x6)
277
socket_$nbs (0x7)
278
socket_$ecma (0x8)
279
socket_$datakit (0x9)
280
socket_$ccitt (0xA)
281
socket_$sna (0xB)
282
socket_$unspec2 (0xC)
283
socket_$dds (0xD)">Family</abbr>
35 daniel-mar 284
- 56 bit Node</pre></p>
285
 
31 daniel-mar 286
<h3 id="gen_uuidv2">Generate DCE Security (version 2) UUID</h3>
30 daniel-mar 287
 
37 daniel-mar 288
<p><i>An UUIDv2 contains information about the creator (person, group, or organization), the generating system (MAC address), and time.
35 daniel-mar 289
The creator information replaced parts of the time bits, therefore the time resolution is very low.</i></p>
290
 
291
<script>
292
function show_uuidv2_info() {
293
        document.getElementById("uuidv2_info_button").style.display = "none";
294
        document.getElementById("uuidv2_info").style.display = "block";
295
}
296
</script>
62 daniel-mar 297
<p><a id="uuidv2_info_button" href="javascript:show_uuidv2_info()">Show format</a>
35 daniel-mar 298
<pre id="uuidv2_info" style="display:none">Variant 1, Version 2 UUID:
299
- 32 bit Local Domain Number
37 daniel-mar 300
- 16 bit Mid <abbr title="Count of 429.4967296s intervals passed since 15 Oct 1582 00:00:00 GMT">Time</abbr>
35 daniel-mar 301
-  4 bit Version (fix 0x2)
37 daniel-mar 302
- 12 bit High <abbr title="Count of 429.4967296s intervals passed since 15 Oct 1582 00:00:00 GMT">Time</abbr>
35 daniel-mar 303
-  2 bit Variant (fix 0b10)
304
-  6 bit Clock Sequence
37 daniel-mar 305
-  8 bit <abbr title="0 = person
306
1 = group
307
2 = org
308
3-255 = site-defined">Local Domain</abbr>
35 daniel-mar 309
- 48 bit MAC Address</pre></p>
310
 
30 daniel-mar 311
<form method="GET" action="interprete_uuid.php">
2 daniel-mar 312
        <input type="hidden" name="version" value="2">
35 daniel-mar 313
        <label>Domain (8&nbsp;bits):</label><select name="domain_choose" id="dce_domain_choice" onchange="javascript:dce_domain_choose();">
34 daniel-mar 314
                <option value="uid">Person (e.g. POSIX UID)</option>
315
                <option value="gid">Group (e.g. POSIX GID)</option>
316
                <option value="org">Organization</option>
2 daniel-mar 317
                <option value="site">Site-defined</option>
62 daniel-mar 318
        </select> = Address Family ID: <input type="number" min="0" max="255" name="dce_domain" value="" id="dce_domain" style="width:50px" pattern="[0-9]+"> (decimal notation)<br>
35 daniel-mar 319
        <label>Value (32&nbsp;bits):</label><input type="number" min="0" max="4294967295" name="dce_id" value="0" id="dce_id" style="width:200px" pattern="[0-9]+"> (decimal notation)<br>
37 daniel-mar 320
        <font color="red">Warning</font>: The timestamp has an accuracy of 7:10 minutes,
30 daniel-mar 321
        therefore the uniqueness of these UUIDs is not guaranteed!<br><br>
59 daniel-mar 322
        <input type="hidden" name="uuid" value="CREATE"> <input type="submit" value="Create UUIDv2">
2 daniel-mar 323
</form>
324
<script>
325
function dce_domain_choose() {
326
        var ns = document.getElementById('dce_domain_choice').value;
327
        if (ns == "uid") {
328
                document.getElementById('dce_domain').value = "0";
329
        }
330
        if (ns == "gid") {
331
                document.getElementById('dce_domain').value = "1";
332
        }
333
        if (ns == "org") {
334
                document.getElementById('dce_domain').value = "2";
335
        }
336
        if (ns == "site") {
337
                document.getElementById('dce_domain').value = "";
338
        }
339
}
340
dce_domain_choose();
341
</script>
342
 
61 daniel-mar 343
<h3 id="gen_uuidv35">Generate name-based (version 3 / 5 / <font color="green">New: 8</font>) UUID</h3>
2 daniel-mar 344
 
57 daniel-mar 345
<p><i>An UUIDv3 is made out of a MD5 hash and an UUIDv5 is made out of a SHA1 hash.
346
The revision of RFC4122 also contains an example for a custom UUIDv8 that
72 daniel-mar 347
uses modern hash algorithms.</i></p>
35 daniel-mar 348
 
349
<script>
350
function show_uuidv35_info() {
351
        document.getElementById("uuidv35_info_button").style.display = "none";
352
        document.getElementById("uuidv35_info").style.display = "block";
353
}
354
</script>
62 daniel-mar 355
<p><a id="uuidv35_info_button" href="javascript:show_uuidv35_info()">Show format</a>
58 daniel-mar 356
<pre id="uuidv35_info" style="display:none">Variant 1, Version 3/5/8 UUID:
35 daniel-mar 357
- 48 bit Hash High
58 daniel-mar 358
-  4 bit Version (fix 0x3, 0x5, or 0x8)
35 daniel-mar 359
- 12 bit Hash Mid
360
-  2 bit Variant (fix 0b10)
62 daniel-mar 361
- 62 bit Hash Low
35 daniel-mar 362
 
62 daniel-mar 363
 
69 daniel-mar 364
<u>As defined by <a href="https://datatracker.ietf.org/doc/rfc4122/">RFC4122</a>:</u>
365
UUIDv3(<i>NamespaceUuid</i>, <i>Data</i>) := <abbr title="Adds UUID variant 0b10 and version 3">ConvertRawBytesToUuid_v3</abbr>(MD5( Binary[<i>NameSpaceUuid</i>] || <i>Data</i> )).
366
UUIDv5(<i>NamespaceUuid</i>, <i>Data</i>) := <abbr title="Adds UUID variant 0b10 and version 5">ConvertRawBytesToUuid_v5</abbr>(SHA1( Binary[<i>NameSpaceUuid</i>] || <i>Data</i> )).
62 daniel-mar 367
NameSpaceUuid&lt;DNS&gt;          := "6ba7b810-9dad-11d1-80b4-00c04fd430c8".
368
NameSpaceUuid&lt;URL&gt;          := "6ba7b811-9dad-11d1-80b4-00c04fd430c8".
369
NameSpaceUuid&lt;OID&gt;          := "6ba7b812-9dad-11d1-80b4-00c04fd430c8".
370
NameSpaceUuid&lt;X500&gt;         := "6ba7b814-9dad-11d1-80b4-00c04fd430c8".
371
 
69 daniel-mar 372
<u>As defined by <a href="https://datatracker.ietf.org/doc/draft-ietf-uuidrev-rfc4122bis/">draft-ietf-uuidrev-rfc4122bis-11</a>:</u>
373
UUIDv8(<i>HashAlgo</i>, <i>NameSpaceUuid</i>, <i>Data</i>) := <abbr title="Adds UUID variant 0b10 and version 8">ConvertRawBytesToUuid_v8</abbr>(<i>HashAlgo</i>( Binary[HashSpaceUuid&lt;<i>HashAlgo</i>&gt;] || Binary[<i>NameSpaceUuid</i>] || <i>Data</i> )).
66 daniel-mar 374
<?php
62 daniel-mar 375
 
66 daniel-mar 376
$tmp = [];
69 daniel-mar 377
foreach (get_uuidv8_hash_space_ids() as list($algo,$space,$friendlyName,$author,$available)) {
378
        $line = str_pad('HashSpaceUuid&lt;'.htmlentities($friendlyName).'&gt;', 34, ' ', STR_PAD_RIGHT);
379
        $line .= ':= "'.$space.'".';
380
        if (!$available) $line .= " (Currently not available on this system)";
381
        $line .= "\n";
382
        $tmp[$friendlyName] = $line;
66 daniel-mar 383
}
384
ksort($tmp);
385
foreach ($tmp as $line) {
386
        echo $line;
387
}
388
 
389
?>
390
 
69 daniel-mar 391
<u>Custom implementation ("Raw Hash"):</u>
392
UUIDv8(<i>HashAlgo</i>, <i>NameSpaceUuid</i>, <i>Data</i>) := <abbr title="Adds UUID variant 0b10 and version 8">ConvertRawBytesToUuid_v8</abbr>(<i>HashAlgo</i>( Binary[<i>NameSpaceUuid</i>] || <i>Data</i> )).
67 daniel-mar 393
 
62 daniel-mar 394
</pre></p>
395
 
35 daniel-mar 396
<style>
397
label {
398
        width:120px;
399
        text-align:left;
400
        margin-right: 20px;
401
        display:inline-block;
402
}
403
</style>
404
 
2 daniel-mar 405
<form method="GET" action="interprete_uuid.php">
59 daniel-mar 406
        <label>Hash algorithm:</label><select name="version" id="nb_version" onchange="javascript:nb_version_choose();">
407
                <?php
67 daniel-mar 408
 
409
                echo "\t\t<option disabled>--- UUIDv3 (RFC 4122) ---</option>\n";
410
                echo "\t\t<option value=\"3\">MD5</option>\n";
411
                echo "\t\t<option disabled>--- UUIDv5 (RFC 4122) ---</option>\n";
412
                echo "\t\t<option value=\"5\" selected>SHA1</option>\n";
413
 
414
                $categories = [];
62 daniel-mar 415
                foreach (get_uuidv8_hash_space_ids() as list($algo,$space,$friendlyName,$author,$available)) {
67 daniel-mar 416
                        if (!in_array($author, $categories)) $categories[] = $author;
417
                }
418
                sort($categories);
419
 
420
                foreach ($categories as $category) {
421
                        echo "\t\t<option disabled>--- UUIDv8 (defined by ".htmlentities($category).") ---</option>\n";
422
                        $tmp = [];
423
                        foreach (get_uuidv8_hash_space_ids() as list($algo,$space,$friendlyName,$author,$available)) {
424
                                if ($author != $category) continue;
425
                                if ($available) {
426
                                        $tmp[$friendlyName] = '<option value="8_namebased_'.$space.'">'.htmlentities($friendlyName).'</option>';
427
                                }
62 daniel-mar 428
                        }
67 daniel-mar 429
                        ksort($tmp);
430
                        foreach ($tmp as $html) {
431
                                echo "\t\t$html\n";
432
                        }
59 daniel-mar 433
                }
69 daniel-mar 434
 
435
                echo "\t\t<option disabled>--- UUIDv8 (Raw Hash) ---</option>\n";
436
                $tmp = [];
437
                $algos = hash_algos();
438
                $algos[] = 'shake128';
439
                $algos[] = 'shake256';
440
                foreach ($algos as $algo) {
441
                        if ($algo == 'md5') continue; // use UUIDv3 instead
442
                        if ($algo == 'sha1') continue; // use UUIDv5 instead
443
                        $friendlyName = strtoupper($algo);
444
 
445
                        if ($algo == 'shake128') $bits = 999;
446
                        else if ($algo == 'shake256') $bits = 999;
447
                        else $bits = strlen(hash($algo, '', true)) * 8;
448
                        if ($bits < 128) $friendlyName .= " (Small hash size! $bits bits)";
449
 
450
                        $space = $algo;
451
                        $tmp[$friendlyName] = '<option value="8_namebased_'.$space.'">'.htmlentities($friendlyName).'</option>';
452
                }
453
                natsort($tmp);
454
                foreach ($tmp as $html) {
455
                        echo "\t\t$html\n";
456
                }
457
 
59 daniel-mar 458
                ?>
459
        </select><font size="-1"><span id="nb_hash_info"></span></font><br>
35 daniel-mar 460
        <label>Namespace:</label><select name="namespace_choose" id="nb_nsc" onchange="javascript:nb_ns_choose();">
2 daniel-mar 461
                <option value="dns">DNS</option>
462
                <option value="url">URL</option>
463
                <option value="oid">OID</option>
464
                <option value="x500">X.500 DN</option>
35 daniel-mar 465
                <!-- <option value="oidplus_ns">OIDplus ns only</option> -->
466
                <!-- <option value="oidplus_ns_val">OIDplus ns+val</option> -->
28 daniel-mar 467
                <!-- <option value="oidplus_pubkey">OIDplus pubkey</option> -->
2 daniel-mar 468
                <option value="other">Other</option>
59 daniel-mar 469
        </select> = Namespace UUID: <input type="text" name="nb_ns" value="" id="nb_ns" style="width:270px" onchange="javascript:nb_ns_textchange();" pattern="[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}"><br>
35 daniel-mar 470
        <label>Value:</label><input type="text" name="nb_val" value="" id="nb_val" style="width:300px"><br>
30 daniel-mar 471
        <font color="red">Warning</font>: These UUIDs do not contain a timestamp,
472
        therefore the uniqueness of these UUIDs is not guaranteed!<br><br>
59 daniel-mar 473
        <input type="hidden" name="uuid" value="CREATE"> <input type="submit" id="nb_create_btn" value="Create UUID">
2 daniel-mar 474
</form>
475
<script>
59 daniel-mar 476
function nb_version_choose() {
477
        var ver = document.getElementById('nb_version').value;
478
        document.getElementById('nb_create_btn').value = 'Create UUIDv' + ver.substr(0,1);
479
        var x = ver.split('_namebased_');
69 daniel-mar 480
        if ((x.length == 2) && (x[1].length == 36)) {
61 daniel-mar 481
                document.getElementById('nb_hash_info').innerHTML = ' (UUIDv8 Hash Space ID: ' + x[1] + ')';
59 daniel-mar 482
        } else {
483
                document.getElementById('nb_hash_info').innerHTML = '';
484
        }
485
 
486
}
35 daniel-mar 487
function nb_ns_textchange() {
488
        var ns = document.getElementById('nb_ns').value.toLowerCase();
489
        if (ns == "6ba7b810-9dad-11d1-80b4-00c04fd430c8") {
490
                if (document.getElementById('nb_nsc').value != "dns") {
491
                        document.getElementById('nb_nsc').value = "dns";
57 daniel-mar 492
                        document.getElementById('nb_val').value = "www.example.com";
35 daniel-mar 493
                }
494
        }
495
        else if (ns == "6ba7b811-9dad-11d1-80b4-00c04fd430c8") {
496
                if (document.getElementById('nb_nsc').value != "url") {
497
                        document.getElementById('nb_nsc').value = "url";
57 daniel-mar 498
                        document.getElementById('nb_val').value = "http://www.example.com/";
35 daniel-mar 499
                }
500
        }
501
        else if (ns == "6ba7b812-9dad-11d1-80b4-00c04fd430c8") {
502
                if (document.getElementById('nb_nsc').value != "oid") {
503
                        document.getElementById('nb_nsc').value = "oid";
504
                        document.getElementById('nb_val').value = "2.999";
505
                }
506
        }
507
        else if (ns == "6ba7b814-9dad-11d1-80b4-00c04fd430c8") {
508
                if (document.getElementById('nb_nsc').value != "x500") {
509
                        document.getElementById('nb_nsc').value = "x500";
510
                        document.getElementById('nb_val').value = "UID=jsmith,DC=example,DC=net";
511
                }
512
        }
513
        else {
514
                if (document.getElementById('nb_nsc').value != "other") {
515
                        document.getElementById('nb_nsc').value = "other";
516
                        document.getElementById('nb_val').value = "";
517
                }
518
        }
519
}
2 daniel-mar 520
function nb_ns_choose() {
521
        var ns = document.getElementById('nb_nsc').value;
522
        if (ns == "dns") {
523
                document.getElementById('nb_ns').value = "6ba7b810-9dad-11d1-80b4-00c04fd430c8";
57 daniel-mar 524
                document.getElementById('nb_val').value = "www.example.com";
2 daniel-mar 525
        }
35 daniel-mar 526
        else if (ns == "url") {
2 daniel-mar 527
                document.getElementById('nb_ns').value = "6ba7b811-9dad-11d1-80b4-00c04fd430c8";
57 daniel-mar 528
                document.getElementById('nb_val').value = "http://www.example.com/";
2 daniel-mar 529
        }
35 daniel-mar 530
        else if (ns == "oid") {
2 daniel-mar 531
                document.getElementById('nb_ns').value = "6ba7b812-9dad-11d1-80b4-00c04fd430c8";
532
                document.getElementById('nb_val').value = "2.999";
533
        }
35 daniel-mar 534
        else if (ns == "x500") {
2 daniel-mar 535
                document.getElementById('nb_ns').value = "6ba7b814-9dad-11d1-80b4-00c04fd430c8";
536
                document.getElementById('nb_val').value = "UID=jsmith,DC=example,DC=net";
537
        }
35 daniel-mar 538
        /*
539
        else if (ns == "oidplus_ns") {
2 daniel-mar 540
                document.getElementById('nb_ns').value = "0943e3ce-4b79-11e5-b742-78e3b5fc7f22";
541
                document.getElementById('nb_val').value = "ipv4";
542
        }
35 daniel-mar 543
        else if (ns == "oidplus_ns_val") {
2 daniel-mar 544
                document.getElementById('nb_ns').value = "ad1654e6-7e15-11e4-9ef6-78e3b5fc7f22";
545
                document.getElementById('nb_val').value = "ipv4:8.8.8.8";
546
        }
35 daniel-mar 547
        else if (ns == "oidplus_ns_pubkey") {
28 daniel-mar 548
                document.getElementById('nb_ns').value = "fd16965c-8bab-11ed-8744-3c4a92df8582";
31 daniel-mar 549
                document.getElementById('nb_val').value = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqg/PnsC1WX3C1/mUSLuk0DIaDHtEsxBnG0auYJRJ1hBtbUUvItbK0odlKrX2SFo1MJJpu/SSxTzAgqkKZsZe3cCFkgA1svfuH9i94oGLjJ4n0kRJEGlanCmGndJBfIqGDJaQE2BJ8tLxeBrpkd9l0KvJsjhRmqJAb9KYK3KYFsWvT+wyjD3UJ1eHcgLbF/Qb3cwMU/u7Fs7ZpsNMW4phDPlsYsk9XHFpJ1/UCj6G53mYRfOC/ouDdGShlbVLB15s0V95QpnU/7lL8mJ2lE+sTZekGNBA4XbJv2gs21cR4E8zc/z+NyZS7117DYZoJqrAN8sKz6xGoKgQF6wueCK5qQIDAQAB";
28 daniel-mar 550
        }
551
        */
35 daniel-mar 552
        else if (ns == "other") {
2 daniel-mar 553
                document.getElementById('nb_ns').value = "";
554
                document.getElementById('nb_val').value = "";
555
        }
556
}
59 daniel-mar 557
nb_version_choose();
2 daniel-mar 558
nb_ns_choose();
559
</script>
560
 
61 daniel-mar 561
<h3 id="gen_uuidv8"><font color="green">New:</font> Generate Custom (version 8) UUID</h3>
34 daniel-mar 562
 
37 daniel-mar 563
<p><i>UUIDv8 is made of 122 bits application-specific / custom data. The other 6 bits are used to specify the variant and version of the UUID, to make it RFC-compatible.</i></p>
35 daniel-mar 564
 
565
<script>
566
function show_uuidv8_info() {
567
        document.getElementById("uuidv8_info_button").style.display = "none";
568
        document.getElementById("uuidv8_info").style.display = "block";
569
}
65 daniel-mar 570
function uuidv8_changedec(block, len) {
571
        var x = document.getElementById("v8_block"+block+"_dec").value;
572
        if (x.trim() == "") x = 0;
573
        x = parseInt(x);
574
        if (isNaN(x)) {
575
                x = "???";
576
        } else {
577
                x = x.toString(16).padStart(len, '0');
578
                if ((len > 0) && (x.length > len)) x = "Overflow";
579
        }
580
        document.getElementById("v8_block"+block+"_hex").value = x;
581
}
582
function uuidv8_changehex(block, len) {
583
        var x = document.getElementById("v8_block"+block+"_hex").value;
584
        if (x.trim() == "") x = 0;
585
        x = parseInt(x, 16);
586
        if (isNaN(x)) {
587
                x = "???";
588
        } else {
589
                x = x.toString().padStart(len, '0');
590
                if ((len > 0) && (x.length > len)) x = "Overflow"; // Note: For block 3/4, the overflow actually happens at 12/14 bits, not at 4 nibbles (16 bits)
591
        }
592
        document.getElementById("v8_block"+block+"_dec").value = x;
593
}
35 daniel-mar 594
</script>
62 daniel-mar 595
<p><a id="uuidv8_info_button" href="javascript:show_uuidv8_info()">Show format</a>
35 daniel-mar 596
<pre id="uuidv8_info" style="display:none">Variant 1, Version 8 UUID:
63 daniel-mar 597
- 48 bit Custom data [Block 1+2]
35 daniel-mar 598
-  4 bit Version (fix 0x8)
63 daniel-mar 599
- 12 bit Custom data [Block 3]
35 daniel-mar 600
-  2 bit Variant (fix 0b10)
63 daniel-mar 601
- 62 bit Custom data [Block 4+5]</pre></p>
35 daniel-mar 602
 
34 daniel-mar 603
<form method="GET" action="interprete_uuid.php">
604
        <input type="hidden" name="version" value="8">
65 daniel-mar 605
 
606
        <label>Block&nbsp;1 (32&nbsp;bits):</label>0x<input type="text" name="block1" value="00000000" maxlength="8" id="v8_block1_hex" onkeyup="uuidv8_changehex(1, 0)" style="width:150px" pattern="[0-9a-fA-F]+"> = Decimal
607
        <input type="number" name="block1dec" value="0" min="0" maxlength="20" id="v8_block1_dec" onmouseup="uuidv8_changedec(1, 8)" onkeyup="uuidv8_changedec(1, 8)" style="width:150px"><br>
608
 
609
        <label>Block&nbsp;2 (16&nbsp;bits):</label>0x<input type="text" name="block2" value="0000" maxlength="4" id="v8_block2_hex" onkeyup="uuidv8_changehex(2, 0)" style="width:150px" pattern="[0-9a-fA-F]+"> = Decimal
610
        <input type="number" name="block2dec" value="0" min="0" maxlength="20" id="v8_block2_dec" onmouseup="uuidv8_changedec(2, 4)" onkeyup="uuidv8_changedec(2, 4)" style="width:150px"><br>
611
 
612
        <label>Block&nbsp;3 (<abbr title="The high 4 bits are occupied by the UUID version = 8">12&nbsp;bits</abbr>):</label>0x<input type="text" name="block3" value="0000" maxlength="4" id="v8_block3_hex" onkeyup="uuidv8_changehex(3, 0)" style="width:150px" pattern="[0-9a-fA-F]+"> = Decimal
613
        <input type="number" name="block3dec" value="0" min="0" maxlength="20" id="v8_block3_dec" onmouseup="uuidv8_changedec(3, 4)" onkeyup="uuidv8_changedec(3, 4)" style="width:150px"><br>
614
 
615
        <label>Block&nbsp;4 (<abbr title="The high 2 bits are occupied by the UUID variant = 0b10">14&nbsp;bits</abbr>):</label>0x<input type="text" name="block4" value="0000" maxlength="4" id="v8_block4_hex" onkeyup="uuidv8_changehex(4, 0)" style="width:150px" pattern="[0-9a-fA-F]+"> = Decimal
616
        <input type="number" name="block4dec" value="0" min="0" maxlength="20" id="v8_block4_dec" onmouseup="uuidv8_changedec(4, 4)" onkeyup="uuidv8_changedec(4, 4)" style="width:150px"><br>
617
 
618
        <label>Block&nbsp;5 (48&nbsp;bits):</label>0x<input type="text" name="block5" value="000000000000" maxlength="12" id="v8_block5_hex" onkeyup="uuidv8_changehex(5, 0)" style="width:150px" pattern="[0-9a-fA-F]+"> = Decimal
619
        <input type="number" name="block5dec" value="0" min="0" maxlength="20" id="v8_block5_dec" onmouseup="uuidv8_changedec(5, 12)" onkeyup="uuidv8_changedec(5, 12)" style="width:150px"><br>
620
 
34 daniel-mar 621
        <font color="red">Warning</font>: These UUIDs do not contain a timestamp,
622
        therefore the uniqueness of these UUIDs is not guaranteed!<br><br>
59 daniel-mar 623
        <input type="hidden" name="uuid" value="CREATE"> <input type="submit" value="Create UUIDv8">
34 daniel-mar 624
</form>
625
 
31 daniel-mar 626
<h2 id="interpret_uuid">Interpret a UUID</h2>
2 daniel-mar 627
 
30 daniel-mar 628
<p>You can enter a UUID in the following notations:</p>
2 daniel-mar 629
 
630
<ul>
631
        <li>Classic notation (case insensitive, curly braces optional): <code>9e83839a-5967-11e4-8c1c-78e3b5fc7f22</code></li>
632
        <li>As OID: <code>2.25.210700883446948645633376489934419689250</code></li>
633
</ul>
634
 
635
<p>The script will output:</p>
636
 
637
<ul>
638
        <li>Notation as UUID and OID</li>
35 daniel-mar 639
        <li>Version, variant, and additional data (date and time, clock sequence, node id, etc.)</li>
2 daniel-mar 640
</ul>
641
 
30 daniel-mar 642
<p>Please enter a UUID or UUID OID:</p>
2 daniel-mar 643
 
644
<form method="GET" action="interprete_uuid.php">
32 daniel-mar 645
        <input type="text" name="uuid" value="" style="width:300px"> <input type="submit" value="Interprete">
2 daniel-mar 646
</form>
647
 
31 daniel-mar 648
<h2 id="interpret_mac">Interpret a MAC address (<abbr title="Media Access Control">MAC</abbr> /
26 daniel-mar 649
<abbr title="Extended Unique Identifier">EUI</abbr> /
650
<abbr title="Extended Local Identifier">ELI</abbr> /
651
<abbr title="Standard Assigned Identifier">SAI</abbr> /
652
<abbr title="Administratively Assigned Identifier">AAI</abbr>)</h2>
2 daniel-mar 653
 
30 daniel-mar 654
<p>You can enter a UUID in the following notations:</p>
2 daniel-mar 655
 
656
<ul>
657
        <li><code>AA-BB-CC-DD-EE-FF</code></li>
658
        <li><code>AA:BB:CC:DD:EE:FF</code></li>
659
        <li><code>AABBCC.DDEEFF</code> (case insensitive)</li>
16 daniel-mar 660
        <li><code>AA-BB-CC-DD-EE-FF-11-22</code> (EUI-64)</li>
661
        <li><code>AA:BB:CC:DD:EE:FF-11-22</code> (EUI-64)</li>
662
        <li><code>fe80::1322:33ff:fe44:5566</code> (IPv6 Link Local / EUI-64)</li>
2 daniel-mar 663
</ul>
664
 
665
<p>The script will output:</p>
666
 
667
<ul>
668
        <li>Information about the I/G and U/L flags.</li>
669
        <li>Information about the entry in the IEEE registry, if available.</li>
670
        <li>Information about the registrant, if available.</li>
671
</ul>
672
 
29 daniel-mar 673
<p>Please enter a MAC (EUI, ELI, SAI, AAI), or IPv6-Link-Local address:</p>
2 daniel-mar 674
 
675
<form method="GET" action="interprete_mac.php">
32 daniel-mar 676
        <input type="text" name="mac" value="" style="width:250px"> <input type="submit" value="Interprete">
2 daniel-mar 677
</form>
678
 
62 daniel-mar 679
<h3 id="gen_aai">Generate an <abbr title="Administratively Assigned Identifier">AAI</abbr></h3>
41 daniel-mar 680
 
681
<p><i>An Administratively Assigned Identifier (AAI) is a MAC address which can be locally defined
682
by applications or an administrator. Unlike the EUI, an AAI is NOT worldwide unique.</i></p>
683
 
684
<form method="GET" action="interprete_mac.php">
685
    <input type="hidden" name="aai_gen" value="1">
686
    <input type="hidden" name="aai_gen_bits" value="48">
687
    <input type="hidden" name="aai_gen_multicast" value="0">
688
    <input type="hidden" name="uuid" value="CREATE"> <input type="submit" value="Generate AAI-48">
689
</form>
690
 
691
<br>
692
 
693
<form method="GET" action="interprete_mac.php">
694
    <input type="hidden" name="aai_gen" value="1">
695
    <input type="hidden" name="aai_gen_bits" value="64">
696
    <input type="hidden" name="aai_gen_multicast" value="0">
697
    <input type="hidden" name="uuid" value="CREATE"> <input type="submit" value="Generate AAI-64">
698
</form>
699
 
700
<p>The following options are rather unusual, but are implemented for the sake of completeness:</p>
701
 
702
<form method="GET" action="interprete_mac.php">
703
    <input type="hidden" name="aai_gen" value="1">
704
    <input type="hidden" name="aai_gen_bits" value="48">
705
    <input type="hidden" name="aai_gen_multicast" value="1">
706
    <input type="hidden" name="uuid" value="CREATE"> <input type="submit" value="Generate Multicast AAI-48">
707
</form>
708
 
709
<br>
710
 
711
<form method="GET" action="interprete_mac.php">
712
    <input type="hidden" name="aai_gen" value="1">
713
    <input type="hidden" name="aai_gen_bits" value="64">
714
    <input type="hidden" name="aai_gen_multicast" value="1">
715
    <input type="hidden" name="uuid" value="CREATE"> <input type="submit" value="Generate Multicast AAI-64">
716
</form>
717
 
718
 
22 daniel-mar 719
<br><br><br>
720
 
2 daniel-mar 721
</body>
722
 
723
</html>