Subversion Repositories uuid_mac_utils

Rev

Rev 88 | 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
82 daniel-mar 5
* Copyright 2017 - 2024 Daniel Marschall, ViaThinkSoft
90 daniel-mar 6
* Version 2024-04-16
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>
75 daniel-mar 45
            <li><a href="#gen_uuidv7"><font color="green">New:</font> Generate Unix Epoch time-based (version 7) UUID</a></li>
46
            <li><a href="#gen_uuidv6"><font color="green">New:</font> Generate reordered Gregorian time-based (version 6) UUID</a></li>
31 daniel-mar 47
            <li><a href="#gen_uuidv4">Generate random (version 4) UUID</a></li>
75 daniel-mar 48
            <li><a href="#gen_uuidv1">Generate Gregorian time-based (version 1) UUID</a></li>
88 daniel-mar 49
            <li><a href="#gen_uuidv8_sqlserver"><font color="green">New:</font> Generate SQL Server sortable time-based (version 8) UUID</a></li>
31 daniel-mar 50
        </ul></li>
51
    <li><a href="#gen_other_uuid">Generate other UUID types</a><ul>
53 daniel-mar 52
            <li><a href="#gen_uuid_ncs">NCS (variant 0) UUID</a></li>
31 daniel-mar 53
            <li><a href="#gen_uuidv2">Generate DCE Security (version 2) UUID</a></li>
61 daniel-mar 54
            <li><a href="#gen_uuidv35">Generate name-based (version 3 / 5 / <font color="green">New: 8</font>) UUID</a></li>
55
            <li><a href="#gen_uuidv8"><font color="green">New:</font> Generate Custom (version 8) UUID</a></li>
31 daniel-mar 56
        </ul></li>
57
    <li><a href="#interpret_uuid">Interpret a UUID</a></li>
41 daniel-mar 58
    <li><a href="#interpret_mac">Interpret a MAC address (MAC / EUI / ELI / SAI / AAI)</a><ul>
59
        <li><a href="#gen_aai">Generate an AAI</a></li>
60
    </ul></li>
31 daniel-mar 61
</ul>
2 daniel-mar 62
 
31 daniel-mar 63
<h2 id="gen_uuid">Generate random and/or time-based UUIDs</h2>
30 daniel-mar 64
 
75 daniel-mar 65
<h3 id="gen_uuidv7"><font color="green">New:</font> Generate Unix Epoch time-based (version 7) UUID &#11088;</h3>
31 daniel-mar 66
 
72 daniel-mar 67
<p><i>A UUIDv7 measures time in the Unix Epoch with an accuracy
68
between 1ms and 245ns, depending on how many bits are spent for the timestamp (48-60 bits).
69
The rest of the UUID (62-74 bits) is filled with random data.
70
The timestamp is at the front of the UUID, therefore the UUIDs are monotonically increasing,
75 daniel-mar 71
which is good for using them in database indexes.
72
Since this UUID version does not contain a MAC address, it is also
72 daniel-mar 73
recommended due to the improved privacy.</i></p>
31 daniel-mar 74
 
35 daniel-mar 75
<script>
76
function show_uuidv7_info() {
77
        document.getElementById("uuidv7_info_button").style.display = "none";
78
        document.getElementById("uuidv7_info").style.display = "block";
79
}
80
</script>
62 daniel-mar 81
<p><a id="uuidv7_info_button" href="javascript:show_uuidv7_info()">Show format</a>
35 daniel-mar 82
<pre id="uuidv7_info" style="display:none">Variant 1, Version 7 UUID:
37 daniel-mar 83
- 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 84
-  4 bit Version (fix 0x7)
70 daniel-mar 85
- 12 bit Data
35 daniel-mar 86
-  2 bit Variant (fix 0b10)
70 daniel-mar 87
- 62 bit Data
35 daniel-mar 88
 
70 daniel-mar 89
Structure of data (74 bits):
90
- OPTIONAL : Sub-millisecond timestamp fraction (0-12 bits)
91
- OPTIONAL : Carefully seeded counter
92
- Random generated bits for any remaining space
93
 
94
Time resolution for various sub-millisecond bits:
31 daniel-mar 95
<?php
70 daniel-mar 96
for ($num_ms_frac_bits=0; $num_ms_frac_bits<=12; $num_ms_frac_bits++) {
97
        $resolution_ns = 1000000 / pow(2,$num_ms_frac_bits);
98
        if ($resolution_ns >= 1000000) $resolution_ns_hf = ($resolution_ns/1000000)." ms";
99
        else if ($resolution_ns >= 1000) $resolution_ns_hf = ($resolution_ns/1000)." &micro;s";
100
        else $resolution_ns_hf = "$resolution_ns ns";
101
        echo "$num_ms_frac_bits bits fraction = $resolution_ns_hf\n";
102
}
103
?>
72 daniel-mar 104
 
