Subversion Repositories uuid_mac_utils

Compare Revisions

Regard whitespace Rev 82 → Rev 83

/trunk/includes/uuid_utils.inc.php
837,7 → 837,7
 
// Block 5
$signature = substr($uuid,20,12);
if (strtolower($signature) == '4849434b454c'/*HICKEL*/) {
if (strtolower($signature) == '5ce32bd83b96') {
// HickelSOFT "SQL Server sortable UUID in C#"
// Version 2: Resolution of 1 milliseconds, random part of 18 bits, UTC time, UUIDv8 conform.
// Example: 2088dc33-000d-8045-87e8-4849434b454c
874,8 → 874,8
echo sprintf("%-32s %s\n", "Minute of day:", "[0x".substr($uuid,8,4)."] $minuteOfDay (".str_pad("$hours",2,'0',STR_PAD_LEFT).":".str_pad("$minutes",2,'0',STR_PAD_LEFT).")");
echo sprintf("%-32s %s\n", "Day of year:", "[0x".substr($uuid,13,3)."] $dayOfYear (Day=$day, Month=$month)");
echo sprintf("%-32s %s\n", "Random 2 bits:", "[$rnd2bits] 0b".str_pad("".base_convert("$rnd2bits", 16, 2), 2, '0', STR_PAD_LEFT));
echo sprintf("%-32s %s\n", "Year:", "[0x".substr($uuid,17,3)."] $year)");
echo sprintf("%-32s %s\n", "Signature:", "[0x".substr($uuid,20,12)."] HICKEL");
echo sprintf("%-32s %s\n", "Year:", "[0x".substr($uuid,17,3)."] $year");
echo sprintf("%-32s %s\n", "Signature:", "[0x".substr($uuid,20,12)."] HickelSOFT \"SQL Server Sortable Custom UUID\", Version 2 (very likely)");
echo sprintf("%-32s %s\n", "UTC Date Time:", $utc_time);
}
} else if (strtolower($signature) == '000000000000') {
920,7 → 920,7
echo sprintf("%-32s %s\n", "Day:", "[0x".substr($uuid,12,2)."] $day");
echo sprintf("%-32s %s\n", "Month:", "[0x".substr($uuid,14,2)."] $month");
echo sprintf("%-32s %s\n", "Year:", "[0x".substr($uuid,16,4)."] $year");
echo sprintf("%-32s %s\n", "Signature:", "[0x".substr($uuid,20,12)."]");
echo sprintf("%-32s %s\n", "Signature:", "[0x".substr($uuid,20,12)."] HickelSOFT \"SQL Server Sortable Custom UUID\", Version 1 (maybe)");
echo sprintf("%-32s %s\n", "Generator's Local Date Time:", $local_time);
}
}
1569,7 → 1569,7
if ($hickelUuidVersion == 1) {
$block5 = "000000000000";
} else if ($hickelUuidVersion == 2) {
$block5 = "4849434B454C"/*Hex:"HICKEL"*/;
$block5 = "5ce32bd83b96";
} else {
throw new Exception("Invalid version");
}
1580,7 → 1580,7
$block4 = substr($year, 2, 2).substr($year, 0, 2); // Example: 0x2420 = 2024
} else {
$variant = 0x8; // First nibble needs to be 0b10_ (0x8-0xB) for "RFC 4122bis". We use it to store 2 more random bits.
$rnd2bits = rand(0x0, 0x3);
$rnd2bits = _random_int(0x0, 0x3);
$year = $dt->format('Y');
$block4 = sprintf('%01x%03x', $variant + ($rnd2bits & 0x3), $year);
}
1605,16 → 1605,16
// Then: Sort block 1, bytes from right to left
$millisecond8bits = ceil(($dt->format('v') / 999) * 255);
if ($hickelUuidVersion == 1) {
$rnd16bits = rand(0x0000, 0xFFFF-1);
$rnd16bits = _random_int(0x0000, 0xFFFF-1);
$block1 = sprintf('%04x%02x', $rnd16bits, $millisecond8bits).$dt->format('s');
} else {
$rnd16bits = rand(0x0000, 0xFFFF);
$rnd16bits = _random_int(0x0000, 0xFFFF);
$block1 = sprintf('%04x%02x%02x', $rnd16bits, $millisecond8bits, $dt->format('s'));
}
 
// Now build and parse UUID
usleep((int)ceil(999 / 255)); // Make sure that "millisecond" is not repeated on this system
return "$block1-$block2-$block3-$block4-$block5";
return strtolower("$block1-$block2-$block3-$block4-$block5");
}
 
# --------------------------------------
/trunk/index.php
246,9 → 246,8
 