105
This implementation outputs:
106
- 12 bits sub-millisecond timestamp (~245ns resolution)
107
- no counter
108
- 62 bits random data
70 daniel-mar 109
</pre></p>
110
 
111
<?php
31 daniel-mar 112
if (AUTO_NEW_UUIDS > 0) { /** @phpstan-ignore-line */
35 daniel-mar 113
        echo '<p>Here are '.AUTO_NEW_UUIDS.' UUIDs that were created just for you! (Reload the page to get more)</p>';
31 daniel-mar 114
 
115
        echo '<pre>';
70 daniel-mar 116
        for ($i=0; $i<AUTO_NEW_UUIDS; $i++) {
31 daniel-mar 117
                $uuid = gen_uuid_v7();
118
                echo '<a href="interprete_uuid.php?uuid='.$uuid.'">'.$uuid.'</a><br>';
119
        }
120
        echo '</pre>';
121
}
122
?>
123
 
2 daniel-mar 124
<form method="GET" action="interprete_uuid.php">
31 daniel-mar 125
    <input type="hidden" name="version" value="7">
126
    <input type="hidden" name="uuid" value="CREATE"> <input type="submit" value="Create and display another UUID">
2 daniel-mar 127
</form>
128
 
75 daniel-mar 129
<h3 id="gen_uuidv6"><font color="green">New:</font> Generate reordered Gregorian time-based (version 6) UUID &#9200;</h3>
2 daniel-mar 130
 
31 daniel-mar 131
<p><i>Like UUIDv1, this kind of UUID is made of the MAC address of the generating computer,
132
        the time, and a clock sequence. However, the components in UUIDv6 are reordered (time is at the beginning),
75 daniel-mar 133
        so that UUIDs are monotonically increasing, which is good for using them in 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
 
75 daniel-mar 205
<h3 id="gen_uuidv1">Generate Gregorian 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
 
88 daniel-mar 245
<h3 id="gen_uuidv8_sqlserver">Generate SQL Server sortable time-based (version 8) UUID</h3>
82 daniel-mar 246
 
85 daniel-mar 247
<p><i>The sorting of UUIDs in SQL Server is rather confusing and incompatible with UUIDv6 and UUIDv7.<br>
82 daniel-mar 248
Therefore this method developed by <a href="https://www.hickelsoft.de/">HickelSOFT</a>
83 daniel-mar 249
generates UUIDs which are sortable by SQL Server.<br>
86 daniel-mar 250
They have a time resolution of 1 milliseconds combined with 16 bits of random data.</i><br>
82 daniel-mar 251
<a href="https://gist.github.com/danielmarschall/7fafd270a3bc107d38e8449ce7420c25">C# implementation</a> |
252
<a href="https://github.com/danielmarschall/uuid_mac_utils/blob/master/includes/uuid_utils.inc.php">PHP implementation</a>
253
</p>
254
 
255
<script>
256
function show_uuidv8_sqlserver_info() {
257
        document.getElementById("uuidv8_sqlserver_info_button").style.display = "none";
258
        document.getElementById("uuidv8_sqlserver_info").style.display = "block";
259
}
260
</script>
261
<p><a id="uuidv8_sqlserver_info_button" href="javascript:show_uuidv8_sqlserver_info()">Show format</a>
86 daniel-mar 262
<pre id="uuidv8_sqlserver_info" style="display:none">Version 2: Resolution of 1 milliseconds, random part of 16 bits, UTC time, 48 bit random "signature", UUIDv8 conform:
82 daniel-mar 263
- 16 bit Random data
84 daniel-mar 264
-  8 bit UTC Milliseconds transformed from 1000ms to 0..255, deviation -2ms..2ms (hex encoded)
82 daniel-mar 265
-  8 bit UTC Seconds (hex encoded)
266
- 16 bit UTC Minute of the day (1..1440, hex encoded)
267
-  4 bit UUID version 8
268
- 12 bit UTC Day of the year (1..366, hex encoded)
269
-  2 bit UUID Variant (0b10)
86 daniel-mar 270
-  2 bit Unused (must be zero)
82 daniel-mar 271
- 12 bit UTC Year (hex encoded)
83 daniel-mar 272
- 48 bit Signature 0x5ce32bd83b96
82 daniel-mar 273
 
86 daniel-mar 274
Version 1: Resolution of 1 milliseconds, random part of 16 bits, local timezone, 48 zero bits "signature", NOT UUIDv8 conform:
82 daniel-mar 275
- 16 bit Random data
84 daniel-mar 276
-  8 bit Generator's local timezone Milliseconds transformed from 1000ms to 0..255, deviation -4ms..0ms (hex encoded)
82 daniel-mar 277
-  8 bit Generator's local timezone Seconds (BCD encoded)
278
-  8 bit Generator's local timezone Minute (BCD encoded)
279
-  8 bit Generator's local timezone Hour (BCD encoded)
280
-  8 bit Generator's local timezone Day (BCD encoded)
281
-  8 bit Generator's local timezone Month (BCD encoded)
282
-  8 bit Generator's local timezone 2-digit year (BCD encoded)
283
-  8 bit Generator's local timezone 2-digit century (BCD encoded)
284
- 48 bit Signature 0x000000000000</pre></p>
285
 
286
<?php
287
if (AUTO_NEW_UUIDS > 0) { /** @phpstan-ignore-line */
288
    echo '<p>Here are '.AUTO_NEW_UUIDS.' UUIDs that were created just for you! (Reload the page to get more)</p>';
289
 
290
    echo '<pre>';
291
    for ($i=0; $i<AUTO_NEW_UUIDS; $i++) {
292
        $uuid = gen_uuid_v8_sqlserver_sortable();
293
        echo '<a href="interprete_uuid.php?uuid='.$uuid.'">'.$uuid.'</a><br>';
294
    }
295
    echo '</pre>';
296
}
297
?>
298
 
299
<form method="GET" action="interprete_uuid.php">
300
    <input type="hidden" name="version" value="8_sqlserver_v2">
301
    <input type="hidden" name="uuid" value="CREATE"> <input type="submit" value="Create and display another UUID (new version)">
302
</form><br>
303
 
304
<form method="GET" action="interprete_uuid.php">
305
    <input type="hidden" name="version" value="8_sqlserver_v1">
306
    <input type="hidden" name="uuid" value="CREATE"> <input type="submit" value="Create and display another UUID (old version)">
307
</form>
308
 
309
 
310
 
31 daniel-mar 311
<h2 id="gen_other_uuid">Generate other UUID types</h2>
30 daniel-mar 312
 
47 daniel-mar 313
<p><i>The following types of UUIDs are less common and/or require special knowledge. Please only use the following
30 daniel-mar 314
generators if you know what you are doing.</i></p>
315
 
53 daniel-mar 316
<h3 id="gen_uuid_ncs">NCS (variant 0) UUID</h3>
30 daniel-mar 317
 
53 daniel-mar 318
<p>The <abbr title="Network Computing System">NCS</abbr> UUIDs are a legacy format
319
initially designed by Apollo Computer that cannot be generated anymore, because the
30 daniel-mar 320
amount of available timestamp bits was exhausted on <strong>5 September 2015</strong>.
53 daniel-mar 321
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 322
<a href="interprete_uuid.php?uuid=ffffffff-ffff-0000-027f-000001000000"><code>ffffffff-ffff-0000-027f-000001000000</code></a>.</p>
30 daniel-mar 323
 
35 daniel-mar 324
<script>
325
function show_uuidnce_info() {
326
        document.getElementById("uuidnce_info_button").style.display = "none";
327
        document.getElementById("uuidnce_info").style.display = "block";
328
}
329
</script>
62 daniel-mar 330
<p><a id="uuidnce_info_button" href="javascript:show_uuidnce_info()">Show format</a>
35 daniel-mar 331
<pre id="uuidnce_info" style="display:none">Variant 0 UUID:
37 daniel-mar 332
- 32 bit High <abbr title="Count of 4&#xB5;s intervals passed since 1 Jan 1980 00:00:00 GMT">Time</abbr>
333
- 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 334
- 16 bit Reserved
335
-  1 bit Variant (fix 0b0)
37 daniel-mar 336
-  7 bit <abbr title="socket_$unspec (0x0)
337
socket_$unix (0x1)
338
socket_$internet (0x2)
339
socket_$implink (0x3)
340
socket_$pup (0x4)
341
socket_$chaos (0x5)
342
socket_$ns (0x6)
343
socket_$nbs (0x7)
344
socket_$ecma (0x8)
345
socket_$datakit (0x9)
346
socket_$ccitt (0xA)
347
socket_$sna (0xB)
348
socket_$unspec2 (0xC)
349
socket_$dds (0xD)">Family</abbr>
35 daniel-mar 350
- 56 bit Node</pre></p>
351
 
31 daniel-mar 352
<h3 id="gen_uuidv2">Generate DCE Security (version 2) UUID</h3>
30 daniel-mar 353
 
37 daniel-mar 354
<p><i>An UUIDv2 contains information about the creator (person, group, or organization), the generating system (MAC address), and time.
35 daniel-mar 355
The creator information replaced parts of the time bits, therefore the time resolution is very low.</i></p>
356
 