<p><i>The sorting of SQL Server is rather confusing and incompatible with UUIDv6 and UUIDv7.<br>
Therefore this method developed by <a href="https://www.hickelsoft.de/">HickelSOFT</a>
generates UUID which are sortable by SQL Server.<br>
Version 1: Resolution of 1 milliseconds, random part of 16 bits, local timezone, NOT UUIDv8 conform.<br>
Version 2: Resolution of 1 milliseconds, random part of 18 bits, UTC time, UUIDv8 conform.</i><br>
generates UUIDs which are sortable by SQL Server.<br>
They have a time resolution of 1 milliseconds combined with 18 bits of random data.</i><br>
<a href="https://gist.github.com/danielmarschall/7fafd270a3bc107d38e8449ce7420c25">C# implementation</a> |
<a href="https://github.com/danielmarschall/uuid_mac_utils/blob/master/includes/uuid_utils.inc.php">PHP implementation</a>
</p>
260,7 → 259,7
}
</script>
<p><a id="uuidv8_sqlserver_info_button" href="javascript:show_uuidv8_sqlserver_info()">Show format</a>
<pre id="uuidv8_sqlserver_info" style="display:none">Version 2: Resolution of 1 milliseconds, random part of 18 bits, UTC time, UUIDv8 conform:
<pre id="uuidv8_sqlserver_info" style="display:none">Version 2: Resolution of 1 milliseconds, random part of 18 bits, UTC time, 48 bit random "signature", UUIDv8 conform:
- 16 bit Random data
- 8 bit UTC Milliseconds transformed from 1000ms to 0..255 (hex encoded)
- 8 bit UTC Seconds (hex encoded)
270,9 → 269,9
- 2 bit UUID Variant (0b10)
- 2 bit Random data
- 12 bit UTC Year (hex encoded)
- 48 bit Signature "HICKEL" = 0x4849434B454C
- 48 bit Signature 0x5ce32bd83b96
 
Version 1: Resolution of 1 milliseconds, random part of 16 bits, local timezone, NOT UUIDv8 conform.
Version 1: Resolution of 1 milliseconds, random part of 16 bits, local timezone, 48 zero bit "signature", NOT UUIDv8 conform.
- 16 bit Random data
- 8 bit Generator's local timezone Milliseconds transformed from 1000ms to 0..255 (hex encoded)
- 8 bit Generator's local timezone Seconds (BCD encoded)
/trunk/interprete_uuid.php
21,15 → 21,15
$uuid = isset($_GET['uuid']) ? trim($_GET['uuid']) : 'CREATE';
 
$version = $_REQUEST['version'] ?? null;
$hash_sqlserver_version = null;
$hash_algo = null;
$v8_sqlserver_version = null;
$v8_hash_algo = null;
if (!is_null($version)) {
if (preg_match('@^(8)_sqlserver_v(.+)$@', $version, $m)) {
$version = $m[1];
$hash_sqlserver_version = $m[2];
$v8_sqlserver_version = $m[2];
} else if (preg_match('@^(8)_namebased_(.+)$@', $version, $m)) {
$version = $m[1];
$hash_algo = $m[2];
$v8_hash_algo = $m[2];
}
}
if (!is_numeric($version) || (strlen($version)!=1)) $version = 1; // default: Version 1 / time based
61,7 → 61,7
echo '<form method="GET" action="interprete_uuid.php">';
echo ' UUID: <input style="font-family:Courier,Courier New,Serif;width:325px" type="text" name="uuid" value="'.htmlentities($uuid).'"> <input type="submit" value="Interprete">';
echo '</form>';
} else if (($version!=3) && ($version!=5) && ($version!=8)) {
} else if (($version!=3) && ($version!=5) && (($version!=8) || ($v8_sqlserver_version!=null))) {
echo '<p><i>Reload the page to receive another UUID.</i></p>';
}
 
86,10 → 86,10
} else if ($version == '7') {
$uuid = gen_uuid_unix_epoch();
} else if ($version == '8') {
if ($hash_sqlserver_version != null) {
$uuid = gen_uuid_v8_sqlserver_sortable(intval($hash_sqlserver_version));
} else if ($hash_algo != null) {
$uuid = gen_uuid_v8_namebased($hash_algo, trim($_REQUEST['nb_ns']??''), trim($_REQUEST['nb_val']??''));
if ($v8_sqlserver_version != null) {
$uuid = gen_uuid_v8_sqlserver_sortable(intval($v8_sqlserver_version));
} else if ($v8_hash_algo != null) {
$uuid = gen_uuid_v8_namebased($v8_hash_algo, trim($_REQUEST['nb_ns']??''), trim($_REQUEST['nb_val']??''));
} else {
$uuid = gen_uuid_custom(trim($_REQUEST['block1']??'0'), trim($_REQUEST['block2']??'0'), trim($_REQUEST['block3']??'0'), trim($_REQUEST['block4']??'0'), trim($_REQUEST['block5']??'0'));
}