357
<script>
358
function show_uuidv2_info() {
359
        document.getElementById("uuidv2_info_button").style.display = "none";
360
        document.getElementById("uuidv2_info").style.display = "block";
361
}
362
</script>
62 daniel-mar 363
<p><a id="uuidv2_info_button" href="javascript:show_uuidv2_info()">Show format</a>
35 daniel-mar 364
<pre id="uuidv2_info" style="display:none">Variant 1, Version 2 UUID:
365
- 32 bit Local Domain Number
37 daniel-mar 366
- 16 bit Mid <abbr title="Count of 429.4967296s intervals passed since 15 Oct 1582 00:00:00 GMT">Time</abbr>
35 daniel-mar 367
-  4 bit Version (fix 0x2)
37 daniel-mar 368
- 12 bit High <abbr title="Count of 429.4967296s intervals passed since 15 Oct 1582 00:00:00 GMT">Time</abbr>
35 daniel-mar 369
-  2 bit Variant (fix 0b10)
370
-  6 bit Clock Sequence
37 daniel-mar 371
-  8 bit <abbr title="0 = person
372
1 = group
373
2 = org
374
3-255 = site-defined">Local Domain</abbr>
35 daniel-mar 375
- 48 bit MAC Address</pre></p>
376
 
30 daniel-mar 377
<form method="GET" action="interprete_uuid.php">
2 daniel-mar 378
        <input type="hidden" name="version" value="2">
88 daniel-mar 379
        <label>Domain (8&nbsp;bits):</label><select name="domain_choose" id="dce_domain_choice" onchange="javascript:dce_domain_choice_choose();">
34 daniel-mar 380
                <option value="uid">Person (e.g. POSIX UID)</option>
381
                <option value="gid">Group (e.g. POSIX GID)</option>
382
                <option value="org">Organization</option>
2 daniel-mar 383
                <option value="site">Site-defined</option>
88 daniel-mar 384
        </select> = Address Family ID: <input type="number" min="0" max="255" name="dce_domain" value="0" id="dce_domain" style="width:50px" pattern="[0-9]+" onchange="javascript:dce_domain_choose();"> (decimal notation)<br>
35 daniel-mar 385
        <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 386
        <font color="red">Warning</font>: The timestamp has an accuracy of 7:10 minutes,
30 daniel-mar 387
        therefore the uniqueness of these UUIDs is not guaranteed!<br><br>
59 daniel-mar 388
        <input type="hidden" name="uuid" value="CREATE"> <input type="submit" value="Create UUIDv2">
2 daniel-mar 389
</form>
390
<script>
391
function dce_domain_choose() {
88 daniel-mar 392
        var ns = document.getElementById('dce_domain').value;
393
        if (ns == "0") {
394
                document.getElementById('dce_domain_choice').value = "uid";
395
        } else if (ns == "1") {
396
                document.getElementById('dce_domain_choice').value = "gid";
397
        } else if (ns == "2") {
398
                document.getElementById('dce_domain_choice').value = "org";
399
        } else {
400
                document.getElementById('dce_domain_choice').value = "site";
401
        }
402
}
403
function dce_domain_choice_choose() {
2 daniel-mar 404
        var ns = document.getElementById('dce_domain_choice').value;
405
        if (ns == "uid") {
406
                document.getElementById('dce_domain').value = "0";
88 daniel-mar 407
        } else if (ns == "gid") {
2 daniel-mar 408
                document.getElementById('dce_domain').value = "1";
88 daniel-mar 409
        } else if (ns == "org") {
2 daniel-mar 410
                document.getElementById('dce_domain').value = "2";
88 daniel-mar 411
        } else if (ns == "site") {
2 daniel-mar 412
                document.getElementById('dce_domain').value = "";
413
        }
414
}
415
dce_domain_choose();
416
</script>
417
 
61 daniel-mar 418
<h3 id="gen_uuidv35">Generate name-based (version 3 / 5 / <font color="green">New: 8</font>) UUID</h3>
2 daniel-mar 419
 
57 daniel-mar 420
<p><i>An UUIDv3 is made out of a MD5 hash and an UUIDv5 is made out of a SHA1 hash.
90 daniel-mar 421
RFC 9562 also contains an example for a custom UUIDv8 implementation that
72 daniel-mar 422
uses modern hash algorithms.</i></p>
35 daniel-mar 423
 
424
<script>
425
function show_uuidv35_info() {
426
        document.getElementById("uuidv35_info_button").style.display = "none";
427
        document.getElementById("uuidv35_info").style.display = "block";
428
}
429
</script>
62 daniel-mar 430
<p><a id="uuidv35_info_button" href="javascript:show_uuidv35_info()">Show format</a>
58 daniel-mar 431
<pre id="uuidv35_info" style="display:none">Variant 1, Version 3/5/8 UUID:
35 daniel-mar 432
- 48 bit Hash High
58 daniel-mar 433
-  4 bit Version (fix 0x3, 0x5, or 0x8)
35 daniel-mar 434
- 12 bit Hash Mid
435
-  2 bit Variant (fix 0b10)
62 daniel-mar 436
- 62 bit Hash Low
35 daniel-mar 437
 
62 daniel-mar 438
 
90 daniel-mar 439
<u>As shown in <a href="https://www.ietf.org/rfc/rfc9562.txt">RFC 9562</a> Appendix B.2:</u>
69 daniel-mar 440
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 441
 
62 daniel-mar 442
</pre></p>
443
 
35 daniel-mar 444
<style>
445
label {
446
        width:120px;
447
        text-align:left;
448
        margin-right: 20px;
449
        display:inline-block;
450
}
451
</style>
452
 
2 daniel-mar 453
<form method="GET" action="interprete_uuid.php">
59 daniel-mar 454
        <label>Hash algorithm:</label><select name="version" id="nb_version" onchange="javascript:nb_version_choose();">
455
                <?php
67 daniel-mar 456
 
90 daniel-mar 457
                echo "\t\t<option disabled>--- UUIDv3 (defined in RFC 4122/9562) ---</option>\n";
67 daniel-mar 458
                echo "\t\t<option value=\"3\">MD5</option>\n";
90 daniel-mar 459
                echo "\t\t<option disabled>--- UUIDv5 (defined in RFC 4122/9562) ---</option>\n";
67 daniel-mar 460
                echo "\t\t<option value=\"5\" selected>SHA1</option>\n";
90 daniel-mar 461
                echo "\t\t<option disabled>--- UUIDv8 (shown in RFC 9562, Appendix B.2) ---</option>\n";
69 daniel-mar 462
                $tmp = [];
463
                $algos = hash_algos();
464
                $algos[] = 'shake128';
465
                $algos[] = 'shake256';
466
                foreach ($algos as $algo) {
467
                        if ($algo == 'md5') continue; // use UUIDv3 instead
468
                        if ($algo == 'sha1') continue; // use UUIDv5 instead
469
                        $friendlyName = strtoupper($algo);
470
 
471
                        if ($algo == 'shake128') $bits = 999;
472
                        else if ($algo == 'shake256') $bits = 999;
473
                        else $bits = strlen(hash($algo, '', true)) * 8;
75 daniel-mar 474
                        if ($bits < 128) $friendlyName .= " (Small hash size! $bits bits)"; // <-- this is not described in Appendix C.2
69 daniel-mar 475
 
82 daniel-mar 476
                        $tmp[$friendlyName] = '<option value="8_namebased_'.$algo.'">'.htmlentities($friendlyName).'</option>';
69 daniel-mar 477
                }
478
                natsort($tmp);
479
                foreach ($tmp as $html) {
480
                        echo "\t\t$html\n";
481
                }
482
 
59 daniel-mar 483
                ?>
75 daniel-mar 484
        </select><br>
35 daniel-mar 485
        <label>Namespace:</label><select name="namespace_choose" id="nb_nsc" onchange="javascript:nb_ns_choose();">
2 daniel-mar 486
                <option value="dns">DNS</option>
487
                <option value="url">URL</option>
488
                <option value="oid">OID</option>
489
                <option value="x500">X.500 DN</option>
76 daniel-mar 490
                <option value="r74n">R74n Namespace</option>
35 daniel-mar 491
                <!-- <option value="oidplus_ns">OIDplus ns only</option> -->
492
                <!-- <option value="oidplus_ns_val">OIDplus ns+val</option> -->
28 daniel-mar 493
                <!-- <option value="oidplus_pubkey">OIDplus pubkey</option> -->
2 daniel-mar 494
                <option value="other">Other</option>
59 daniel-mar 495
        </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 496
        <label>Value:</label><input type="text" name="nb_val" value="" id="nb_val" style="width:300px"><br>
30 daniel-mar 497
        <font color="red">Warning</font>: These UUIDs do not contain a timestamp,
498
        therefore the uniqueness of these UUIDs is not guaranteed!<br><br>
59 daniel-mar 499
        <input type="hidden" name="uuid" value="CREATE"> <input type="submit" id="nb_create_btn" value="Create UUID">
2 daniel-mar 500
</form>
501
<script>
59 daniel-mar 502
function nb_version_choose() {
503
        var ver = document.getElementById('nb_version').value;
504
        document.getElementById('nb_create_btn').value = 'Create UUIDv' + ver.substr(0,1);
505
}
35 daniel-mar 506
function nb_ns_textchange() {
507
        var ns = document.getElementById('nb_ns').value.toLowerCase();
508
        if (ns == "6ba7b810-9dad-11d1-80b4-00c04fd430c8") {
509
                if (document.getElementById('nb_nsc').value != "dns") {
510
                        document.getElementById('nb_nsc').value = "dns";
57 daniel-mar 511
                        document.getElementById('nb_val').value = "www.example.com";
35 daniel-mar 512
                }
513
        }
514
        else if (ns == "6ba7b811-9dad-11d1-80b4-00c04fd430c8") {
515
                if (document.getElementById('nb_nsc').value != "url") {
516
                        document.getElementById('nb_nsc').value = "url";
57 daniel-mar 517
                        document.getElementById('nb_val').value = "http://www.example.com/";
35 daniel-mar 518
                }
519
        }
520
        else if (ns == "6ba7b812-9dad-11d1-80b4-00c04fd430c8") {
521
                if (document.getElementById('nb_nsc').value != "oid") {
522
                        document.getElementById('nb_nsc').value = "oid";
523
                        document.getElementById('nb_val').value = "2.999";
524
                }
525
        }
526
        else if (ns == "6ba7b814-9dad-11d1-80b4-00c04fd430c8") {
527
                if (document.getElementById('nb_nsc').value != "x500") {
528
                        document.getElementById('nb_nsc').value = "x500";
529
                        document.getElementById('nb_val').value = "UID=jsmith,DC=example,DC=net";
530
                }
531
        }
76 daniel-mar 532
        else if (ns == "ca069732-780c-11ee-b962-000000000074") { // https://r74n.com/id/uuid
533
                if (document.getElementById('nb_nsc').value != "r74n") {
534
                        document.getElementById('nb_nsc').value = "r74n";
535
                        document.getElementById('nb_val').value = "ants";
536
                }
537
        }
35 daniel-mar 538
        else {
539
                if (document.getElementById('nb_nsc').value != "other") {
540
                        document.getElementById('nb_nsc').value = "other";
541
                        document.getElementById('nb_val').value = "";
542
                }
543
        }
544
}
2 daniel-mar 545
function nb_ns_choose() {
546
        var ns = document.getElementById('nb_nsc').value;
547
        if (ns == "dns") {
548
                document.getElementById('nb_ns').value = "6ba7b810-9dad-11d1-80b4-00c04fd430c8";
57 daniel-mar 549
                document.getElementById('nb_val').value = "www.example.com";
2 daniel-mar 550
        }
35 daniel-mar 551
        else if (ns == "url") {
2 daniel-mar 552
                document.getElementById('nb_ns').value = "6ba7b811-9dad-11d1-80b4-00c04fd430c8";
57 daniel-mar 553
                document.getElementById('nb_val').value = "http://www.example.com/";
2 daniel-mar 554
        }
35 daniel-mar 555
        else if (ns == "oid") {
2 daniel-mar 556
                document.getElementById('nb_ns').value = "6ba7b812-9dad-11d1-80b4-00c04fd430c8";
557
                document.getElementById('nb_val').value = "2.999";
558
        }
35 daniel-mar 559
        else if (ns == "x500") {
2 daniel-mar 560
                document.getElementById('nb_ns').value = "6ba7b814-9dad-11d1-80b4-00c04fd430c8";
561
                document.getElementById('nb_val').value = "UID=jsmith,DC=example,DC=net";
562
        }
76 daniel-mar 563
        else if (ns == "r74n") { // https://r74n.com/id/uuid
564
                document.getElementById('nb_ns').value = "ca069732-780c-11ee-b962-000000000074";
565
                document.getElementById('nb_val').value = "ants";
566
        }
35 daniel-mar 567
        /*
568
        else if (ns == "oidplus_ns") {
2 daniel-mar 569
                document.getElementById('nb_ns').value = "0943e3ce-4b79-11e5-b742-78e3b5fc7f22";
570
                document.getElementById('nb_val').value = "ipv4";
571
        }
35 daniel-mar 572
        else if (ns == "oidplus_ns_val") {
2 daniel-mar 573
                document.getElementById('nb_ns').value = "ad1654e6-7e15-11e4-9ef6-78e3b5fc7f22";
574
                document.getElementById('nb_val').value = "ipv4:8.8.8.8";
575
        }
35 daniel-mar 576
        else if (ns == "oidplus_ns_pubkey") {
28 daniel-mar 577
                document.getElementById('nb_ns').value = "fd16965c-8bab-11ed-8744-3c4a92df8582";
31 daniel-mar 578
                document.getElementById('nb_val').value = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqg/PnsC1WX3C1/mUSLuk0DIaDHtEsxBnG0auYJRJ1hBtbUUvItbK0odlKrX2SFo1MJJpu/SSxTzAgqkKZsZe3cCFkgA1svfuH9i94oGLjJ4n0kRJEGlanCmGndJBfIqGDJaQE2BJ8tLxeBrpkd9l0KvJsjhRmqJAb9KYK3KYFsWvT+wyjD3UJ1eHcgLbF/Qb3cwMU/u7Fs7ZpsNMW4phDPlsYsk9XHFpJ1/UCj6G53mYRfOC/ouDdGShlbVLB15s0V95QpnU/7lL8mJ2lE+sTZekGNBA4XbJv2gs21cR4E8zc/z+NyZS7117DYZoJqrAN8sKz6xGoKgQF6wueCK5qQIDAQAB";
28 daniel-mar 579
        }
580
        */
35 daniel-mar 581
        else if (ns == "other") {
2 daniel-mar 582
                document.getElementById('nb_ns').value = "";
583
                document.getElementById('nb_val').value = "";
584
        }
585
}
59 daniel-mar 586
nb_version_choose();
2 daniel-mar 587
nb_ns_choose();
588
</script>
589
 
61 daniel-mar 590
<h3 id="gen_uuidv8"><font color="green">New:</font> Generate Custom (version 8) UUID</h3>
34 daniel-mar 591
 
37 daniel-mar 592
<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 593
 
594
<script>
595
function show_uuidv8_info() {
596
        document.getElementById("uuidv8_info_button").style.display = "none";
597
        document.getElementById("uuidv8_info").style.display = "block";
598
}
65 daniel-mar 599
function uuidv8_changedec(block, len) {
600
        var x = document.getElementById("v8_block"+block+"_dec").value;
601
        if (x.trim() == "") x = 0;
602
        x = parseInt(x);
603
        if (isNaN(x)) {
604
                x = "???";
605
        } else {
606
                x = x.toString(16).padStart(len, '0');
607
                if ((len > 0) && (x.length > len)) x = "Overflow";
608
        }
609
        document.getElementById("v8_block"+block+"_hex").value = x;
610
}
611
function uuidv8_changehex(block, len) {
612
        var x = document.getElementById("v8_block"+block+"_hex").value;
613
        if (x.trim() == "") x = 0;
614
        x = parseInt(x, 16);
615
        if (isNaN(x)) {
616
                x = "???";
617
        } else {
618
                x = x.toString().padStart(len, '0');
619
                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)
620
        }
621
        document.getElementById("v8_block"+block+"_dec").value = x;
622
}
35 daniel-mar 623
</script>
62 daniel-mar 624
<p><a id="uuidv8_info_button" href="javascript:show_uuidv8_info()">Show format</a>
35 daniel-mar 625
<pre id="uuidv8_info" style="display:none">Variant 1, Version 8 UUID:
63 daniel-mar 626
- 48 bit Custom data [Block 1+2]
35 daniel-mar 627
-  4 bit Version (fix 0x8)
63 daniel-mar 628
- 12 bit Custom data [Block 3]
35 daniel-mar 629
-  2 bit Variant (fix 0b10)
63 daniel-mar 630
- 62 bit Custom data [Block 4+5]</pre></p>
35 daniel-mar 631
 
34 daniel-mar 632
<form method="GET" action="interprete_uuid.php">
633
        <input type="hidden" name="version" value="8">
65 daniel-mar 634
 
635
        <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
636
        <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>
637
 
638
        <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
639
        <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>
640
 
641
        <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
642
        <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>
643
 
644
        <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
645
        <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>
646
 
647
        <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
648
        <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>
649
 
34 daniel-mar 650
        <font color="red">Warning</font>: These UUIDs do not contain a timestamp,
651
        therefore the uniqueness of these UUIDs is not guaranteed!<br><br>
59 daniel-mar 652
        <input type="hidden" name="uuid" value="CREATE"> <input type="submit" value="Create UUIDv8">
34 daniel-mar 653
</form>
654
 
31 daniel-mar 655
<h2 id="interpret_uuid">Interpret a UUID</h2>
2 daniel-mar 656
 
30 daniel-mar 657
<p>You can enter a UUID in the following notations:</p>
2 daniel-mar 658
 
659
<ul>
660
        <li>Classic notation (case insensitive, curly braces optional): <code>9e83839a-5967-11e4-8c1c-78e3b5fc7f22</code></li>
661
        <li>As OID: <code>2.25.210700883446948645633376489934419689250</code></li>
662
</ul>
663
 
664
<p>The script will output:</p>
665
 
666
<ul>
667
        <li>Notation as UUID and OID</li>
35 daniel-mar 668
        <li>Version, variant, and additional data (date and time, clock sequence, node id, etc.)</li>
2 daniel-mar 669
</ul>
670
 
30 daniel-mar 671
<p>Please enter a UUID or UUID OID:</p>
2 daniel-mar 672
 
673
<form method="GET" action="interprete_uuid.php">
32 daniel-mar 674
        <input type="text" name="uuid" value="" style="width:300px"> <input type="submit" value="Interprete">
2 daniel-mar 675
</form>
676
 
31 daniel-mar 677
<h2 id="interpret_mac">Interpret a MAC address (<abbr title="Media Access Control">MAC</abbr> /
26 daniel-mar 678
<abbr title="Extended Unique Identifier">EUI</abbr> /
679
<abbr title="Extended Local Identifier">ELI</abbr> /
680
<abbr title="Standard Assigned Identifier">SAI</abbr> /
681
<abbr title="Administratively Assigned Identifier">AAI</abbr>)</h2>
2 daniel-mar 682
 
30 daniel-mar 683
<p>You can enter a UUID in the following notations:</p>
2 daniel-mar 684
 
685
<ul>
686
        <li><code>AA-BB-CC-DD-EE-FF</code></li>
687
        <li><code>AA:BB:CC:DD:EE:FF</code></li>
688
        <li><code>AABBCC.DDEEFF</code> (case insensitive)</li>
16 daniel-mar 689
        <li><code>AA-BB-CC-DD-EE-FF-11-22</code> (EUI-64)</li>
690
        <li><code>AA:BB:CC:DD:EE:FF-11-22</code> (EUI-64)</li>
691
        <li><code>fe80::1322:33ff:fe44:5566</code> (IPv6 Link Local / EUI-64)</li>
2 daniel-mar 692
</ul>
693
 
694
<p>The script will output:</p>
695
 
696
<ul>
697
        <li>Information about the I/G and U/L flags.</li>
698
        <li>Information about the entry in the IEEE registry, if available.</li>
699
        <li>Information about the registrant, if available.</li>
700
</ul>
701
 
29 daniel-mar 702
<p>Please enter a MAC (EUI, ELI, SAI, AAI), or IPv6-Link-Local address:</p>
2 daniel-mar 703
 
704
<form method="GET" action="interprete_mac.php">
32 daniel-mar 705
        <input type="text" name="mac" value="" style="width:250px"> <input type="submit" value="Interprete">
2 daniel-mar 706
</form>
707
 
62 daniel-mar 708
<h3 id="gen_aai">Generate an <abbr title="Administratively Assigned Identifier">AAI</abbr></h3>
41 daniel-mar 709
 
710
<p><i>An Administratively Assigned Identifier (AAI) is a MAC address which can be locally defined
711
by applications or an administrator. Unlike the EUI, an AAI is NOT worldwide unique.</i></p>
712
 
713
<form method="GET" action="interprete_mac.php">
714
    <input type="hidden" name="aai_gen" value="1">
715
    <input type="hidden" name="aai_gen_bits" value="48">
716
    <input type="hidden" name="aai_gen_multicast" value="0">
717
    <input type="hidden" name="uuid" value="CREATE"> <input type="submit" value="Generate AAI-48">
718
</form>
719
 
720
<br>
721
 
722
<form method="GET" action="interprete_mac.php">
723
    <input type="hidden" name="aai_gen" value="1">
724
    <input type="hidden" name="aai_gen_bits" value="64">
725
    <input type="hidden" name="aai_gen_multicast" value="0">
726
    <input type="hidden" name="uuid" value="CREATE"> <input type="submit" value="Generate AAI-64">
727
</form>
728
 
729
<p>The following options are rather unusual, but are implemented for the sake of completeness:</p>
730
 
731
<form method="GET" action="interprete_mac.php">
732
    <input type="hidden" name="aai_gen" value="1">
733
    <input type="hidden" name="aai_gen_bits" value="48">
734
    <input type="hidden" name="aai_gen_multicast" value="1">
735
    <input type="hidden" name="uuid" value="CREATE"> <input type="submit" value="Generate Multicast AAI-48">
736
</form>
737
 
738
<br>
739
 
740
<form method="GET" action="interprete_mac.php">
741
    <input type="hidden" name="aai_gen" value="1">
742
    <input type="hidden" name="aai_gen_bits" value="64">
743
    <input type="hidden" name="aai_gen_multicast" value="1">
744
    <input type="hidden" name="uuid" value="CREATE"> <input type="submit" value="Generate Multicast AAI-64">
745
</form>
746
 
22 daniel-mar 747
<br><br><br>
748
 
2 daniel-mar 749
</body>
750
 
751
</html>