[
  {
    "path": ".github/workflows/clojure.yml",
    "content": "name: Clojure CI\n\non:\n  push:\n    branches:\n      - \"*\"\n  pull_request:\n    branches: [ \"master\" ]\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n    - name: Checkout code\n      uses: actions/checkout@v3\n\n    - name: Prepare java\n      uses: actions/setup-java@v3\n      with:\n        distribution: 'zulu'\n        java-version: '17'\n\n    - name: Install clojure tools\n      uses: DeLaGuardo/setup-clojure@13.4\n      with:\n        # Install just one or all simultaneously\n        # The value must indicate a particular version of the tool, or use 'latest'\n        # to always provision the latest version\n        #        cli: 1.10.1.693              # Clojure CLI based on tools.deps\n        lein: 2.11.2                  # Leiningen\n\n    - name: Run tests\n      run: lein test\n"
  },
  {
    "path": ".gitignore",
    "content": "/target\n/classes\n/checkouts\npom.xml\npom.xml.asc\n*.jar\n*.class\n/.lein-*\n.nrepl-port\nlpr.sh\n\ntest/new.clj\n/clj-uuid.iml\n/.idea\n/.claude\n/.lein-failures\n/.lein-repl-history\n.DS_Store\n"
  },
  {
    "path": "CHANGES.md",
    "content": "# Changes\n\n## 0.2.5\n\n### Performance\n\nThe bitmop layer has been rewritten around ByteBuffer-based primitives\nand JVM intrinsics, delivering substantial performance gains across\nthe board with no changes to the public API.\n\n`mask-offset`, `mask-width`, and `bit-count` now compile to single\nhardware instructions (`TZCNT`, `POPCNT`) via `Long/numberOfTrailingZeros`\nand `Long/bitCount`, replacing the previous O(n) loops.\n\nA new ByteBuffer abstraction (`uuid->buf`, `buf->uuid`) provides\ndirect typed access at byte offsets via native `getLong`/`putLong`\noperations, eliminating manual shift/mask loops for serialization.\n\nRepresentative speedups over 0.2.0:\n\n| Category                        | Speedup     |\n|---------------------------------|-------------|\n| `to-byte-array`                 | **57x**     |\n| `to-hex-string`                 | **29x**     |\n| v3 (MD5) generation             | **9.0x**    |\n| v5 (SHA1) generation            | **6.0x**    |\n| v8 (custom) generation          | **4.2x**    |\n| v1 (time-based) generation      | **1.5x**    |\n| v6 (time-based) generation      | **1.4x**    |\n\nCombined generate + serialize operations see 3-19x end-to-end\nimprovement depending on UUID version and serialization format.\n\nv3/v5 generation now uses a fused digest pipeline with ThreadLocal\nByteBuffer reuse, `ByteBuffer/wrap` on digest output, and inlined\nversion/variant bit stamping -- eliminating all intermediate\nallocations and var lookups.  v5 is now at parity with JUG 5.2\n(~260 ns vs ~254 ns).\n\n### Correctness\n\n- `get-clk-seq` now uses `bitmop/ldb` to extract the 14-bit clock\n  sequence directly, fixing incorrect results that occurred when\n  Java's `.clockSequence()` method threw on non-v1 UUIDs.\n\n### Clock improvements\n\n- The Gregorian monotonic clock now uses `AtomicLong` with\n  `compareAndSet` on a packed long (50-bit millis + 14-bit seqid),\n  replacing `atom` + `swap!` + per-call `State` allocation.\n- v1 and v6 constructors inline the CAS loop and bit-field packing,\n  eliminating var lookup, function dispatch, and `ldb`/`dpb` overhead\n  on the hot path.\n- The monotonic counter initial state is now seeded with a\n  cryptographically random 10-bit value instead of zero, avoiding\n  predictable first values after library load.\n- Per-tick counter reseed uses 10-bit entropy (was 8-bit).\n\n### New UUID versions\n\n- v6 (reordered time-based, lexically sortable)\n- v7 (unix time-based, cryptographically secure, lexically sortable)\n- v7nc (unix time-based, non-cryptographic, maximum throughput)\n- v8 (custom / user-defined)\n- Max UUID sentinel (`+max+`, `max`, `max?`)\n\n`v7nc` uses `ThreadLocalRandom` and a per-thread monotonic counter\ninstead of `SecureRandom` and a global `AtomicLong`.  At ~39 ns/op,\nit is **1.26x faster** than JUG 5.2's `TimeBasedEpochGenerator`\n(~50 ns/op).\n\n### New protocol members\n\n- `get-instant` -- returns a `java.util.Date` for time-based UUIDs\n- `get-unix-time` -- returns POSIX millis for v1, v6, and v7\n- `get-clk-seq` -- returns the 14-bit clock sequence for v1 and v6\n- `to-hex-string` -- 32-character hex encoding (no dashes)\n- `to-uri` -- returns `java.net.URI` in URN format\n- `max?` -- predicate for the max UUID\n- `UUIDRfc9562` protocol (with `UUIDRfc4122` as a backward-compatible alias)\n\n### New constructors\n\n- `v0` / `null` -- null UUID constructor\n- `max` -- max UUID constructor\n- `v4` two-arity form `(v4 msb lsb)` -- stamps version and variant bits onto\n  caller-supplied words\n- Multi-arity `=`, `<`, `>` comparison operators\n\n### Extended polymorphism\n\n- `as-uuid` now accepts `java.net.URI`, byte arrays, and URN strings\n  in addition to canonical UUID strings\n- `uuidable?` predicate for testing coercibility\n\n### Build and packaging\n\n- Added `deps.edn` for tools.deps / CLI users\n- Removed `.travis.yml`; CI now uses GitHub Actions\n- Updated to Clojure 1.12.0 and primitive-math 1.0.1\n- Comprehensive test suite: 138 tests, 1.4M+ assertions, 0 failures\n- Test coverage: 94% forms, 93% lines (via cloverage)\n\n### Documentation\n\n- README rewritten to cover v6, v7, v8, max UUID, and the new\n  performance characteristics\n- Typo corrections throughout (`get-timestamp`, `approximately`,\n  `associated`, `requirements`, `consciousness`, `alphabetically`,\n  `elapsed`, `duplicate`, `construction`)\n"
  },
  {
    "path": "LICENSE",
    "content": "THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC\nLICENSE (\"AGREEMENT\"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM\nCONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.\n\n1. DEFINITIONS\n\n\"Contribution\" means:\n\na) in the case of the initial Contributor, the initial code and\ndocumentation distributed under this Agreement, and\n\nb) in the case of each subsequent Contributor:\n\ni) changes to the Program, and\n\nii) additions to the Program;\n\nwhere such changes and/or additions to the Program originate from and are\ndistributed by that particular Contributor. A Contribution 'originates' from\na Contributor if it was added to the Program by such Contributor itself or\nanyone acting on such Contributor's behalf. Contributions do not include\nadditions to the Program which: (i) are separate modules of software\ndistributed in conjunction with the Program under their own license\nagreement, and (ii) are not derivative works of the Program.\n\n\"Contributor\" means any person or entity that distributes the Program.\n\n\"Licensed Patents\" mean patent claims licensable by a Contributor which are\nnecessarily infringed by the use or sale of its Contribution alone or when\ncombined with the Program.\n\n\"Program\" means the Contributions distributed in accordance with this\nAgreement.\n\n\"Recipient\" means anyone who receives the Program under this Agreement,\nincluding all Contributors.\n\n2. GRANT OF RIGHTS\n\na) Subject to the terms of this Agreement, each Contributor hereby grants\nRecipient a non-exclusive, worldwide, royalty-free copyright license to\nreproduce, prepare derivative works of, publicly display, publicly perform,\ndistribute and sublicense the Contribution of such Contributor, if any, and\nsuch derivative works, in source code and object code form.\n\nb) Subject to the terms of this Agreement, each Contributor hereby grants\nRecipient a non-exclusive, worldwide, royalty-free patent license under\nLicensed Patents to make, use, sell, offer to sell, import and otherwise\ntransfer the Contribution of such Contributor, if any, in source code and\nobject code form.  This patent license shall apply to the combination of the\nContribution and the Program if, at the time the Contribution is added by the\nContributor, such addition of the Contribution causes such combination to be\ncovered by the Licensed Patents. The patent license shall not apply to any\nother combinations which include the Contribution. No hardware per se is\nlicensed hereunder.\n\nc) Recipient understands that although each Contributor grants the licenses\nto its Contributions set forth herein, no assurances are provided by any\nContributor that the Program does not infringe the patent or other\nintellectual property rights of any other entity. Each Contributor disclaims\nany liability to Recipient for claims brought by any other entity based on\ninfringement of intellectual property rights or otherwise. As a condition to\nexercising the rights and licenses granted hereunder, each Recipient hereby\nassumes sole responsibility to secure any other intellectual property rights\nneeded, if any. For example, if a third party patent license is required to\nallow Recipient to distribute the Program, it is Recipient's responsibility\nto acquire that license before distributing the Program.\n\nd) Each Contributor represents that to its knowledge it has sufficient\ncopyright rights in its Contribution, if any, to grant the copyright license\nset forth in this Agreement.\n\n3. REQUIREMENTS\n\nA Contributor may choose to distribute the Program in object code form under\nits own license agreement, provided that:\n\na) it complies with the terms and conditions of this Agreement; and\n\nb) its license agreement:\n\ni) effectively disclaims on behalf of all Contributors all warranties and\nconditions, express and implied, including warranties or conditions of title\nand non-infringement, and implied warranties or conditions of merchantability\nand fitness for a particular purpose;\n\nii) effectively excludes on behalf of all Contributors all liability for\ndamages, including direct, indirect, special, incidental and consequential\ndamages, such as lost profits;\n\niii) states that any provisions which differ from this Agreement are offered\nby that Contributor alone and not by any other party; and\n\niv) states that source code for the Program is available from such\nContributor, and informs licensees how to obtain it in a reasonable manner on\nor through a medium customarily used for software exchange.\n\nWhen the Program is made available in source code form:\n\na) it must be made available under this Agreement; and\n\nb) a copy of this Agreement must be included with each copy of the Program.\n\nContributors may not remove or alter any copyright notices contained within\nthe Program.\n\nEach Contributor must identify itself as the originator of its Contribution,\nif any, in a manner that reasonably allows subsequent Recipients to identify\nthe originator of the Contribution.\n\n4. COMMERCIAL DISTRIBUTION\n\nCommercial distributors of software may accept certain responsibilities with\nrespect to end users, business partners and the like. While this license is\nintended to facilitate the commercial use of the Program, the Contributor who\nincludes the Program in a commercial product offering should do so in a\nmanner which does not create potential liability for other Contributors.\nTherefore, if a Contributor includes the Program in a commercial product\noffering, such Contributor (\"Commercial Contributor\") hereby agrees to defend\nand indemnify every other Contributor (\"Indemnified Contributor\") against any\nlosses, damages and costs (collectively \"Losses\") arising from claims,\nlawsuits and other legal actions brought by a third party against the\nIndemnified Contributor to the extent caused by the acts or omissions of such\nCommercial Contributor in connection with its distribution of the Program in\na commercial product offering.  The obligations in this section do not apply\nto any claims or Losses relating to any actual or alleged intellectual\nproperty infringement. In order to qualify, an Indemnified Contributor must:\na) promptly notify the Commercial Contributor in writing of such claim, and\nb) allow the Commercial Contributor tocontrol, and cooperate with the\nCommercial Contributor in, the defense and any related settlement\nnegotiations. The Indemnified Contributor may participate in any such claim\nat its own expense.\n\nFor example, a Contributor might include the Program in a commercial product\noffering, Product X. That Contributor is then a Commercial Contributor. If\nthat Commercial Contributor then makes performance claims, or offers\nwarranties related to Product X, those performance claims and warranties are\nsuch Commercial Contributor's responsibility alone. Under this section, the\nCommercial Contributor would have to defend claims against the other\nContributors related to those performance claims and warranties, and if a\ncourt requires any other Contributor to pay any damages as a result, the\nCommercial Contributor must pay those damages.\n\n5. NO WARRANTY\n\nEXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON\nAN \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER\nEXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR\nCONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A\nPARTICULAR PURPOSE. Each Recipient is solely responsible for determining the\nappropriateness of using and distributing the Program and assumes all risks\nassociated with its exercise of rights under this Agreement , including but\nnot limited to the risks and costs of program errors, compliance with\napplicable laws, damage to or loss of data, programs or equipment, and\nunavailability or interruption of operations.\n\n6. DISCLAIMER OF LIABILITY\n\nEXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY\nCONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION\nLOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE\nEXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY\nOF SUCH DAMAGES.\n\n7. GENERAL\n\nIf any provision of this Agreement is invalid or unenforceable under\napplicable law, it shall not affect the validity or enforceability of the\nremainder of the terms of this Agreement, and without further action by the\nparties hereto, such provision shall be reformed to the minimum extent\nnecessary to make such provision valid and enforceable.\n\nIf Recipient institutes patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Program itself\n(excluding combinations of the Program with other software or hardware)\ninfringes such Recipient's patent(s), then such Recipient's rights granted\nunder Section 2(b) shall terminate as of the date such litigation is filed.\n\nAll Recipient's rights under this Agreement shall terminate if it fails to\ncomply with any of the material terms or conditions of this Agreement and\ndoes not cure such failure in a reasonable period of time after becoming\naware of such noncompliance. If all Recipient's rights under this Agreement\nterminate, Recipient agrees to cease use and distribution of the Program as\nsoon as reasonably practicable. However, Recipient's obligations under this\nAgreement and any licenses granted by Recipient relating to the Program shall\ncontinue and survive.\n\nEveryone is permitted to copy and distribute copies of this Agreement, but in\norder to avoid inconsistency the Agreement is copyrighted and may only be\nmodified in the following manner. The Agreement Steward reserves the right to\npublish new versions (including revisions) of this Agreement from time to\ntime. No one other than the Agreement Steward has the right to modify this\nAgreement. The Eclipse Foundation is the initial Agreement Steward. The\nEclipse Foundation may assign the responsibility to serve as the Agreement\nSteward to a suitable separate entity. Each new version of the Agreement will\nbe given a distinguishing version number. The Program (including\nContributions) may always be distributed subject to the version of the\nAgreement under which it was received. In addition, after a new version of\nthe Agreement is published, Contributor may elect to distribute the Program\n(including its Contributions) under the new version. Except as expressly\nstated in Sections 2(a) and 2(b) above, Recipient receives no rights or\nlicenses to the intellectual property of any Contributor under this\nAgreement, whether expressly, by implication, estoppel or otherwise. All\nrights in the Program not expressly granted under this Agreement are\nreserved.\n\nThis Agreement is governed by the laws of the State of Washington and the\nintellectual property laws of the United States of America. No party to this\nAgreement will bring a legal action under this Agreement more than one year\nafter the cause of action arose. Each party waives its rights to a jury trial\nin any resulting litigation.\n"
  },
  {
    "path": "README.md",
    "content": "clj-uuid\n========\n\n> _\"The intent of the UUID is to enable distributed systems to uniquely_\n> _identify information without significant central coordination.\"_\n> -- [_Wikipedia/UUID_](http://en.wikipedia.org/wiki/Universally_unique_identifier)\n\n* * * * * *\n\n**clj-uuid** is a Clojure library for generation and utilization of\nUUIDs (Universally Unique Identifiers) as described by\n[**IETF RFC-9562**](http://www.ietf.org/rfc/rfc9562.txt).\n\nThis library extends the standard Java\nUUID class to provide true v1, v6, v7 (time based),\nv3/v5 (namespace based), and v8 (user customizable)\nidentifier generation. Additionally, a number of useful\nutilities are provided to support serialization and\nmanipulation of these UUIDs in a simple, efficient manner.\n\nThe essential nature of the value RFC-9562 UUIDs provide is that of an\nenormous namespace and a deterministic mathematical model by means of\nwhich one navigates it. UUIDs represent an extremely powerful and\nversatile computation technique that is often overlooked, and\nunderutilized. In my opinion, this, in part, is due to the generally\npoor quality, performance, and capability of available libraries and,\nin part, due to a general misunderstanding in the popular consciousness\nof their proper use and benefit. It is my hope that this library will\nserve to expand awareness, make available, and simplify the use of standards\ncompliant UUIDs to a wider audience.\n\n### The Most Recent Release\n\nWith Leiningen:\n\n\n[![Clojars Project](https://img.shields.io/clojars/v/danlentz/clj-uuid.svg)](https://clojars.org/danlentz/clj-uuid)\n\n\n### What's new?\n\nThe latest release focuses on performance.  There are no external\nchanges to the API.\n\nclj-uuid 0.2.5 now uses ByteBuffer-based primitives and JVM intrinsics\nto deliver significant performance gains over traditional shift/mask\nloop approach.\n\n| Category                      | Speedup     |\n|-------------------------------|-------------|\n| `to-byte-array`               | **57x**     |\n| `to-hex-string`               | **29x**     |\n| v3 (MD5) generation           | **9.0x**    |\n| v5 (SHA1) generation          | **6.0x**    |\n| v8 (custom) generation        | **4.2x**    |\n| v1 (time-based) generation    | **1.5x**    |\n| v6 (time-based) generation    | **1.4x**    |\n\nv5 generation is now at parity with JUG 5.2 (~260 ns vs ~254 ns)\nthanks to a fused digest pipeline with ThreadLocal ByteBuffer reuse.\n\nA new `v7nc` constructor provides non-cryptographic v7 UUIDs at\n**~39 ns** -- **1.26x faster** than JUG's `TimeBasedEpochGenerator`\n(~50 ns).\n\nCombined generate + serialize operations see **3-19x** end-to-end\nimprovement depending on UUID version and serialization format.\n\nFor detailed benchmarks and further analysis, see:\n\n* [Performance Analysis](doc/perf-analysis.md) -- architectural analysis\n  of bitmop (old) vs bitmop2 (new) primitives\n* [Benchmarks](doc/uuid-generation-benchmarks.md) -- per-version timings, throughput, and combined operation benchmarks\n* [Competitive Benchmarks](doc/apples.md) -- head-to-head comparison with JUG, uuid-creator, and JDK\n\n\n### Why is this library useful??\n\nThe JVM version only provides an automatic generator for random (v4)\nand (non-namespaced) pseudo-v3 UUID's.  Where appropriate, this library\ndoes use the internal JVM UUID implementation.  The benefit with this library\nis that clj-uuid provides an easy way to get fast time-based (v1, v6),\ntrue namespaced (v3, v5), and high quality cryptographcically secure\ntime-based (v7) UUIDs.\n\n### But wait, why so many choices?\n\nEach version of UUID offers advantages in particular situations. Please\nread on to learn more, but, to help put you at ease, your decision on\nwhich is appropriate to use will usually be clear.\n\nv1, v6, and v7nc time-encoded UUIDs are useful because they can be generated\nmuch more quickly than other forms of UUID, as there is no need to\ncall a cryptographic random number generator.  v7nc is the fastest at ~39 ns.\n\nv3/v5 deternibistic UUID's are necessary because many of the interesting\nthings that you can do with UUID's require stable, reproducable,\nnamespaced identifiers.\n\nv7's combine time encoding, secure cryptogrsphy, lexical ordering, and\nindex-friendliness to provide a premium UUID experience, but at some\nadditional cost to produce.\n\n### How Big?\n\nThe provided namespace represents an _inexhaustable_ resource and as\nsuch can be used in a variety of ways not feasible using traditional\ntechniques rooted in the notions imposed by finite resources.  When I\nsay \"inexhaustable\" this of course is slight hyperbolie, but not by\nmuch.  The upper bound on the representation implemented by this\nlibrary limits the number of unique identifiers to a mere...\n\n*three hundred forty undecillion two hundred eighty-two decillion three*\n*hundred sixty-six nonillion nine hundred twenty octillion nine hundred*\n*thirty-eight septillion four hundred sixty-three sextillion four hundred*\n*sixty-three quintillion three hundred seventy-four quadrillion six hundred*\n*seven trillion four hundred thirty-one billion seven hundred sixty-eight*\n*million two hundred eleven thousand four hundred and fifty-five.*\n\nIf you think you might be starting to run low, let me know when you get down\nto your last few undecillion or so and I'll see what I can do to help out.\n\n### Usage\n\nUsing clj-uuid is really easy.  Docstrings are provided, but sometimes\nexamples help, too.  The following cases demonstrate about 90% of the\nfunctionality that you are likely to ever need.\n\nIn order to refer to the symbols in this library, it is recommended to\n*require* it in a given namespace:\n\n```clojure\n\n(require '[clj-uuid.core :as uuid])\n```\n\nOr include in namespace declaration:\n\n```clojure\n\n(ns foo\n  (:require [clj-uuid.core :as uuid])\n  ...\n  )\n\n```\n\nThe legacy single-segment namespace `clj-uuid` is still supported for\nbackward compatibility:\n\n```clojure\n\n(require '[clj-uuid :as uuid])  ;; also works\n```\n\n#### Literal Syntax\n\nUUID's have a convenient literal syntax supported by the clojure\nreader.  The tag `#uuid` denotes that the following string literal\nwill be read as a UUID.  UUID's evaluate to themselves, similarly to\nClojure keywords.\n\n```clojure\n\nuser> #uuid \"e6ff478d-9492-48dd-886d-23ec4c6385ee\"\n\n;;  => #uuid \"e6ff478d-9492-48dd-886d-23ec4c6385ee\"\n```\n\n\n#### The NULL Identifier\n\nThe special UUID, `#uuid \"00000000-0000-0000-0000-000000000000\"` is\nknown as the _**null** UUID_ or _version 0 UUID_ and can be useful for\nrepresenting special values such as _nil_ or _null-context_. One may\nreference the null UUID declaratively or functionally, although it is\nbest to pick one convention and remain consistant. When comparing UUID's\nthe NULL UUID is considered the MININUM VALUE.\n\n\n```clojure\n\nuser> (uuid/null)\n\n;;  => #uuid \"00000000-0000-0000-0000-000000000000\"\n\nuser> uuid/+null+\n\n;;  => #uuid \"00000000-0000-0000-0000-000000000000\"\n\n```\n\n\n#### The MAX Identifier\n\nThe special UUID, `#uuid \"ffffffff-ffff-ffff-ffff-ffffffffffff\"` is\nknown as the _**max** UUID_ and is used similarly to the _**null** UUID_.  When\ncomparing UUID's the NULL UUID is considered the MAXIMUM VALUE.\n\n\n```clojure\n\nuser> (uuid/max)\n\n;;  => #uuid \"ffffffff-ffff-ffff-ffff-ffffffffffff\"\n\nuser> uuid/+max+\n\n;;  => #uuid \"ffffffff-ffff-ffff-ffff-ffffffffffff\"\n\n```\n\n#### v6/v1: Fast, Time Encoded Identifiers\n\nYou can make your own v1 and v6 UUID's at home with the functions\n`uuid/v1` and `uuid/v6`.  These are fast to produce (~100 ns) and guarantee\nto be unique and thread-safe regardless of clock precision or degree of\nconcurrency, but each with slightly different characteristics:\n\nA v6 UUID encodes both the time and a random node identifier that is\nreset each time the library is loaded.  They are fast, lexically\n(alphabetically) ordered, and index-friendly.\n\nA v1 UUID is similar, but may reveal both the identity of the computer\nthat generated the UUID and the time at which it did so.  Its uniqueness\nacross computers is guaranteed as long as node/MAC addresses are not\nduplicated. In general, other than for legacy compatibility, the use\ncase for this would be for situations where it is useful to know the\nprovenance of any given UUID.  It does not provide lexical ordering or\nindex-friendliness.\n\n\n```clojure\n\n(uuid/v6)\n\n;; => #uuid \"1ef7b36c-4ca7-6df0-91a1-233a797d04c0\"\n;; => #uuid \"1ef7b36c-9c4c-60e0-91a1-233a797d04c0\"\n;; => #uuid \"1ef7b373-1c84-6180-91a1-233a797d04c0\"\n\n\n(uuid/v1)\n\n;; => #uuid \"ffa803f0-b3d3-11e4-a03e-3af93c3de9ae\"\n;; => #uuid \"005b7570-b3d4-11e4-a03e-3af93c3de9ae\"\n;; => #uuid \"018a0a60-b3d4-11e4-a03e-3af93c3de9ae\"\n```\n\nv7nc is the fastest UUID generator at ~39 ns, followed by v1 and v6 at ~100 ns,\nall significantly faster than the JVM's `java.util.UUID/randomUUID` (~345 ns):\n\n\n```\nuser> (criterium.core/bench (uuid/v7nc))\n\n;; Execution time mean : 39.412000 ns\n\nuser> (criterium.core/bench (uuid/v6))\n\n;; Execution time mean : 100.764073 ns\n\nuser> (criterium/bench (java.util.UUID/randomUUID))\n\n;; Execution time mean : 344.654110 ns\n\n```\n\n##### Sequential (Temporal) Namespace\n\nv6 and v1 UUID's retrievably encode the time of their creation.  The\nnative representation of this timestamp is as a 60 bit value indicating\nthe number of 100 nanosecond intervals since the Gregorian epoch (for\nthe younger readers, this was at 12am Friday October 15, 1582 UTC).\n\n\n```clojure\n\nuser> (uuid/get-timestamp (uuid/v6))\n\n;;  => 136459064897650000\n\n\nuser> (map uuid/get-timestamp (repeatedly 10 uuid/v1))\n\n;;  => (136459065592300000\n;;      136459065592310000\n;;      136459065592320000\n;;      136459065592340000\n;;      136459065592340001 <-+ subcounter ensures unique timestamp\n;;      136459065592350000   | even when the resolution of the\n;;      136459065592350001 <-+ system clock is insufficiently\n;;      136459065592370000   | granular to provide uniqueness.\n;;      136459065592370001 <-+\n;;      136459065592380000)\n```\n\nClearly, that is pretty useful.  We can look at any two time-based\nUUID's and compare their timestamps relative to one another.  We can\nalso look at the absolute timestamp values of time-based UUID's using the\nideomatic Clojure representation of timestamp values:\n\n\n```clojure\n\nuser> (uuid/get-instant (uuid/v1))\n\n;;  => #inst \"2015-03-17T17:51:15.970-00:00\"\n\n\nuser> (map uuid/get-instant (repeatedly 10 uuid/v1))\n\n;;  => (#inst \"2015-03-17T17:51:53.800-00:00\" <-+ Note, however,\n;;      #inst \"2015-03-17T17:51:53.800-00:00\" <-+ insufficient clock precision\n;;      #inst \"2015-03-17T17:51:53.802-00:00\"   | to distinguish betweem\n;;      #inst \"2015-03-17T17:51:53.803-00:00\" <-+ absolute timestamp values\n;;      #inst \"2015-03-17T17:51:53.803-00:00\" <-+\n;;      #inst \"2015-03-17T17:51:53.804-00:00\"\n;;      #inst \"2015-03-17T17:51:53.807-00:00\"\n;;      #inst \"2015-03-17T17:51:53.808-00:00\"\n;;      #inst \"2015-03-17T17:51:53.812-00:00\"\n;;      #inst \"2015-03-17T17:51:53.814-00:00\")\n```\n\n\n#### v4: Random Identifiers\n\nV4 identifiers are generated by directly invoking the static method\n`java.util.UUID/randomUUID` and are, in typical situations, slower to\ngenerate in addition to being non-deterministically unique. It exists\nprimarily because it is very simple to implement and because randomly\ngenerated UUID's are hard to guess.  They can be useful in that case,\nfor example to seed a UUID namespace as we will see in a later example.\n\n```clojure\n\nuser> (uuid/v4)\n\n;; => #uuid \"49c248c3-d232-4960-b2f4-fd5a3a72ea62\"\n```\n\n\n#### v7: Time Encoded Cryptographically Random Identifiers\n\nCombining some of the best features of all of the above, v7 UUIDs\nprovide time encoding, lexical ordering, and entropy-friendly\nrandomness, at, of course, some additional cost to compute.\n\n\n```clojure\n\nuser> (uuid/v7)\n\n;; => #uuid \"0192292b-c52c-7058-bdf8-741af201c7d3\"\n\nuser> (uuid/get-timestamp (uuid/v7))\n\n;; => 1727267644205  (note -- POSIX time!)\n\nuser> (uuid/get-instant (uuid/v7))\n\n;; => #inst \"2024-09-25T12:34:57.981-00:00\"\n\n\nuser> (criterium.core/bench (uuid/v7))\n\n;; Execution time mean : 333.232000 ns\n\n```\n\nIf cryptographic unguessability of the random portion is not required,\n`v7nc` provides the same v7 UUID structure using `ThreadLocalRandom`\ninstead of `SecureRandom`:\n\n```clojure\n\nuser> (uuid/v7nc)\n\n;; => #uuid \"0194cba3-f2d1-7a4c-8b1e-6c3a9d8e4f21\"\n\nuser> (criterium.core/bench (uuid/v7nc))\n\n;; Execution time mean : 39.412000 ns\n\n```\n\n#### Lexical Comparability\n\nOk, you've heard me mention \"lexical ordering\" a few times. What does\nthis mean?  v6 and v7 UUIDs offer identifiers that can be efficiently\nordered alphabetically, requiring no decoding, based on the order of\ntheir creation. Let's take an example:\n\n```clojure\n\nuser> (def x (uuid/v7))\n\n;; => #uuid \"0192293c-8640-7058-9106-b97bf1754d98\"\n\nuser> (def y (uuid/v7))\n\n;; => #uuid \"0192293c-a931-709d-afba-5ad27082a4b6\"\n\nuser> (get-instant x)\n\n;; => #inst \"2024-09-25T12:51:25.376-00:00\"\n\nuser> (get-instant y)\n\n;; => #inst \"2024-09-25T12:51:34.321-00:00\"\n\n```\n\nAs you can see, it is always possible to order time encoded ids by\nparsing them, but v6 and v7 UUIDs make this easier, on any platform,\neven if you don't have your trusty clj-uuid library available.\n\n\n```clojure\nuser> (uuid/= x y)\n\n;; => false\n\nuser> (uuid/< x y)\n\n;; => true\n\nuser> (clojure.core/compare (str x) (str y))\n\n;; => -41  (negative -- ie, \"less than\")\n\nuser> (clojure.core/compare (str y) (str x))\n\n;; =>  41  (positive -- ie  \"greater than\")\n\n\n```\n\n#### v3/v5: Namespaced Identifiers\n\nFirst of all, the only difference between v3 and v5 UUID's is that v3's\nare computed using an MD5 digest algorithm and v5's are computed using SHA1.\nIt is generally considered that SHA1 is a superior hash, but MD5 is\ncomputationally less expensive and so v3 may be preferred in\nsituations requiring slightly faster performance. As such, when we give\nexamples of namespaced identifiers, we will typically just use `v5` with\nthe understanding that `v3` could be used identically in each case.\n\n##### Namespaces\n\nIf you are familiar with Clojure _vars_, you already understand the\nidea of _namespaced_ identifiers.  To resolve the value of a var, one\nneeds to know not only the _name_ of a var, but also the _namespace_\nit resides in.  It is intuitively clear that vars `#'user/x` and\n`#'library/x` are distinct.  Namespaced UUID's follow a similar\nconcept, however namespaces are themselves represented as UUID's.\nNames are strings that encode a representation of a symbol or value in\nthe namespace of that identifier.  Given a namespace and a local-name,\none can always (re)construct the unique identifier that represents\nit.  We can demonstrate a few examples constructed using several of\nthe canonical top level namespace UUIDs:\n\n```clojure\n\nuser> (uuid/v5 uuid/+namespace-url+ \"http://example.com/\")\n\n;;  => #uuid \"0a300ee9-f9e4-5697-a51a-efc7fafaba67\"\n\nuser> (uuid/v5 uuid/+namespace-x500+ \"http://example.com/\")\n\n;;  => #uuid \"0cb29677-4eaf-578f-ab9b-f9ac67c33cb9\"\n\n\nuser> (uuid/v3 uuid/+namespace-dns+ \"www.clojure.org\")\n\n;;  => #uuid \"3bdca4f7-fc85-3a8b-9038-7626457527b0\"\n\n\nuser> (uuid/v5 uuid/+namespace-oid+ \"0.1.22.13.8.236.1\")\n\n;;  => #uuid \"9989a7d2-b7fc-5b6a-84d6-556b0531a065\"\n```\n\nYou can see in each case that the local \"name\" string is given in some\nwell-definted format specific to each namespace.  This is a very\ncommon convention, but not enforced.  It is perfectly valid to\nconstruct a namespaced UUID from any literal string.\n\n```clojure\n\nuser> (uuid/v5 uuid/+namespace-url+ \"I am clearly not a URL\")\n\n;;  => #uuid \"a167a791-e550-57ae-b20f-666ee47ce7c1\"\n```\n\nAs a matter of fact, the requirements for a valid the local-part\nconstituent are even more general than even just Strings.  Any kind of\nobject will do:\n\n```clojure\n\nuser> (uuid/v5 uuid/+namespace-url+ :keyword)\n\n;;  => #uuid \"bc480d53-fba7-5e5f-8f33-6ad77880a007\"\n\nuser> (uuid/v5 uuid/+namespace-url+ :keyword)\n\n;;  => #uuid \"bc480d53-fba7-5e5f-8f33-6ad77880a007\"\n\nuser> (uuid/v5 uuid/+namespace-oid+ :keyword)\n\n;;  => #uuid \"9b3d8a3d-fadf-55b5-811f-12a0c50c3e86\"\n\n\n\nuser> (uuid/v5 uuid/+null+ 'this-symbol)\n\n;;  => #uuid \"8b2941d5-e40b-5364-afcf-0008833715a2\"\n\nuser> (uuid/v5 uuid/+null+ 'this-symbol)\n\n;;  => #uuid \"8b2941d5-e40b-5364-afcf-0008833715a2\"\n\n\n```\n\nThis will be most efficient for classes of object that have been\nextended with the `UUIDNameBytes` protocol.  If one intends to do such\na thing fequently, it is a simple matter to specialize an\n`as-byte-array` method which can extract a byte serialization that\nrepresents the 'name' of an object, typically unique within some given\nnamespace.  Here is a simple example where one adds specialized support\nfor URLs to be quickly digested as the bytes of their string representation.\n\n\n```clojure\n\n(extend-protocol UUIDNameBytes java.net.URL\n  (as-byte-array [this]\n    (.getBytes (.toString this) StandardCharsets/UTF_8)))\n\n\n(uuid/v5 uuid/+namespace-url+ \"http://example.com/\")\n\n;; => #uuid \"0a300ee9-f9e4-5697-a51a-efc7fafaba67\"\n\n\n(uuid/v5 uuid/+namespace-url+ (java.net.URL. \"http://example.com/\"))\n\n;; => #uuid \"0a300ee9-f9e4-5697-a51a-efc7fafaba67\"\n\n```\n\n\n##### Hierarchical Namespace\n\nBecause each UUID denotes its own namespace, it is easy to compose v5\nidentifiers in order to represent hierarchical sub-namespaces.  This,\nfor example, can be used to assign unique identifiers based not only\non the content of a string but the unique identity representing its\nsource or provenance:\n\n```clojure\n\nuser> (uuid/v5\n        (uuid/v5 uuid/+namespace-url+ \"http://example.com/\")\n        \"resource1#\")\n\n;;  => #uuid \"6a3944a4-f00e-5921-b8b6-2cea5a745132\"\n\n\nuser> (uuid/v5\n        (uuid/v5 uuid/+namespace-url+ \"http://example.com/\")\n        \"resource2#\")\n\n;;  => #uuid \"98879e2a-8511-59ab-877d-ac6f8667866d\"\n\n\nuser> (uuid/v5\n        (uuid/v5 uuid/+namespace-url+ \"http://other.com/\")\n        \"resource1#\")\n\n;;  => #uuid \"bc956d0c-7af3-5b81-89f2-a96e8f9fd1a8\"\n\n\nuser> (uuid/v5\n        (uuid/v5 uuid/+namespace-url+ \"http://other.com/\")\n        \"resource2#\")\n\n;;  => #uuid \"a38b24fe-7ab8-58c8-a3f8-d3adb308260b\"\n\n\n```\n\nBecause UUID's and namespaces can be chained together like this, one\ncan be certain that the UUID resulting from a chain of calls such as\nthe following will be unique -- if and only if the original namespace\nmatches:\n\n\n```clojure\n\nuser> (-> (uuid/v1)\n        (uuid/v5 \"one\")\n        (uuid/v5 \"two\")\n        (uuid/v5 \"three\"))\n\n;;  => #uuid \"eb7a0c2b-eb0e-5bb2-9819-3c9edc2814fa\"\n\n\nuser> (-> (uuid/v1)\n        (uuid/v5 \"one\")\n        (uuid/v5 \"two\")\n        (uuid/v5 \"three\"))\n\n;;  => #uuid \"45e8c272-1660-57ba-8892-6844e1d3196a\"\n\n```\n\n\nAt each step, the local part string must be identical, in order for the the\nfinal UUID to match:\n\n```clojure\n\nuser> (-> uuid/+namespace-dns+\n        (uuid/v5 \"one\")\n        (uuid/v5 \"two\")\n        (uuid/v5 \"three\"))\n\n;;  => #uuid \"617756cc-3b02-5a86-ad4a-ab3e1403dbd6\"\n\n\nuser> (-> uuid/+namespace-dns+\n        (uuid/v5 \"two\")\n        (uuid/v5 \"one\")\n        (uuid/v5 \"three\"))\n\n;;  => #uuid \"52d5453e-2aa1-53c1-b093-0ea20ef57ad1\"\n\n```\n\nThis capability can be used to represent uniqueness of a sequence of\ncomputations in, for example, a transaction system such as the one\nused in the graph-object database system\n[de.setf.resource](http://github.com/lisp/de.setf.resource/) or this\ninteresting new [CQRS/ES Server](http://yuppiechef.github.io/cqrs-server/).\n\n### A Simple Example\n\nOk, so now you know how to use this nifty new UUID library and you are\nburning up to do something awesome with UUID's... But, ah, hmmm... First\nyou need to figure out what exactly you want to do with them.  Well,\nbefore you start working on your distributed cloud-based secret\nweapon, here is a simple way you can generate cryptographically\nsecure activation keys for your draconian licensing scheme.\n\nFirst, we pick a secret key.  We might pick a time-based id, or we might\nbegin with some secret namespace, secret identifier pair to compute that\ninitial namespace deterministically.  This is convenient, but not necessary\n-- the time-based or random private key could also be stored in some form\nof persistent memory.  As unguessability important to deter hackers, we will\nchoose a random namespace and record it in some secret, persistent storage\nto ensure we can regenerate a user's activation code identically on-demand\nin the future.\n\n```clojure\n\nuser> (def +secret-weapon-licensing-namespace+ (uuid/v4))\n\n\nuser> (uuid/v5 +secret-weapon-licensing-namespace+ \"joe@example.com\")\n\n;;  => #uuid \"b6433d1e-d369-5282-8dbc-bdd3845c376c\"\n\n\nuser> (uuid/v5 +secret-weapon-licensing-namespace+ \"mom@knitting-arts.edu\")\n\n;;  => #uuid \"81e4708c-85bb-5f3c-be56-bba4d8b0ac91\"\n\n```\n\nNow, as the orders start rolling in for your product, you can crank out\nsecret weapon activation codes just as well as if you were Microsoft.\nEach one will be keyed to a user's email address and is guaranteed\nto be irreversible.  You will infuriate them with unreasonably high\nmaintence support contract fees and intractible licensing terms.\nYou truly are diabolical.\n\n\n### Basic API\n\n* * * * * *\n\n#### Namespaces\n\n_(var)_         `+null+`\n\n> `#uuid \"00000000-0000-0000-0000-000000000000\"`\n\n_(var)_         `+max+`\n\n> `#uuid \"ffffffff-ffff-ffff-ffff-ffffffffffff\"`\n\n\n_(var)_         `+namespace-dns+`\n\n> `#uuid \"6ba7b810-9dad-11d1-80b4-00c04fd430c8\"`\n\n\n_(var)_         `+namespace-url+`\n\n> `#uuid \"6ba7b811-9dad-11d1-80b4-00c04fd430c8\"`\n\n\n_(var)_         `+namespace-oid+`\n\n> `#uuid \"6ba7b812-9dad-11d1-80b4-00c04fd430c8\"`\n\n\n_(var)_         `+namespace-x500+`\n\n> `#uuid \"6ba7b814-9dad-11d1-80b4-00c04fd430c8\"`\n\n* * * * * *\n\n#### Generators\n\n_(function)_    `null []`\n\n> Return the null UUID, a special form of sentinel UUID that is specified to have\n> all 128 bits set to zero: #uuid \"00000000-0000-0000-0000-000000000000\"\n\n_(function)_    `max []`\n\n> Return the max UUID, a special form of sentinel UUID that is specified to have\n> all 128 bits set to one: \"#uuid \"ffffffff-ffff-ffff-ffff-ffffffffffff\"\n\n_(function)_    `v1 []`\n\n> Generate a v1 (time-based) unique identifier, guaranteed to be unique\n> and thread-safe regardless of clock precision or degree of concurrency.\n> Creation of v1 UUID's does not require any call to a cryptographic\n> generator and can be accomplished much more efficiently than v3, v4, v5, v7,\n> or squuid's.  A v1 UUID reveals both the identity of the computer that\n> generated the UUID and the time at which it did so.  Its uniqueness across\n> computers is guaranteed as long as MAC addresses are not duplicated.\n\n_(function)_    `v3 [^UUID namespace ^Object local-name]`\n\n>  Generate a v3 (name based, MD5 hash) UUID. context' must be UUIDable.\n>  v3 identifiers are intended for generating UUID's from names that are\n>  drawn from, and unique within, some namespace.  The concept of name and\n>  namespace should be broadly construed, and not limited to textual names.\n>  The requirements for a v3 UUID are as follows:\n>\n>  * v3 UUID's generated at different times from the same name in the same\n>    namespace MUST be equal.\n>\n>  * v3 UUID's generated from two different names in the same namespace\n>    SHOULD be distinct with a high degree of certainty.\n>\n>  * v3 UUID's generated from the same name in two different namespaces\n>    SHOULD be distinct with a high degree of certainty.\n>\n>  * If two v3 UUID's are equal, then there is a high degree of certainty\n>    that they were generated from the same name in the same namespace.\n\n_(function)_    `v4 []`\n\n_(function)_    `v4 [^long msb, ^long lsb]`\n\n>  Generate a v4 (random) UUID.  Uses default JVM implementation.  If two\n>  arguments, lsb and msb (both long) are provided, then construct a valid,\n>  properly formatted v4 UUID based on those values.  So, for example the\n>  following UUID, created from all zero bits, is indeed distinct from the\n>  null UUID:\n>\n>      (v4)\n>       => #uuid \"dcf0035f-ea29-4d1c-b52e-4ea499c6323e\"\n>\n>      (v4 0 0)\n>       => #uuid \"00000000-0000-4000-8000-000000000000\"\n>\n>      (null)\n>       => #uuid \"00000000-0000-0000-0000-000000000000\"\n\n\n_(function)_    `v5 [^UUID namespace ^Object local-name]`\n\n>  Generate a v5 (name based, SHA1 hash) UUID. 'context' must be UUIDable.\n>  v5 identifiers are intended for generating UUID's from names that are\n>  drawn from, and unique within, some namespace.  The concept of name and\n>  namespace should be broadly construed, and not limited to textual names.\n>  The requirements for a v5 UUID are as follows:\n>\n>  * v5 UUID's generated at different times from the same name in the same\n>    namespace MUST be equal.\n>\n>  * v5 UUID's generated from two different names in the same namespace\n>    SHOULD be distinct with a high degree of certainty.\n>\n>  * v5 UUID's generated from the same name in two different namespaces\n>    SHOULD be distinct with a high degree of certainty.\n>\n>  * If two v5 UUID's are equal, then there is a high degree of certainty\n>    that they were generated from the same name in the same namespace.\n\n_(function)_    `v6 []`\n\n> Generate a v6 (time-based), LEXICALLY SORTABLE, unique identifier,\n> v6 is a field-compatible version of v1, reordered for improved DB\n> locality.  Creation of v6 UUID's does not require any call to a\n> cryptographic generator and can be accomplished much more efficiently\n> than v3, v4, v5, v7, or squuid's.  A v6 UUID uses a cryptographically\n> secure, hard to guess random node id. It DOES NOT reveal the identity\n> of the computer on which it was created.\n\n_(function)_    `v7 []`\n\n>  Generate a v7 unix time-based, LEXICALLY SORTABLE UUID with monotonic\n>  counter, cryptographically secure random portion, and POSIX time encoding.\n>  As such, creation of v7 UUIDs may be slower, but have improved\n>  entropy chararacteristics compared to v1 or v6 UUIDs.\n\n_(function)_    `v7nc []`\n\n>  Generate a v7 UUID using non-cryptographic randomness (ThreadLocalRandom).\n>  Same timestamp/version/variant structure as v7, but uses a per-thread\n>  monotonic counter and ThreadLocalRandom instead of SecureRandom and a\n>  global AtomicLong.  At ~39 ns, this is faster than JUG 5.2's v7\n>  generator (~50 ns).  Use when cryptographic unguessability of the\n>  random portion is not required.\n\n_(function)_    `v8 [^long msb, ^long lsb]`\n\n> Generate a v8 custom UUID with up to 122 bits of user data.\n\n_(function)_    `squuid []`\n\n>  Generate a SQUUID (sequential, random) unique identifier.  SQUUID's\n>  are a nonstandard variation on v4 (random) UUIDs that have the\n>  desirable property that they increase sequentially over time as well\n>  as encode retrievably the posix time at which they were generated.\n>  Splits and reassembles a v4 UUID to merge current POSIX\n>  time (seconds since 12:00am January 1, 1970 UTC) with the most\n>  significant 32 bits of the UUID\n\n_(function)_    `= [x]`\n\n_(function)_    `= [x y]`\n\n_(function)_    `= [x y & more]`\n\n> Directly compare two or more UUIDs for = relation based on the\n> ordinality semantics defined by [RFC4122:3 RULES FOR LEXICAL\n> EQUIVALENCE].\n\n_(function)_    `> [x]`\n\n_(function)_    `> [x y]`\n\n_(function)_    `> [x y & more]`\n\n> Directly compare two or more UUIDs for > relation based on the\n> ordinality semantics defined by [RFC4122:3 RULES FOR LEXICAL\n> EQUIVALENCE].\n\n_(function)_    `< [x]`\n\n_(function)_    `< [x y]`\n\n_(function)_    `< [x y & more]`\n\n> Directly compare two or more UUIDs for < relation based on the\n> ordinality semantics defined by [RFC4122:3 RULES FOR LEXICAL\n> EQUIVALENCE].\n\n_(function)_    `monotonic-time []`\n\n>  Return a monotonic timestamp (guaranteed always increasing)  based on\n>  the number of 100-nanosecond intervals elapsed since the adoption of the\n>  Gregorian calendar in the West, 12:00am Friday October 15, 1582 UTC.\n\n* * * * * *\n\n#### Protocols\n\n_(protocol)_    `UUIDNameBytes`\n\n>  A mechanism intended for user-level extension that defines the\n>  decoding rules for the local-part representation of arbitrary\n>  Clojure / Java Objects when used for computing namespaced\n>  identifiers.\n>\n> _(member)_    `as-byte-array [self]`\n>\n>>  Extract a byte serialization that represents the 'name' of x,\n>>  typically unique within a given namespace.\n\n\n_(protocol)_    `UUIDable`\n\n>  A UUIDable object directly represents a UUID.  Examples of things which\n>  might be conceptually 'uuidable' include string representation of a\n>  UUID in canonical hex format, or an appropriate URN URI.\n>\n> _(member)_    `as-uuid [self]`\n>\n>>  Coerce the value of `self` to a java.util.UUID.\n>\n> _(member)_    `uuidable? [self]`\n>\n>>  Return 'true' if `self` can be coerced to UUID.\n\n\n_(protocol)_    `UUIDRfc4122`\n\n> Aliases UUIDRfc9526\n\n_(protocol)_    `UUIDRfc9526`\n\n>  A protocol that abstracts an unique identifier as described by\n>  IETF RFC9526 <http://www.ietf.org/rfc/rfc9526.txt>. A UUID\n>  represents a 128-bit value, however there are variant encoding\n>  layouts used to assign and interpret information encoded in\n>  those bits.  This is a protocol for  _variant 2_ (*Leach-Salz*)\n>  UUID's.\n>\n> _(member)_    `null? [self]`\n>\n>>  Return `true` only if `self` has all 128 bits set ot zero and is\n>>  therefore equal to the null UUID, `00000000-0000-0000-0000-000000000000`.\n>\n> _(member)_    `uuid? [self]`\n>\n>>  Return `true` if the class of `self` implements an RFC9526 unique identifier.\n>\n> _(member)_    `uuid= [self other]`\n>\n>>  Directly compare two UUID's for `=` relation based on the equality\n>>  semantics defined by [RFC4122:3 \"RULES FOR LEXICAL EQUIVALENCE\"].\n>\n> _(member)_    `uuid< [self other]`\n>\n>>  Directly compare two UUID's for `<` relation based on the ordinality\n>>  semantics defined by [RFC4122:3 \"RULES FOR LEXICAL EQUIVALENCE\"].\n>\n> _(member)_    `uuid> [self other]`\n>\n>>  Directly compare two UUID's for `>` relation based on the ordinality\n>>  semantics defined by [RFC4122:3 \"RULES FOR LEXICAL EQUIVALENCE\"].\n>\n> _(member)_    `get-word-high [self]`\n>\n>>  Return the most significant 64 bits of the 128 bit value of UUID `self`.\n>\n> _(member)_    `get-word-low [self]`\n>\n>>  Return the least significant 64 bits of the 128 bit value of UUID `self`.\n>\n> _(member)_    `get-variant [self]`\n>\n>>  Return the _variant_ number associated with this UUID.  The variant field\n>>  contains a value which identifies the layout of the UUID.  The bit-layout\n>>  implemented by this protocol supports UUID's with a variant value of 0x2,\n>>  which indicates Leach-Salz layout.  Defined UUID variant values are:\n>>\n>>     0x0   Null\n>>     0x2   Leach-Salz\n>>     0x6   Microsoft\n>>     0x7   Max\n>>\n>>  In the canonical representation, `xxxxxxxx-xxxx-xxxx-Nxxx-xxxxxxxxxxxx`,\n>>  the most significant bits of N indicate the variant (depending on the\n>>  variant one, two, or three bits are used). The variant covered by RFC4122\n>>  is indicated by the two most significant bits of `N` being `1 0` (i.e., the\n>>  hexadecimal `N` will always be `8`, `9`, `A`, or `B`).\n>\n> _(member)_    `get-version [self]`\n>\n>>  Return the _version_ number associated with this UUID.  The version\n>>  field contains a value which describes the nature of the UUID.  There\n>>  are five versions of Leach-Salz UUID, plus the null and max UUIDs:\n>>\n>>     0x0   Null\n>>     0x1   Time based\n>>     0x2   DCE security with POSIX UID\n>>     0x3   Namespaced, deterministic (MD5 Digest)\n>>     0x4   Cryptographic random\n>>     0x5   Namespaced, deterministic (SHA1 Digest)\n>>     0x6   Time based, lexically ordered\n>>     0x7   POSIX Time based, lexically ordered, cryptographically secure\n>>     0x8   User Customizable\n>>     0xF   Max\n>>\n>>  In the canonical representation, xxxxxxxx-xxxx-Mxxx-xxxx-xxxxxxxxxxxx,\n>>  the four bits of M indicate the UUID version (i.e., the hexadecimal M\n>>  will be either 1, 2, 3, 4, 5, 6, 7, or 8).\")\n>\n> _(member)_    `get-timestamp [self]`\n>\n>>  Return the time of UUID creation.  For Gregorian time-based (v1,\n>>  v6) UUID's, this is 60 bit unsigned value that represents a\n>>  temporally unique timestamp associated with this UUID.  The result\n>>  encodes the number of 100 nanosecond intervals since the adoption of\n>>  the Gregorian calendar.  For v7 UUID's this encodes the more common\n>>  unix time in milliseconds since midnight, January 1, 1970 UTC.  For\n>>  non-time-based (v3, v4, v5, v8, squuid) UUID's, always returns\n>>  `nil`.\n>\n> _(member)_    `get-instant [self]`\n>\n>>  For time-based (v1, v6, v7) UUID's, return a `java.util.Date` object\n>>  that represents the system time at which this UUID was\n>>  generated. NOTE: the returned value may not necessarily be\n>>  temporally unique. For non-time-based (v3, v4, v5, squuid) UUID's,\n>>  always returns `nil`.\n>\n> _(member)_    `get-unix-time [self]`\n>\n>>  For time-based (v1, v6, v7) UUIDs return the timestamp portion in\n>>  approximately milliseconds since the Unix epoch 1970-01-01T00:00:00.000Z.\n>>  For non-time-based (v3, v4, v5, v8, squuid) UUID's, always returns\n>`nil`.\n>\n> _(member)_    `get-time-low [self]`\n>\n>>  Return the 32 bit unsigned value that represents the _time-low_ field\n>>  of the _timestamp_ associated with this UUID.\n>\n> _(member)_    `get-time-mid [self]`\n>\n>>  Return the 16 bit unsigned value that represents the _time-mid_ field\n>>  of the _timestamp_ associated with this UUID.\n>\n> _(member)_    `get-time-high [self]`\n>\n>>  Return the 16 bit unsigned value that represents the _time-high_ field\n>>  of the _timestamp_ multiplexed with the _version_ of this UUID.\n>\n> _(member)_    `get-clk-seq [self]`\n>\n>>  Return the _clk-seq_ number associated with this UUID. For\n>>  time-based (v1, v6) UUID's the _clock-sequence_ value is a somewhat\n>>  counter-intuitively named seed-value that is used to reduce the\n>>  potential that duplicate UUID's might be generated under unusual\n>>  situations, such as if the system hardware clock is set backward in\n>>  time or if, despite all efforts otherwise, a duplicate `+node-id+`\n>>  happens to be generated. This value is initialized to a random\n>>  16-bit number once per lifetime of the system.  For non-time-based\n>>  (v3, v4, v5, squuid) UUID's, always returns `nil`.\n>\n> _(member)_    `get-clk-high [self]`\n>\n>>  Return the 8 bit unsigned value that represents the most significant\n>>  byte of the _clk-seq_ multiplexed with the _variant_ of this UUID.\n>\n> _(member)_    `get-clk-low [self]`\n>\n>>  Return the 8 bit unsigned value that represents the least significant\n>>  byte of the _clk-seq_ associated with this UUID.\n>\n> _(member)_    `get-node-id [self]`\n>\n>>  Return the 48 bit unsigned value that represents the spatially unique\n>>  _node identifier_ associated with this UUID.\n>\n> _(member)_    `hash-code [self]`\n>\n>>  Return a suitable 64-bit hash value for `self`.  Extend for\n>>  specialized hash computation.\n>\n> _(member)_    `to-byte-array [self]`\n>\n>>  Return an array of 16 bytes that represents `self` as a decomposed\n>>  octet serialization encoded in most-significant-byte first order.\n>\n> _(member)_    `to-string [self]`\n>\n>>  Return a String object that represents `self` in the canonical\n>>  36 character hexadecimal string format:\n>>\n>>     \"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"\n>\n> _(member)_    `to-hex-string [self]`\n>\n>>  Return a String object that represents `self` as the 32 hexadecimal\n>>  characters directly encodong the UUID's 128 bit value:\n>>\n>>     \"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n>\n> _(member)_    `to-urn-string [self]`\n>\n>>  Return a String object that represents `uuid` as a the string\n>>  serialization of the URN URI based on the canonical 36 character\n>>  hex-string representation:\n>>\n>>     \"urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"\n>\n> _(member)_    `to-uri [self]`\n>\n>>  Return the unique URN URI associated with this UUID.\n\n\n### References\n\n* [IETF RFC-9562](http://www.ietf.org/rfc/rfc9562.txt) _Universally Unique IDentifiers (UUIDs)_\n\n* [IETF RFC-4122](http://www.ietf.org/rfc/rfc4122.txt) _A Universally Unique IDentifier (UUID) URN Namespace_\n\n* [Wikipedia/_Universally unique identifier_](http://en.wikipedia.org/wiki/Universally_unique_identifier)\n\n* [CL-UUID](http://www.dardoria.net/software/uuid.html) reference implementation\n\n* [UNICLY](https://github.com/mon-key/unicly) reference implementation\n\n* [java.util.UUID](http://docs.oracle.com/javase/6/docs/api/java/util/UUID.html) JavaDoc\n\n* [Java and Unsigned Primitive Datatypes](http://www.darksleep.com/player/JavaAndUnsignedTypes.html)\n\n* [The web of names, hashes, and UUIDs](http://joearms.github.io/2015/03/12/The_web_of_names.html)\n\n* [Coding Katas Clojure -- Bloom Filters](http://blog.find-method.de/index.php?/archives/200-Coding-katas-Clojure-Bloom-filters.html)\n\n\n### Special Thanks\n\n![YourKit](https://www.yourkit.com/images/yklogo.png)\n\nYourKit supports open source projects with its full-featured Java Profiler.\nYourKit, LLC is the creator of [YourKit Java Profiler](https://www.yourkit.com/java/profiler/index.jsp)\nand [YourKit .NET Profiler](https://www.yourkit.com/.net/profiler/index.jsp),\n    innovative and intelligent tools for profiling Java and .NET\napplications.\n\n\n### License\n\nCopyright © 2024 Dan Lentz\n\nDistributed under the Eclipse Public License version 1.0\n"
  },
  {
    "path": "deps.edn",
    "content": "{:paths [\"src\"]\n :deps  {org.clojure/clojure {:mvn/version \"1.12.0\"}\n         org.clj-commons/primitive-math {:mvn/version \"1.0.1\"}}\n :aliases\n {:test {:extra-paths [\"test\"]}\n  :coverage {:extra-paths [\"test\"]\n             :extra-deps {cloverage/cloverage {:mvn/version \"1.2.4\"}}\n             :main-opts [\"-m\" \"cloverage.coverage\"\n                         \"--src-ns-path\" \"src\"\n                         \"--test-ns-path\" \"test\"]}}}\n"
  },
  {
    "path": "doc/api/clj-uuid.bitmop.html",
    "content": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>clj-uuid.bitmop documentation</title><link rel=\"stylesheet\" type=\"text/css\" href=\"css/default.css\" /><link rel=\"stylesheet\" type=\"text/css\" href=\"css/highlight.css\" /><script type=\"text/javascript\" src=\"js/highlight.min.js\"></script><script type=\"text/javascript\" src=\"js/jquery.min.js\"></script><script type=\"text/javascript\" src=\"js/page_effects.js\"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id=\"header\"><h2>Generated by <a href=\"https://github.com/weavejester/codox\">Codox</a></h2><h1><a href=\"index.html\"><span class=\"project-title\"><span class=\"project-name\">clj-uuid</span> <span class=\"project-version\">0.2.5-SNAPSHOT</span></span></a></h1></div><div class=\"sidebar primary\"><h3 class=\"no-link\"><span class=\"inner\">Project</span></h3><ul class=\"index-link\"><li class=\"depth-1 \"><a href=\"index.html\"><div class=\"inner\">Index</div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Namespaces</span></h3><ul><li class=\"depth-1\"><a href=\"clj-uuid.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>clj-uuid</span></div></a></li><li class=\"depth-2 branch current\"><a href=\"clj-uuid.bitmop.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>bitmop</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.clock.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>clock</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.constants.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>constants</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.core.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>core</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.node.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>node</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.random.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>random</span></div></a></li><li class=\"depth-2\"><a href=\"clj-uuid.util.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>util</span></div></a></li></ul></div><div class=\"sidebar secondary\"><h3><a href=\"#top\"><span class=\"inner\">Public Vars</span></a></h3><ul><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-assemble-bytes\"><div class=\"inner\"><span>assemble-bytes</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-bit-count\"><div class=\"inner\"><span>bit-count</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-buf-.3Ebytes\"><div class=\"inner\"><span>buf-&gt;bytes</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-buf-.3Euuid\"><div class=\"inner\"><span>buf-&gt;uuid</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-buf-compare\"><div class=\"inner\"><span>buf-compare</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-buf-hex\"><div class=\"inner\"><span>buf-hex</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-buf-str\"><div class=\"inner\"><span>buf-str</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-buffer\"><div class=\"inner\"><span>buffer</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-buffer-from-bytes\"><div class=\"inner\"><span>buffer-from-bytes</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-bytes-.3Elong\"><div class=\"inner\"><span>bytes-&gt;long</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-dpb\"><div class=\"inner\"><span>dpb</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-dpb-buf\"><div class=\"inner\"><span>dpb-buf</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-duplicate\"><div class=\"inner\"><span>duplicate</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-expt2\"><div class=\"inner\"><span>expt2</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-get-byte\"><div class=\"inner\"><span>get-byte</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-get-int\"><div class=\"inner\"><span>get-int</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-get-long\"><div class=\"inner\"><span>get-long</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-get-lsb\"><div class=\"inner\"><span>get-lsb</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-get-msb\"><div class=\"inner\"><span>get-msb</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-get-short\"><div class=\"inner\"><span>get-short</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-hex\"><div class=\"inner\"><span>hex</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-hex-.3Ebuf\"><div class=\"inner\"><span>hex-&gt;buf</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-ldb\"><div class=\"inner\"><span>ldb</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-ldb-buf\"><div class=\"inner\"><span>ldb-buf</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-long-.3Ebytes\"><div class=\"inner\"><span>long-&gt;bytes</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-mask\"><div class=\"inner\"><span>mask</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-mask-offset\"><div class=\"inner\"><span>mask-offset</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-mask-width\"><div class=\"inner\"><span>mask-width</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-octet-hex\"><div class=\"inner\"><span>octet-hex</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-pphex\"><div class=\"inner\"><span>pphex</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-put-byte\"><div class=\"inner\"><span>put-byte</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-put-int\"><div class=\"inner\"><span>put-int</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-put-long\"><div class=\"inner\"><span>put-long</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-put-short\"><div class=\"inner\"><span>put-short</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-sb16\"><div class=\"inner\"><span>sb16</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-sb32\"><div class=\"inner\"><span>sb32</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-sb64\"><div class=\"inner\"><span>sb64</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-sb8\"><div class=\"inner\"><span>sb8</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-set-lsb\"><div class=\"inner\"><span>set-lsb</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-set-msb\"><div class=\"inner\"><span>set-msb</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-ub16\"><div class=\"inner\"><span>ub16</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-ub24\"><div class=\"inner\"><span>ub24</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-ub32\"><div class=\"inner\"><span>ub32</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-ub4\"><div class=\"inner\"><span>ub4</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-ub48\"><div class=\"inner\"><span>ub48</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-ub56\"><div class=\"inner\"><span>ub56</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-ub8\"><div class=\"inner\"><span>ub8</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.bitmop.html#var-uuid-.3Ebuf\"><div class=\"inner\"><span>uuid-&gt;buf</span></div></a></li></ul></div><div class=\"namespace-docs\" id=\"content\"><h1 class=\"anchor\" id=\"top\">clj-uuid.bitmop</h1><div class=\"doc\"><pre class=\"plaintext\">Unsigned Long and ByteBuffer-based bitwise operation primitives for\nUUID manipulation.\n\nProvides the same mask/ldb/dpb fundamentals as in the past, plus a\n16-byte ByteBuffer abstraction for direct UUID byte manipulation.\n\nThe ByteBuffer approach has two key advantages:\n\n1. Performance: ByteBuffer provides direct typed access at byte offsets\n   via single native operations (getLong, getInt, etc.) rather than\n   manual shift/mask loops.\n2. Portability: The buffer abstraction maps naturally to JavaScript's\n   DataView/ArrayBuffer, enabling a future cljc implementation.</pre></div><div class=\"public anchor\" id=\"var-assemble-bytes\"><h3>assemble-bytes</h3><div class=\"usage\"><code>(assemble-bytes v)</code></div><div class=\"doc\"><pre class=\"plaintext\">Assemble a sequence of 8 bytes (big-endian) into a long.\n</pre></div></div><div class=\"public anchor\" id=\"var-bit-count\"><h3>bit-count</h3><div class=\"usage\"><code>(bit-count x)</code></div><div class=\"doc\"><pre class=\"plaintext\">Count the number of set bits in `x`.\n</pre></div></div><div class=\"public anchor\" id=\"var-buf-.3Ebytes\"><h3>buf-&gt;bytes</h3><div class=\"usage\"><code>(buf-&gt;bytes buf)</code></div><div class=\"doc\"><pre class=\"plaintext\">Extract the contents of a 16-byte UUID buffer as a byte array.\n</pre></div></div><div class=\"public anchor\" id=\"var-buf-.3Euuid\"><h3>buf-&gt;uuid</h3><div class=\"usage\"><code>(buf-&gt;uuid buf)</code></div><div class=\"doc\"><pre class=\"plaintext\">Convert a 16-byte UUID buffer to a java.util.UUID.\n</pre></div></div><div class=\"public anchor\" id=\"var-buf-compare\"><h3>buf-compare</h3><div class=\"usage\"><code>(buf-compare a b)</code></div><div class=\"doc\"><pre class=\"plaintext\">Lexicographic unsigned comparison of two 16-byte UUID buffers.\nReturns negative if a &lt; b, zero if equal, positive if a &gt; b.\nComparison is unsigned (treats bytes as 0-255) which matches UUID\ncanonical string ordering.</pre></div></div><div class=\"public anchor\" id=\"var-buf-hex\"><h3>buf-hex</h3><div class=\"usage\"><code>(buf-hex buf)</code></div><div class=\"doc\"><pre class=\"plaintext\">Convert a 16-byte UUID buffer to a 32-character hex string.\n</pre></div></div><div class=\"public anchor\" id=\"var-buf-str\"><h3>buf-str</h3><div class=\"usage\"><code>(buf-str buf)</code></div><div class=\"doc\"><pre class=\"plaintext\">Convert a 16-byte UUID buffer to the canonical 36-character UUID string:\n  xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n\nByte ranges correspond to UUID fields:\n  bytes 0-3:   time-low\n  bytes 4-5:   time-mid\n  bytes 6-7:   time-high-and-version\n  bytes 8-9:   clock-seq\n  bytes 10-15: node</pre></div></div><div class=\"public anchor\" id=\"var-buffer\"><h3>buffer</h3><div class=\"usage\"><code>(buffer)</code><code>(buffer msb lsb)</code></div><div class=\"doc\"><pre class=\"plaintext\">Create a 16-byte big-endian ByteBuffer.\n\n0-arity:  zeroed buffer\n2-arity:  from msb and lsb longs\nThe buffer uses absolute (position-independent) get/put operations.</pre></div></div><div class=\"public anchor\" id=\"var-buffer-from-bytes\"><h3>buffer-from-bytes</h3><div class=\"usage\"><code>(buffer-from-bytes arr)</code></div><div class=\"doc\"><pre class=\"plaintext\">Create a 16-byte ByteBuffer from a byte array (at least 16 bytes).\n</pre></div></div><div class=\"public anchor\" id=\"var-bytes-.3Elong\"><h3>bytes-&gt;long</h3><div class=\"usage\"><code>(bytes-&gt;long arr i)</code></div><div class=\"doc\"><pre class=\"plaintext\">Read 8 bytes from `arr` starting at offset `i`, returning a long.\n</pre></div></div><div class=\"public anchor\" id=\"var-dpb\"><h3>dpb</h3><div class=\"usage\"><code>(dpb bitmask num value)</code></div><div class=\"doc\"><pre class=\"plaintext\">Deposit Byte -- insert `value` into the bit field defined by `bitmask`\nwithin `num`.</pre></div></div><div class=\"public anchor\" id=\"var-dpb-buf\"><h3>dpb-buf</h3><div class=\"usage\"><code>(dpb-buf buf word-offset bitmask value)</code></div><div class=\"doc\"><pre class=\"plaintext\">Deposit bit field: insert `value` into the bits defined by `bitmask`\nwithin the 64-bit word at `word-offset` in the buffer.  Mutates and\nreturns the buffer.</pre></div></div><div class=\"public anchor\" id=\"var-duplicate\"><h3>duplicate</h3><div class=\"usage\"><code>(duplicate buf)</code></div><div class=\"doc\"><pre class=\"plaintext\">Create an independent copy of a UUID buffer.\n</pre></div></div><div class=\"public anchor\" id=\"var-expt2\"><h3>expt2</h3><div class=\"usage\"><code>(expt2 pow)</code></div><div class=\"doc\"><pre class=\"plaintext\">Compute 2^pow using bit-set.\n</pre></div></div><div class=\"public anchor\" id=\"var-get-byte\"><h3>get-byte</h3><div class=\"usage\"><code>(get-byte buf offset)</code></div><div class=\"doc\"><pre class=\"plaintext\">Read an unsigned byte (0-255) at byte offset from buffer.\n</pre></div></div><div class=\"public anchor\" id=\"var-get-int\"><h3>get-int</h3><div class=\"usage\"><code>(get-int buf offset)</code></div><div class=\"doc\"><pre class=\"plaintext\">Read an unsigned 32-bit value at byte offset from buffer.\n</pre></div></div><div class=\"public anchor\" id=\"var-get-long\"><h3>get-long</h3><div class=\"usage\"><code>(get-long buf offset)</code></div><div class=\"doc\"><pre class=\"plaintext\">Read a 64-bit long at byte offset from buffer.\n</pre></div></div><div class=\"public anchor\" id=\"var-get-lsb\"><h3>get-lsb</h3><div class=\"usage\"><code>(get-lsb buf)</code></div><div class=\"doc\"><pre class=\"plaintext\">Read the least significant 64 bits (bytes 8-15) of a UUID buffer.\n</pre></div></div><div class=\"public anchor\" id=\"var-get-msb\"><h3>get-msb</h3><div class=\"usage\"><code>(get-msb buf)</code></div><div class=\"doc\"><pre class=\"plaintext\">Read the most significant 64 bits (bytes 0-7) of a UUID buffer.\n</pre></div></div><div class=\"public anchor\" id=\"var-get-short\"><h3>get-short</h3><div class=\"usage\"><code>(get-short buf offset)</code></div><div class=\"doc\"><pre class=\"plaintext\">Read an unsigned 16-bit value at byte offset from buffer.\n</pre></div></div><div class=\"public anchor\" id=\"var-hex\"><h3>hex</h3><div class=\"usage\"><code>(hex thing)</code></div><div class=\"doc\"><pre class=\"plaintext\">Convert a long or byte sequence to a hex string.\nFor a long, produces a 16-character zero-padded hex string.</pre></div></div><div class=\"public anchor\" id=\"var-hex-.3Ebuf\"><h3>hex-&gt;buf</h3><div class=\"usage\"><code>(hex-&gt;buf s)</code></div><div class=\"doc\"><pre class=\"plaintext\">Parse a 32-character hex string into a 16-byte UUID buffer.\n</pre></div></div><div class=\"public anchor\" id=\"var-ldb\"><h3>ldb</h3><div class=\"usage\"><code>(ldb bitmask num)</code></div><div class=\"doc\"><pre class=\"plaintext\">Load Byte -- extract the bit field defined by `bitmask` from `num`.\n</pre></div></div><div class=\"public anchor\" id=\"var-ldb-buf\"><h3>ldb-buf</h3><div class=\"usage\"><code>(ldb-buf buf word-offset bitmask)</code></div><div class=\"doc\"><pre class=\"plaintext\">Load bit field: extract bits defined by `bitmask` from the 64-bit word\nat `word-offset` in the buffer.</pre></div></div><div class=\"public anchor\" id=\"var-long-.3Ebytes\"><h3>long-&gt;bytes</h3><div class=\"usage\"><code>(long-&gt;bytes x)</code><code>(long-&gt;bytes x arr i)</code></div><div class=\"doc\"><pre class=\"plaintext\">Write `x` as 8 big-endian bytes.  With one argument returns a new byte\narray.  With three arguments writes into `arr` at offset `i`.</pre></div></div><div class=\"public anchor\" id=\"var-mask\"><h3>mask</h3><div class=\"usage\"><code>(mask width offset)</code></div><div class=\"doc\"><pre class=\"plaintext\">Create a bitmask of `width` bits starting at bit `offset`.\n</pre></div></div><div class=\"public anchor\" id=\"var-mask-offset\"><h3>mask-offset</h3><div class=\"usage\"><code>(mask-offset m)</code></div><div class=\"doc\"><pre class=\"plaintext\">Return the bit offset (position of least significant set bit) of a mask.\n</pre></div></div><div class=\"public anchor\" id=\"var-mask-width\"><h3>mask-width</h3><div class=\"usage\"><code>(mask-width m)</code></div><div class=\"doc\"><pre class=\"plaintext\">Return the number of set bits in a contiguous bitmask.\n</pre></div></div><div class=\"public anchor\" id=\"var-octet-hex\"><h3>octet-hex</h3><div class=\"usage\"><code>(octet-hex num)</code></div><div class=\"doc\"><pre class=\"plaintext\">Convert a single byte value to a two-character uppercase hex string.\n</pre></div></div><div class=\"public anchor\" id=\"var-pphex\"><h3>pphex</h3><div class=\"usage\"><code>(pphex x)</code></div><div class=\"doc\"><pre class=\"plaintext\">Pretty-print a long value in both hexadecimal and binary.\n</pre></div></div><div class=\"public anchor\" id=\"var-put-byte\"><h3>put-byte</h3><div class=\"usage\"><code>(put-byte buf offset val)</code></div><div class=\"doc\"><pre class=\"plaintext\">Write a byte value at byte offset in buffer.  Returns the buffer.\n</pre></div></div><div class=\"public anchor\" id=\"var-put-int\"><h3>put-int</h3><div class=\"usage\"><code>(put-int buf offset val)</code></div><div class=\"doc\"><pre class=\"plaintext\">Write a 32-bit value at byte offset in buffer.  Returns the buffer.\n</pre></div></div><div class=\"public anchor\" id=\"var-put-long\"><h3>put-long</h3><div class=\"usage\"><code>(put-long buf offset val)</code></div><div class=\"doc\"><pre class=\"plaintext\">Write a 64-bit long at byte offset in buffer.  Returns the buffer.\n</pre></div></div><div class=\"public anchor\" id=\"var-put-short\"><h3>put-short</h3><div class=\"usage\"><code>(put-short buf offset val)</code></div><div class=\"doc\"><pre class=\"plaintext\">Write a 16-bit value at byte offset in buffer.  Returns the buffer.\n</pre></div></div><div class=\"public anchor\" id=\"var-sb16\"><h3>sb16</h3><div class=\"usage\"><code>(sb16 num)</code></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-sb32\"><h3>sb32</h3><div class=\"usage\"><code>(sb32 num)</code></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-sb64\"><h3>sb64</h3><div class=\"usage\"><code>(sb64 num)</code></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-sb8\"><h3>sb8</h3><div class=\"usage\"><code>(sb8 num)</code></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-set-lsb\"><h3>set-lsb</h3><div class=\"usage\"><code>(set-lsb buf val)</code></div><div class=\"doc\"><pre class=\"plaintext\">Set the least significant 64 bits (bytes 8-15) of a UUID buffer.\nReturns the buffer.</pre></div></div><div class=\"public anchor\" id=\"var-set-msb\"><h3>set-msb</h3><div class=\"usage\"><code>(set-msb buf val)</code></div><div class=\"doc\"><pre class=\"plaintext\">Set the most significant 64 bits (bytes 0-7) of a UUID buffer.\nReturns the buffer.</pre></div></div><div class=\"public anchor\" id=\"var-ub16\"><h3>ub16</h3><div class=\"usage\"><code>(ub16 num)</code></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-ub24\"><h3>ub24</h3><div class=\"usage\"><code>(ub24 num)</code></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-ub32\"><h3>ub32</h3><div class=\"usage\"><code>(ub32 num)</code></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-ub4\"><h3>ub4</h3><div class=\"usage\"><code>(ub4 num)</code></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-ub48\"><h3>ub48</h3><div class=\"usage\"><code>(ub48 num)</code></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-ub56\"><h3>ub56</h3><div class=\"usage\"><code>(ub56 num)</code></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-ub8\"><h3>ub8</h3><div class=\"usage\"><code>(ub8 num)</code></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-uuid-.3Ebuf\"><h3>uuid-&gt;buf</h3><div class=\"usage\"><code>(uuid-&gt;buf uuid)</code></div><div class=\"doc\"><pre class=\"plaintext\">Convert a java.util.UUID to a 16-byte ByteBuffer.\n</pre></div></div></div></body></html>"
  },
  {
    "path": "doc/api/clj-uuid.clock.html",
    "content": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>clj-uuid.clock documentation</title><link rel=\"stylesheet\" type=\"text/css\" href=\"css/default.css\" /><link rel=\"stylesheet\" type=\"text/css\" href=\"css/highlight.css\" /><script type=\"text/javascript\" src=\"js/highlight.min.js\"></script><script type=\"text/javascript\" src=\"js/jquery.min.js\"></script><script type=\"text/javascript\" src=\"js/page_effects.js\"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id=\"header\"><h2>Generated by <a href=\"https://github.com/weavejester/codox\">Codox</a></h2><h1><a href=\"index.html\"><span class=\"project-title\"><span class=\"project-name\">clj-uuid</span> <span class=\"project-version\">0.2.5-SNAPSHOT</span></span></a></h1></div><div class=\"sidebar primary\"><h3 class=\"no-link\"><span class=\"inner\">Project</span></h3><ul class=\"index-link\"><li class=\"depth-1 \"><a href=\"index.html\"><div class=\"inner\">Index</div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Namespaces</span></h3><ul><li class=\"depth-1\"><a href=\"clj-uuid.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>clj-uuid</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.bitmop.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>bitmop</span></div></a></li><li class=\"depth-2 branch current\"><a href=\"clj-uuid.clock.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>clock</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.constants.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>constants</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.core.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>core</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.node.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>node</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.random.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>random</span></div></a></li><li class=\"depth-2\"><a href=\"clj-uuid.util.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>util</span></div></a></li></ul></div><div class=\"sidebar secondary\"><h3><a href=\"#top\"><span class=\"inner\">Public Vars</span></a></h3><ul><li class=\"depth-1\"><a href=\"clj-uuid.clock.html#var-.2Brandom-counter-resolution.2B\"><div class=\"inner\"><span>+random-counter-resolution+</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.clock.html#var-.2Bsubcounter-resolution.2B\"><div class=\"inner\"><span>+subcounter-resolution+</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.clock.html#var--gregorian-packed-\"><div class=\"inner\"><span>-gregorian-packed-</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.clock.html#var-monotonic-time\"><div class=\"inner\"><span>monotonic-time</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.clock.html#var-monotonic-unix-time-and-random-counter\"><div class=\"inner\"><span>monotonic-unix-time-and-random-counter</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.clock.html#var-posix-time\"><div class=\"inner\"><span>posix-time</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.clock.html#var-universal-time\"><div class=\"inner\"><span>universal-time</span></div></a></li></ul></div><div class=\"namespace-docs\" id=\"content\"><h1 class=\"anchor\" id=\"top\">clj-uuid.clock</h1><div class=\"doc\"><pre class=\"plaintext\">Lock-Free, Thread-safe Monotonic Clocks\n</pre></div><div class=\"public anchor\" id=\"var-.2Brandom-counter-resolution.2B\"><h3>+random-counter-resolution+</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-.2Bsubcounter-resolution.2B\"><h3>+subcounter-resolution+</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var--gregorian-packed-\"><h3>-gregorian-packed-</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-monotonic-time\"><h3>monotonic-time</h3><div class=\"usage\"><code>(monotonic-time)</code></div><div class=\"doc\"><pre class=\"plaintext\">Generate a guaranteed monotonically increasing timestamp based on\nGregorian time and a stateful subcounter</pre></div></div><div class=\"public anchor\" id=\"var-monotonic-unix-time-and-random-counter\"><h3>monotonic-unix-time-and-random-counter</h3><div class=\"usage\"><code>(monotonic-unix-time-and-random-counter)</code></div><div class=\"doc\"><pre class=\"plaintext\">Generate guaranteed monotonically increasing number pairs based on\nPOSIX time and a randomly seeded subcounter</pre></div></div><div class=\"public anchor\" id=\"var-posix-time\"><h3>posix-time</h3><div class=\"usage\"><code>(posix-time)</code><code>(posix-time gregorian)</code></div><div class=\"doc\"><pre class=\"plaintext\">Generate the (Unix compatible) POSIX time -- the number of seconds\nthat have elapsed since 00:00 January 1, 1970 UTC</pre></div></div><div class=\"public anchor\" id=\"var-universal-time\"><h3>universal-time</h3><div class=\"usage\"><code>(universal-time)</code><code>(universal-time gregorian)</code></div><div class=\"doc\"><pre class=\"plaintext\">Generate the (Common-Lisp compatible) universal-time -- the number of\nseconds that have elapsed since 00:00 January 1, 1900 GMT</pre></div></div></div></body></html>"
  },
  {
    "path": "doc/api/clj-uuid.constants.html",
    "content": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>clj-uuid.constants documentation</title><link rel=\"stylesheet\" type=\"text/css\" href=\"css/default.css\" /><link rel=\"stylesheet\" type=\"text/css\" href=\"css/highlight.css\" /><script type=\"text/javascript\" src=\"js/highlight.min.js\"></script><script type=\"text/javascript\" src=\"js/jquery.min.js\"></script><script type=\"text/javascript\" src=\"js/page_effects.js\"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id=\"header\"><h2>Generated by <a href=\"https://github.com/weavejester/codox\">Codox</a></h2><h1><a href=\"index.html\"><span class=\"project-title\"><span class=\"project-name\">clj-uuid</span> <span class=\"project-version\">0.2.5-SNAPSHOT</span></span></a></h1></div><div class=\"sidebar primary\"><h3 class=\"no-link\"><span class=\"inner\">Project</span></h3><ul class=\"index-link\"><li class=\"depth-1 \"><a href=\"index.html\"><div class=\"inner\">Index</div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Namespaces</span></h3><ul><li class=\"depth-1\"><a href=\"clj-uuid.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>clj-uuid</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.bitmop.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>bitmop</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.clock.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>clock</span></div></a></li><li class=\"depth-2 branch current\"><a href=\"clj-uuid.constants.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>constants</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.core.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>core</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.node.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>node</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.random.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>random</span></div></a></li><li class=\"depth-2\"><a href=\"clj-uuid.util.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>util</span></div></a></li></ul></div><div class=\"sidebar secondary\"><h3><a href=\"#top\"><span class=\"inner\">Public Vars</span></a></h3><ul><li class=\"depth-1\"><a href=\"clj-uuid.constants.html#var-.2Bhex-chars.2B\"><div class=\"inner\"><span>+hex-chars+</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.constants.html#var-.2Bmd5.2B\"><div class=\"inner\"><span>+md5+</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.constants.html#var-.2Bsha1.2B\"><div class=\"inner\"><span>+sha1+</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.constants.html#var-.2Bub1-mask.2B\"><div class=\"inner\"><span>+ub1-mask+</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.constants.html#var-.2Bub12-mask.2B\"><div class=\"inner\"><span>+ub12-mask+</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.constants.html#var-.2Bub16-mask.2B\"><div class=\"inner\"><span>+ub16-mask+</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.constants.html#var-.2Bub24-mask.2B\"><div class=\"inner\"><span>+ub24-mask+</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.constants.html#var-.2Bub32-mask.2B\"><div class=\"inner\"><span>+ub32-mask+</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.constants.html#var-.2Bub4-mask.2B\"><div class=\"inner\"><span>+ub4-mask+</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.constants.html#var-.2Bub40-mask.2B\"><div class=\"inner\"><span>+ub40-mask+</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.constants.html#var-.2Bub48-mask.2B\"><div class=\"inner\"><span>+ub48-mask+</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.constants.html#var-.2Bub56-mask.2B\"><div class=\"inner\"><span>+ub56-mask+</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.constants.html#var-.2Bub60-mask.2B\"><div class=\"inner\"><span>+ub60-mask+</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.constants.html#var-.2Bub63-mask.2B\"><div class=\"inner\"><span>+ub63-mask+</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.constants.html#var-.2Bub8-mask.2B\"><div class=\"inner\"><span>+ub8-mask+</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.constants.html#var-hex-regex\"><div class=\"inner\"><span>hex-regex</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.constants.html#var-urn-regex\"><div class=\"inner\"><span>urn-regex</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.constants.html#var-uuid-regex\"><div class=\"inner\"><span>uuid-regex</span></div></a></li></ul></div><div class=\"namespace-docs\" id=\"content\"><h1 class=\"anchor\" id=\"top\">clj-uuid.constants</h1><div class=\"doc\"><pre class=\"plaintext\"></pre></div><div class=\"public anchor\" id=\"var-.2Bhex-chars.2B\"><h3>+hex-chars+</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-.2Bmd5.2B\"><h3>+md5+</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-.2Bsha1.2B\"><h3>+sha1+</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-.2Bub1-mask.2B\"><h3>+ub1-mask+</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-.2Bub12-mask.2B\"><h3>+ub12-mask+</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-.2Bub16-mask.2B\"><h3>+ub16-mask+</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-.2Bub24-mask.2B\"><h3>+ub24-mask+</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-.2Bub32-mask.2B\"><h3>+ub32-mask+</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-.2Bub4-mask.2B\"><h3>+ub4-mask+</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-.2Bub40-mask.2B\"><h3>+ub40-mask+</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-.2Bub48-mask.2B\"><h3>+ub48-mask+</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-.2Bub56-mask.2B\"><h3>+ub56-mask+</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-.2Bub60-mask.2B\"><h3>+ub60-mask+</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-.2Bub63-mask.2B\"><h3>+ub63-mask+</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-.2Bub8-mask.2B\"><h3>+ub8-mask+</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-hex-regex\"><h3>hex-regex</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-urn-regex\"><h3>urn-regex</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-uuid-regex\"><h3>uuid-regex</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div></div></body></html>"
  },
  {
    "path": "doc/api/clj-uuid.core.html",
    "content": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>clj-uuid.core documentation</title><link rel=\"stylesheet\" type=\"text/css\" href=\"css/default.css\" /><link rel=\"stylesheet\" type=\"text/css\" href=\"css/highlight.css\" /><script type=\"text/javascript\" src=\"js/highlight.min.js\"></script><script type=\"text/javascript\" src=\"js/jquery.min.js\"></script><script type=\"text/javascript\" src=\"js/page_effects.js\"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id=\"header\"><h2>Generated by <a href=\"https://github.com/weavejester/codox\">Codox</a></h2><h1><a href=\"index.html\"><span class=\"project-title\"><span class=\"project-name\">clj-uuid</span> <span class=\"project-version\">0.2.5-SNAPSHOT</span></span></a></h1></div><div class=\"sidebar primary\"><h3 class=\"no-link\"><span class=\"inner\">Project</span></h3><ul class=\"index-link\"><li class=\"depth-1 \"><a href=\"index.html\"><div class=\"inner\">Index</div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Namespaces</span></h3><ul><li class=\"depth-1\"><a href=\"clj-uuid.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>clj-uuid</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.bitmop.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>bitmop</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.clock.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>clock</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.constants.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>constants</span></div></a></li><li class=\"depth-2 branch current\"><a href=\"clj-uuid.core.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>core</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.node.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>node</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.random.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>random</span></div></a></li><li class=\"depth-2\"><a href=\"clj-uuid.util.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>util</span></div></a></li></ul></div><div class=\"sidebar secondary\"><h3><a href=\"#top\"><span class=\"inner\">Public Vars</span></a></h3><ul><li class=\"depth-1\"><a href=\"clj-uuid.core.html#var-.2Bmax.2B\"><div class=\"inner\"><span>+max+</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.core.html#var-.2Bnamespace-dns.2B\"><div class=\"inner\"><span>+namespace-dns+</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.core.html#var-.2Bnamespace-oid.2B\"><div class=\"inner\"><span>+namespace-oid+</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.core.html#var-.2Bnamespace-url.2B\"><div class=\"inner\"><span>+namespace-url+</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.core.html#var-.2Bnamespace-x500.2B\"><div class=\"inner\"><span>+namespace-x500+</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.core.html#var-.2Bnull.2B\"><div class=\"inner\"><span>+null+</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.core.html#var-.3C\"><div class=\"inner\"><span>&lt;</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.core.html#var-.3D\"><div class=\"inner\"><span>=</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.core.html#var-.3E\"><div class=\"inner\"><span>&gt;</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.core.html#var-max\"><div class=\"inner\"><span>max</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.core.html#var-monotonic-time\"><div class=\"inner\"><span>monotonic-time</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.core.html#var-null\"><div class=\"inner\"><span>null</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.core.html#var-squuid\"><div class=\"inner\"><span>squuid</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.core.html#var-uuid-string.3F\"><div class=\"inner\"><span>uuid-string?</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.core.html#var-uuid-urn-string.3F\"><div class=\"inner\"><span>uuid-urn-string?</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.core.html#var-uuid-vec.3F\"><div class=\"inner\"><span>uuid-vec?</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.core.html#var-UUIDable\"><div class=\"inner\"><span>UUIDable</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.core.html#var-as-uuid\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>as-uuid</span></div></a></li><li class=\"depth-2\"><a href=\"clj-uuid.core.html#var-uuidable.3F\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>uuidable?</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.core.html#var-UUIDNameBytes\"><div class=\"inner\"><span>UUIDNameBytes</span></div></a></li><li class=\"depth-2\"><a href=\"clj-uuid.core.html#var-as-byte-array\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>as-byte-array</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.core.html#var-UUIDRfc4122\"><div class=\"inner\"><span>UUIDRfc4122</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.core.html#var-UUIDRfc9562\"><div class=\"inner\"><span>UUIDRfc9562</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.core.html#var-get-clk-high\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>get-clk-high</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.core.html#var-get-clk-low\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>get-clk-low</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.core.html#var-get-clk-seq\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>get-clk-seq</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.core.html#var-get-instant\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>get-instant</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.core.html#var-get-node-id\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>get-node-id</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.core.html#var-get-time-high\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>get-time-high</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.core.html#var-get-time-low\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>get-time-low</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.core.html#var-get-time-mid\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>get-time-mid</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.core.html#var-get-timestamp\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>get-timestamp</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.core.html#var-get-unix-time\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>get-unix-time</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.core.html#var-get-variant\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>get-variant</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.core.html#var-get-version\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>get-version</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.core.html#var-get-word-high\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>get-word-high</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.core.html#var-get-word-low\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>get-word-low</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.core.html#var-hash-code\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>hash-code</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.core.html#var-max.3F\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>max?</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.core.html#var-null.3F\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>null?</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.core.html#var-to-byte-array\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>to-byte-array</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.core.html#var-to-hex-string\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>to-hex-string</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.core.html#var-to-string\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>to-string</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.core.html#var-to-uri\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>to-uri</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.core.html#var-to-urn-string\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>to-urn-string</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.core.html#var-uuid.3C\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>uuid&lt;</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.core.html#var-uuid.3D\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>uuid=</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.core.html#var-uuid.3E\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>uuid&gt;</span></div></a></li><li class=\"depth-2\"><a href=\"clj-uuid.core.html#var-uuid.3F\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>uuid?</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.core.html#var-v0\"><div class=\"inner\"><span>v0</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.core.html#var-v1\"><div class=\"inner\"><span>v1</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.core.html#var-v3\"><div class=\"inner\"><span>v3</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.core.html#var-v4\"><div class=\"inner\"><span>v4</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.core.html#var-v5\"><div class=\"inner\"><span>v5</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.core.html#var-v6\"><div class=\"inner\"><span>v6</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.core.html#var-v7\"><div class=\"inner\"><span>v7</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.core.html#var-v7nc\"><div class=\"inner\"><span>v7nc</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.core.html#var-v8\"><div class=\"inner\"><span>v8</span></div></a></li></ul></div><div class=\"namespace-docs\" id=\"content\"><h1 class=\"anchor\" id=\"top\">clj-uuid.core</h1><div class=\"doc\"><pre class=\"plaintext\"></pre></div><div class=\"public anchor\" id=\"var-.2Bmax.2B\"><h3>+max+</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">The MAX UUID is a special form of sentinel UUID that is specified to have\nall 128 bits set to one.</pre></div></div><div class=\"public anchor\" id=\"var-.2Bnamespace-dns.2B\"><h3>+namespace-dns+</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-.2Bnamespace-oid.2B\"><h3>+namespace-oid+</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-.2Bnamespace-url.2B\"><h3>+namespace-url+</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-.2Bnamespace-x500.2B\"><h3>+namespace-x500+</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-.2Bnull.2B\"><h3>+null+</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">The NULL UUID is a special form of sentinel UUID that is specified to have\nall 128 bits set to zero.</pre></div></div><div class=\"public anchor\" id=\"var-.3C\"><h3>&lt;</h3><div class=\"usage\"><code>(&lt; _)</code><code>(&lt; x y)</code><code>(&lt; x y &amp; more)</code></div><div class=\"doc\"><pre class=\"plaintext\">Directly compare two or more UUIDs for &lt; relation based on the\nordinality semantics defined by [RFC4122:3 RULES FOR LEXICAL\nEQUIVALENCE].</pre></div></div><div class=\"public anchor\" id=\"var-.3D\"><h3>=</h3><div class=\"usage\"><code>(= _)</code><code>(= x y)</code><code>(= x y &amp; more)</code></div><div class=\"doc\"><pre class=\"plaintext\">Directly compare two or more UUIDs for = relation based on the\nequality semantics defined by [RFC4122:3 RULES FOR LEXICAL\nEQUIVALENCE].</pre></div></div><div class=\"public anchor\" id=\"var-.3E\"><h3>&gt;</h3><div class=\"usage\"><code>(&gt; _)</code><code>(&gt; x y)</code><code>(&gt; x y &amp; more)</code></div><div class=\"doc\"><pre class=\"plaintext\">Directly compare two or more UUIDs for &gt; relation based on the\nordinality semantics defined by [RFC4122:3 RULES FOR LEXICAL\nEQUIVALENCE].</pre></div></div><div class=\"public anchor\" id=\"var-max\"><h3>max</h3><div class=\"usage\"><code>(max)</code></div><div class=\"doc\"><pre class=\"plaintext\">Generates the v15 (maximum) UUID, ffffffff-ffff-ffff-ffff-ffffffffffff.\n</pre></div></div><div class=\"public anchor\" id=\"var-monotonic-time\"><h3>monotonic-time</h3><div class=\"usage\"><code>(monotonic-time)</code></div><div class=\"doc\"><pre class=\"plaintext\">Return a monotonic timestamp (guaranteed always increasing) based on\nthe number of 100-nanosecond intervals elapsed since the adoption of\nthe Gregorian calendar in the West, 12:00am Friday October 15, 1582 UTC.</pre></div></div><div class=\"public anchor\" id=\"var-null\"><h3>null</h3><div class=\"usage\"><code>(null)</code></div><div class=\"doc\"><pre class=\"plaintext\">Generates the v0 (null) UUID, 00000000-0000-0000-0000-000000000000.\n</pre></div></div><div class=\"public anchor\" id=\"var-squuid\"><h3>squuid</h3><div class=\"usage\"><code>(squuid)</code></div><div class=\"doc\"><pre class=\"plaintext\">Generate a SQUUID (sequential, random) unique identifier.  SQUUID's\nare a nonstandard variation on v4 (random) UUIDs that have the\ndesirable property that they increase sequentially over time as well\nas encode retrievably the posix time at which they were generated.\nSplits and reassembles a v4 UUID to merge current POSIX\ntime (seconds since 12:00am January 1, 1970 UTC) with the most\nsignificant 32 bits of the UUID.</pre></div></div><div class=\"public anchor\" id=\"var-uuid-string.3F\"><h3>uuid-string?</h3><div class=\"usage\"><code>(uuid-string? str)</code></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-uuid-urn-string.3F\"><h3>uuid-urn-string?</h3><div class=\"usage\"><code>(uuid-urn-string? str)</code></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-uuid-vec.3F\"><h3>uuid-vec?</h3><div class=\"usage\"><code>(uuid-vec? v)</code></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-UUIDable\"><h3>UUIDable</h3><h4 class=\"type\">protocol</h4><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">A UUIDable object directly represents a UUID.  Examples of things which\nmight be conceptually 'uuidable' include string representation of a\nUUID in canonical hex format, or an appropriate URN URI.</pre></div><div class=\"members\"><h4>members</h4><div class=\"inner\"><div class=\"public anchor\" id=\"var-as-uuid\"><h3>as-uuid</h3><div class=\"usage\"><code>(as-uuid x)</code></div><div class=\"doc\"><pre class=\"plaintext\">Coerce the value 'x' to a UUID.\n</pre></div></div><div class=\"public anchor\" id=\"var-uuidable.3F\"><h3>uuidable?</h3><div class=\"usage\"><code>(uuidable? x)</code></div><div class=\"doc\"><pre class=\"plaintext\">Return 'true' if 'x' can be coerced to UUID.\n</pre></div></div></div></div></div><div class=\"public anchor\" id=\"var-UUIDNameBytes\"><h3>UUIDNameBytes</h3><h4 class=\"type\">protocol</h4><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">A mechanism intended for user-level extension that defines the\ndecoding rules for the local-part representation of arbitrary\nClojure / Java Objects when used for computing namespaced\nidentifiers.</pre></div><div class=\"members\"><h4>members</h4><div class=\"inner\"><div class=\"public anchor\" id=\"var-as-byte-array\"><h3>as-byte-array</h3><div class=\"usage\"><code>(as-byte-array x)</code></div><div class=\"doc\"><pre class=\"plaintext\">Extract a byte serialization that represents the 'name' of x,\ntypically unique within a given namespace.</pre></div></div></div></div></div><div class=\"public anchor\" id=\"var-UUIDRfc4122\"><h3>UUIDRfc4122</h3><h4 class=\"type\">protocol</h4><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-UUIDRfc9562\"><h3>UUIDRfc9562</h3><h4 class=\"type\">protocol</h4><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">A protocol that abstracts an unique identifier as described by\nIETF RFC9562 &lt;<a href=\"http://www.ietf.org/rfc/rfc9562.txt&gt;\">http://www.ietf.org/rfc/rfc9562.txt&gt;</a>;. A UUID\nrepresents a 128-bit value, however there are variant encoding\nlayouts used to assign and interpret information encoded in\nthose bits.  This is a protocol for  _variant 2_ (*Leach-Salz*)\nUUID's.</pre></div><div class=\"members\"><h4>members</h4><div class=\"inner\"><div class=\"public anchor\" id=\"var-get-clk-high\"><h3>get-clk-high</h3><div class=\"usage\"><code>(get-clk-high uuid)</code></div><div class=\"doc\"><pre class=\"plaintext\">Return the 8 bit unsigned value that represents the most significant\nbyte of the `clk-seq` multiplexed with the `variant` of this UUID.</pre></div></div><div class=\"public anchor\" id=\"var-get-clk-low\"><h3>get-clk-low</h3><div class=\"usage\"><code>(get-clk-low uuid)</code></div><div class=\"doc\"><pre class=\"plaintext\">Return the 8 bit unsigned value that represents the least significant\nbyte of the `clk-seq` associated with this UUID.</pre></div></div><div class=\"public anchor\" id=\"var-get-clk-seq\"><h3>get-clk-seq</h3><div class=\"usage\"><code>(get-clk-seq uuid)</code></div><div class=\"doc\"><pre class=\"plaintext\">Return the clock-sequence number associated with this UUID. For time-based\n(v1, v6) UUID's the 'clock-sequence' value is a somewhat counter-intuitively\nnamed seed-value that is used to reduce the potential that duplicate UUID's\nmight be generated under unusual situations, such as if the system hardware\nclock is set backward in time or if, despite all efforts otherwise, a\nduplicate node-id happens to be generated. This value is initialized to\na random 16-bit number once per lifetime of the system.  For\nnon-gregorian-time-based (v3, v4, v5, v7, v8, squuid) UUID's, always\nreturns `nil`.</pre></div></div><div class=\"public anchor\" id=\"var-get-instant\"><h3>get-instant</h3><div class=\"usage\"><code>(get-instant uuid)</code></div><div class=\"doc\"><pre class=\"plaintext\">For time-based (v1, v6, v7) UUID's, return a java.util.Date\nobject that represents the system time at which this UUID was\ngenerated. NOTE: the returned value may not necessarily be\ntemporally unique. For non-time-based\n(v3, v4, v5, v8, squuid) UUID's, always returns `nil`.</pre></div></div><div class=\"public anchor\" id=\"var-get-node-id\"><h3>get-node-id</h3><div class=\"usage\"><code>(get-node-id uuid)</code></div><div class=\"doc\"><pre class=\"plaintext\">Return the 48 bit unsigned value that represents the spatially unique\nnode identifier associated with this UUID.</pre></div></div><div class=\"public anchor\" id=\"var-get-time-high\"><h3>get-time-high</h3><div class=\"usage\"><code>(get-time-high uuid)</code></div><div class=\"doc\"><pre class=\"plaintext\">Return the 16 bit unsigned value that represents the `time-high` field\nof the `timestamp` multiplexed with the `version` of this UUID.</pre></div></div><div class=\"public anchor\" id=\"var-get-time-low\"><h3>get-time-low</h3><div class=\"usage\"><code>(get-time-low uuid)</code></div><div class=\"doc\"><pre class=\"plaintext\">Return the 32 bit unsigned value that represents the `time-low` field\nof the `timestamp` associated with this UUID.</pre></div></div><div class=\"public anchor\" id=\"var-get-time-mid\"><h3>get-time-mid</h3><div class=\"usage\"><code>(get-time-mid uuid)</code></div><div class=\"doc\"><pre class=\"plaintext\">Return the 16 bit unsigned value that represents the `time-mid` field\nof the `timestamp` associated with this UUID.</pre></div></div><div class=\"public anchor\" id=\"var-get-timestamp\"><h3>get-timestamp</h3><div class=\"usage\"><code>(get-timestamp uuid)</code></div><div class=\"doc\"><pre class=\"plaintext\">Return the time of UUID creation.  For Gregorian time-based (v1,\nv6) UUID's, this is 60 bit unsigned value that represents a\ntemporally unique timestamp associated with this UUID.  The result\nencodes the number of 100 nanosecond intervals since the adoption of\nthe Gregorian calendar.  For v7 UUID's this encodes the more common\nunix time in milliseconds since midnight, January 1, 1970 UTC.  For\nnon-time-based (v3, v4, v5, v8, squuid) UUID's, always returns\n`nil`.</pre></div></div><div class=\"public anchor\" id=\"var-get-unix-time\"><h3>get-unix-time</h3><div class=\"usage\"><code>(get-unix-time uuid)</code></div><div class=\"doc\"><pre class=\"plaintext\">For time-based (v1, v6, v7) UUIDs return the timestamp portion in\napproximately milliseconds since the Unix epoch 1970-01-01T00:00:00.000Z.\nFor non-time-based (v3, v4, v5, v8, squuid) UUID's, always returns `nil`.</pre></div></div><div class=\"public anchor\" id=\"var-get-variant\"><h3>get-variant</h3><div class=\"usage\"><code>(get-variant uuid)</code></div><div class=\"doc\"><pre class=\"plaintext\">Return the variant number associated with this UUID.  The variant field\ncontains a value which identifies the layout of the UUID.  The bit-layout\nimplemented by this protocol supports UUID's with a variant value of 0x2,\nwhich indicates Leach-Salz layout.  Defined UUID variant values are:\n\n0x0   Null\n0x2   Leach-Salz\n0x6   Microsoft\n0x7   Max\n\nIn the canonical representation, xxxxxxxx-xxxx-xxxx-Nxxx-xxxxxxxxxxxx,\nthe most significant bits of N indicate the variant (depending on the\nvariant one, two, or three bits are used). The variant covered by RFC9562\nis indicated by the two most significant bits of N being 1 0 (i.e., the\nhexadecimal N will always be 8, 9, A, or B).</pre></div></div><div class=\"public anchor\" id=\"var-get-version\"><h3>get-version</h3><div class=\"usage\"><code>(get-version uuid)</code></div><div class=\"doc\"><pre class=\"plaintext\">Return the version number associated with this UUID.  The version\nfield contains a value which describes the nature of the UUID.  There\nare five versions of Leach-Salz UUID, plus the null and max UUIDs:\n\n0x0   Null\n0x1   Time based\n0x2   DCE security with POSIX UID\n0x3   Namespaced, deterministic (MD5 Digest)\n0x4   Cryptographic random\n0x5   Namespaced, deterministic (SHA1 Digest)\n0x6   Time based, lexically ordered\n0x7   POSIX Time based, lexically ordered, cryptographically secure\n0x8   User Customizable\n0xF   Max\n\nIn the canonical representation, xxxxxxxx-xxxx-Mxxx-xxxx-xxxxxxxxxxxx,\nthe four bits of M indicate the UUID version (i.e., the hexadecimal M\nwill be either 1, 2, 3, 4, 5, 6, 7, or 8).</pre></div></div><div class=\"public anchor\" id=\"var-get-word-high\"><h3>get-word-high</h3><div class=\"usage\"><code>(get-word-high uuid)</code></div><div class=\"doc\"><pre class=\"plaintext\">Return the most significant 64 bits of UUID's 128 bit value.\n</pre></div></div><div class=\"public anchor\" id=\"var-get-word-low\"><h3>get-word-low</h3><div class=\"usage\"><code>(get-word-low uuid)</code></div><div class=\"doc\"><pre class=\"plaintext\">Return the least significant 64 bits of UUID's 128 bit value.\n</pre></div></div><div class=\"public anchor\" id=\"var-hash-code\"><h3>hash-code</h3><div class=\"usage\"><code>(hash-code uuid)</code></div><div class=\"doc\"><pre class=\"plaintext\">Return a suitable 64-bit hash value for `uuid`.  Extend with\nspecialized hash computation.</pre></div></div><div class=\"public anchor\" id=\"var-max.3F\"><h3>max?</h3><div class=\"usage\"><code>(max? uuid)</code></div><div class=\"doc\"><pre class=\"plaintext\">Return `true` only if `uuid` has all 128 bits set and is\ntherefore equal to the maximum UUID, ffffffff-ffff-ffff-ffff-ffffffffffff.</pre></div></div><div class=\"public anchor\" id=\"var-null.3F\"><h3>null?</h3><div class=\"usage\"><code>(null? uuid)</code></div><div class=\"doc\"><pre class=\"plaintext\">Return `true` only if `uuid` has all 128 bits set to zero and is\ntherefore equal to the null UUID, 00000000-0000-0000-0000-000000000000.</pre></div></div><div class=\"public anchor\" id=\"var-to-byte-array\"><h3>to-byte-array</h3><div class=\"usage\"><code>(to-byte-array uuid)</code></div><div class=\"doc\"><pre class=\"plaintext\">Return an array of 16 bytes that represents `uuid` as a decomposed\noctet serialization encoded in most-significant-byte first order.</pre></div></div><div class=\"public anchor\" id=\"var-to-hex-string\"><h3>to-hex-string</h3><div class=\"usage\"><code>(to-hex-string uuid)</code></div><div class=\"doc\"><pre class=\"plaintext\">Return a String object that represents `uuid` as the 32 hexadecimal\ncharacters directly encodong the UUID's 128 bit value:\n\n    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</pre></div></div><div class=\"public anchor\" id=\"var-to-string\"><h3>to-string</h3><div class=\"usage\"><code>(to-string uuid)</code></div><div class=\"doc\"><pre class=\"plaintext\">Return a String object that represents `uuid` in the canonical\n36 character hex-string format:\n\n    xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx</pre></div></div><div class=\"public anchor\" id=\"var-to-uri\"><h3>to-uri</h3><div class=\"usage\"><code>(to-uri uuid)</code></div><div class=\"doc\"><pre class=\"plaintext\">Return the unique URN URI associated with this UUID.\n</pre></div></div><div class=\"public anchor\" id=\"var-to-urn-string\"><h3>to-urn-string</h3><div class=\"usage\"><code>(to-urn-string uuid)</code></div><div class=\"doc\"><pre class=\"plaintext\">Return a String object that represents `uuid` as a the string\nserialization of the URN URI based on the canonical 36 character\nhex-string representation:\n\n    urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx</pre></div></div><div class=\"public anchor\" id=\"var-uuid.3C\"><h3>uuid&lt;</h3><div class=\"usage\"><code>(uuid&lt; x y)</code></div><div class=\"doc\"><pre class=\"plaintext\">Directly compare two UUID's for &lt; relation based on the ordinality\nsemantics defined by [RFC4122:3 RULES FOR LEXICAL EQUIVALENCE].\nSee: `clj-uuid/&lt;`</pre></div></div><div class=\"public anchor\" id=\"var-uuid.3D\"><h3>uuid=</h3><div class=\"usage\"><code>(uuid= x y)</code></div><div class=\"doc\"><pre class=\"plaintext\">Directly compare two UUID's for = relation based on the equality\nsemantics defined by [RFC4122:3 RULES FOR LEXICAL EQUIVALENCE].\nSee: `clj-uuid/=`</pre></div></div><div class=\"public anchor\" id=\"var-uuid.3E\"><h3>uuid&gt;</h3><div class=\"usage\"><code>(uuid&gt; x y)</code></div><div class=\"doc\"><pre class=\"plaintext\">Directly compare two UUID's for &gt; relation based on the ordinality\nsemantics defined by [RFC4122:3 RULES FOR LEXICAL EQUIVALENCE].\nSee: `clj-uuid/&gt;`</pre></div></div><div class=\"public anchor\" id=\"var-uuid.3F\"><h3>uuid?</h3><div class=\"usage\"><code>(uuid? x)</code></div><div class=\"doc\"><pre class=\"plaintext\">Return `true` if `x` implements an RFC9562 unique identifier.\n</pre></div></div></div></div></div><div class=\"public anchor\" id=\"var-v0\"><h3>v0</h3><div class=\"usage\"><code>(v0)</code></div><div class=\"doc\"><pre class=\"plaintext\">Generates the v0 (null) UUID, 00000000-0000-0000-0000-000000000000.\n</pre></div></div><div class=\"public anchor\" id=\"var-v1\"><h3>v1</h3><div class=\"usage\"><code>(v1)</code></div><div class=\"doc\"><pre class=\"plaintext\">Generate a v1 (time-based) unique identifier, guaranteed to be unique\nand thread-safe regardless of clock precision or degree of concurrency.\nCreation of v1 UUID's does not require any call to a cryptographic\ngenerator and can be accomplished much more efficiently than v3, v4, v5, v7,\nor squuid's.  A v1 UUID reveals both the identity of the computer that\ngenerated the UUID and the time at which it did so.  Its uniqueness across\ncomputers is guaranteed as long as MAC addresses are not duplicated.</pre></div></div><div class=\"public anchor\" id=\"var-v3\"><h3>v3</h3><div class=\"usage\"><code>(v3 context local-part)</code></div><div class=\"doc\"><pre class=\"plaintext\">Generate a v3 (name based, MD5 hash) UUID. 'context' must be UUIDable.\nv3 identifiers are intended for generating UUID's from names that are\ndrawn from, and unique within, some namespace.  The concept of name and\nnamespace should be broadly construed, and not limited to textual names.\nThe requirements for a v3 UUID are as follows:\n\n* v3 UUID's generated at different times from the same name in the same\n  namespace MUST be equal.\n\n* v3 UUID's generated from two different names in the same namespace\n  SHOULD be distinct with a high degree of certainty.\n\n* v3 UUID's generated from the same name in two different namespaces\n  SHOULD be distinct with a high degree of certainty.\n\n* If two v3 UUID's are equal, then there is a high degree of certainty\n  that they were generated from the same name in the same namespace.</pre></div></div><div class=\"public anchor\" id=\"var-v4\"><h3>v4</h3><div class=\"usage\"><code>(v4)</code><code>(v4 msb lsb)</code></div><div class=\"doc\"><pre class=\"plaintext\">Generate a v4 (random) UUID.  Uses default JVM implementation.  If two\narguments, lsb and msb (both long) are provided, then construct a valid,\nproperly formatted v4 UUID based on those values.  So, for example the\nfollowing UUID, created from all zero bits, is indeed distinct from the\nnull UUID:\n\n    (v4)\n     =&gt; #uuid \"dcf0035f-ea29-4d1c-b52e-4ea499c6323e\"\n\n    (v4 0 0)\n     =&gt; #uuid \"00000000-0000-4000-8000-000000000000\"\n\n    (null)\n     =&gt; #uuid \"00000000-0000-0000-0000-000000000000\"</pre></div></div><div class=\"public anchor\" id=\"var-v5\"><h3>v5</h3><div class=\"usage\"><code>(v5 context local-part)</code></div><div class=\"doc\"><pre class=\"plaintext\">Generate a v5 (name based, SHA1 hash) UUID. 'context' must be UUIDable.\nv5 identifiers are intended for generating UUID's from names that are\ndrawn from, and unique within, some namespace.  The concept of name and\nnamespace should be broadly construed, and not limited to textual names.\nThe requirements for a v5 UUID are as follows:\n\n* v5 UUID's generated at different times from the same name in the same\n  namespace MUST be equal.\n\n* v5 UUID's generated from two different names in the same namespace\n  SHOULD be distinct with a high degree of certainty.\n\n* v5 UUID's generated from the same name in two different namespaces\n  SHOULD be distinct with a high degree of certainty.\n\n* If two v5 UUID's are equal, then there is a high degree of certainty\n  that they were generated from the same name in the same namespace.</pre></div></div><div class=\"public anchor\" id=\"var-v6\"><h3>v6</h3><div class=\"usage\"><code>(v6)</code></div><div class=\"doc\"><pre class=\"plaintext\">Generate a v6 (time-based), LEXICALLY SORTABLE, unique identifier,\nv6 is a field-compatible version of v1, reordered for improved DB\nlocality.  Creation of v6 UUID's does not require any call to a\ncryptographic generator and can be accomplished much more efficiently\nthan v3, v4, v5, v7, or squuid's.  A v6 UUID uses a cryptographically\nsecure, hard to guess random node id. It DOES NOT reveal the identity\nof the computer on which it was created.</pre></div></div><div class=\"public anchor\" id=\"var-v7\"><h3>v7</h3><div class=\"usage\"><code>(v7)</code></div><div class=\"doc\"><pre class=\"plaintext\">Generate a v7 unix time-based, LEXICALLY SORTABLE UUID with monotonic\ncounter and cryptographically secure random portion and POSIX time encoding.\nAs such, creation of v7 UUIDs may be significantly slower, but have improved\nentropy chararacteristics compared to v1 or v6 UUIDs.</pre></div></div><div class=\"public anchor\" id=\"var-v7nc\"><h3>v7nc</h3><div class=\"usage\"><code>(v7nc)</code></div><div class=\"doc\"><pre class=\"plaintext\">Generate a v7 UUID using non-cryptographic randomness (ThreadLocalRandom).\nProduces valid RFC 9562 v7 UUIDs with the same timestamp/version/variant\nstructure as v7, but uses java.util.concurrent.ThreadLocalRandom instead\nof SecureRandom and a per-thread monotonic counter instead of a global\nAtomicLong.  This trades cryptographic unguessability for significantly\nhigher throughput -- comparable to JUG's TimeBasedEpochGenerator.\n\nThe per-thread counter uses rand_a (12 bits) as a fixed seed per\nmillisecond and rand_b (62 bits) as a strictly increasing counter,\ngiving 2^62 UUIDs per millisecond per thread before overflow.</pre></div></div><div class=\"public anchor\" id=\"var-v8\"><h3>v8</h3><div class=\"usage\"><code>(v8 msb lsb)</code></div><div class=\"doc\"><pre class=\"plaintext\">Generate a v8 custom UUID with up to 122 bits of user data.\n</pre></div></div></div></body></html>"
  },
  {
    "path": "doc/api/clj-uuid.html",
    "content": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>clj-uuid documentation</title><link rel=\"stylesheet\" type=\"text/css\" href=\"css/default.css\" /><link rel=\"stylesheet\" type=\"text/css\" href=\"css/highlight.css\" /><script type=\"text/javascript\" src=\"js/highlight.min.js\"></script><script type=\"text/javascript\" src=\"js/jquery.min.js\"></script><script type=\"text/javascript\" src=\"js/page_effects.js\"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id=\"header\"><h2>Generated by <a href=\"https://github.com/weavejester/codox\">Codox</a></h2><h1><a href=\"index.html\"><span class=\"project-title\"><span class=\"project-name\">clj-uuid</span> <span class=\"project-version\">0.2.5-SNAPSHOT</span></span></a></h1></div><div class=\"sidebar primary\"><h3 class=\"no-link\"><span class=\"inner\">Project</span></h3><ul class=\"index-link\"><li class=\"depth-1 \"><a href=\"index.html\"><div class=\"inner\">Index</div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Namespaces</span></h3><ul><li class=\"depth-1 current\"><a href=\"clj-uuid.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>clj-uuid</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.bitmop.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>bitmop</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.clock.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>clock</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.constants.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>constants</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.core.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>core</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.node.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>node</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.random.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>random</span></div></a></li><li class=\"depth-2\"><a href=\"clj-uuid.util.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>util</span></div></a></li></ul></div><div class=\"sidebar secondary\"><h3><a href=\"#top\"><span class=\"inner\">Public Vars</span></a></h3><ul><li class=\"depth-1\"><a href=\"clj-uuid.html#var-.2Bmax.2B\"><div class=\"inner\"><span>+max+</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-.2Bnamespace-dns.2B\"><div class=\"inner\"><span>+namespace-dns+</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-.2Bnamespace-oid.2B\"><div class=\"inner\"><span>+namespace-oid+</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-.2Bnamespace-url.2B\"><div class=\"inner\"><span>+namespace-url+</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-.2Bnamespace-x500.2B\"><div class=\"inner\"><span>+namespace-x500+</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-.2Bnull.2B\"><div class=\"inner\"><span>+null+</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-.3C\"><div class=\"inner\"><span>&lt;</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-.3D\"><div class=\"inner\"><span>=</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-.3E\"><div class=\"inner\"><span>&gt;</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-as-byte-array\"><div class=\"inner\"><span>as-byte-array</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-as-uuid\"><div class=\"inner\"><span>as-uuid</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-get-clk-high\"><div class=\"inner\"><span>get-clk-high</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-get-clk-low\"><div class=\"inner\"><span>get-clk-low</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-get-clk-seq\"><div class=\"inner\"><span>get-clk-seq</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-get-instant\"><div class=\"inner\"><span>get-instant</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-get-node-id\"><div class=\"inner\"><span>get-node-id</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-get-time-high\"><div class=\"inner\"><span>get-time-high</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-get-time-low\"><div class=\"inner\"><span>get-time-low</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-get-time-mid\"><div class=\"inner\"><span>get-time-mid</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-get-timestamp\"><div class=\"inner\"><span>get-timestamp</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-get-unix-time\"><div class=\"inner\"><span>get-unix-time</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-get-variant\"><div class=\"inner\"><span>get-variant</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-get-version\"><div class=\"inner\"><span>get-version</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-get-word-high\"><div class=\"inner\"><span>get-word-high</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-get-word-low\"><div class=\"inner\"><span>get-word-low</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-hash-code\"><div class=\"inner\"><span>hash-code</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-max\"><div class=\"inner\"><span>max</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-max.3F\"><div class=\"inner\"><span>max?</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-monotonic-time\"><div class=\"inner\"><span>monotonic-time</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-null\"><div class=\"inner\"><span>null</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-null.3F\"><div class=\"inner\"><span>null?</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-squuid\"><div class=\"inner\"><span>squuid</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-to-byte-array\"><div class=\"inner\"><span>to-byte-array</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-to-hex-string\"><div class=\"inner\"><span>to-hex-string</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-to-string\"><div class=\"inner\"><span>to-string</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-to-uri\"><div class=\"inner\"><span>to-uri</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-to-urn-string\"><div class=\"inner\"><span>to-urn-string</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-uuid-string.3F\"><div class=\"inner\"><span>uuid-string?</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-uuid-urn-string.3F\"><div class=\"inner\"><span>uuid-urn-string?</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-uuid-vec.3F\"><div class=\"inner\"><span>uuid-vec?</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-uuid.3C\"><div class=\"inner\"><span>uuid&lt;</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-uuid.3D\"><div class=\"inner\"><span>uuid=</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-uuid.3E\"><div class=\"inner\"><span>uuid&gt;</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-uuid.3F\"><div class=\"inner\"><span>uuid?</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-UUIDable\"><div class=\"inner\"><span>UUIDable</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-uuidable.3F\"><div class=\"inner\"><span>uuidable?</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-UUIDNameBytes\"><div class=\"inner\"><span>UUIDNameBytes</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-UUIDRfc4122\"><div class=\"inner\"><span>UUIDRfc4122</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-UUIDRfc9562\"><div class=\"inner\"><span>UUIDRfc9562</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-v0\"><div class=\"inner\"><span>v0</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-v1\"><div class=\"inner\"><span>v1</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-v3\"><div class=\"inner\"><span>v3</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-v4\"><div class=\"inner\"><span>v4</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-v5\"><div class=\"inner\"><span>v5</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-v6\"><div class=\"inner\"><span>v6</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-v7\"><div class=\"inner\"><span>v7</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-v7nc\"><div class=\"inner\"><span>v7nc</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.html#var-v8\"><div class=\"inner\"><span>v8</span></div></a></li></ul></div><div class=\"namespace-docs\" id=\"content\"><h1 class=\"anchor\" id=\"top\">clj-uuid</h1><div class=\"doc\"><pre class=\"plaintext\">RFC 9562 UUID implementation for Clojure.\n\nThis namespace re-exports all public vars from clj-uuid.core. For backward\ncompatibility, both `(require '[clj-uuid :as uuid])` and\n`(require '[clj-uuid.core :as uuid])` provide identical functionality.\n\nQuick start:\n  (require '[clj-uuid :as uuid])\n  (uuid/v4)       ; random UUID\n  (uuid/v7)       ; time-based, sortable, cryptographically secure\n  (uuid/v7nc)     ; time-based, sortable, fast (non-cryptographic)\n\nSee clj-uuid.core for complete documentation.</pre></div><div class=\"public anchor\" id=\"var-.2Bmax.2B\"><h3>+max+</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">The MAX UUID is a special form of sentinel UUID that is specified to have\nall 128 bits set to one.</pre></div></div><div class=\"public anchor\" id=\"var-.2Bnamespace-dns.2B\"><h3>+namespace-dns+</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-.2Bnamespace-oid.2B\"><h3>+namespace-oid+</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-.2Bnamespace-url.2B\"><h3>+namespace-url+</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-.2Bnamespace-x500.2B\"><h3>+namespace-x500+</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-.2Bnull.2B\"><h3>+null+</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">The NULL UUID is a special form of sentinel UUID that is specified to have\nall 128 bits set to zero.</pre></div></div><div class=\"public anchor\" id=\"var-.3C\"><h3>&lt;</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Directly compare two or more UUIDs for &lt; relation based on the\nordinality semantics defined by [RFC4122:3 RULES FOR LEXICAL\nEQUIVALENCE].</pre></div></div><div class=\"public anchor\" id=\"var-.3D\"><h3>=</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Directly compare two or more UUIDs for = relation based on the\nequality semantics defined by [RFC4122:3 RULES FOR LEXICAL\nEQUIVALENCE].</pre></div></div><div class=\"public anchor\" id=\"var-.3E\"><h3>&gt;</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Directly compare two or more UUIDs for &gt; relation based on the\nordinality semantics defined by [RFC4122:3 RULES FOR LEXICAL\nEQUIVALENCE].</pre></div></div><div class=\"public anchor\" id=\"var-as-byte-array\"><h3>as-byte-array</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Extract a byte serialization that represents the 'name' of x,\ntypically unique within a given namespace.</pre></div></div><div class=\"public anchor\" id=\"var-as-uuid\"><h3>as-uuid</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Coerce the value 'x' to a UUID.\n</pre></div></div><div class=\"public anchor\" id=\"var-get-clk-high\"><h3>get-clk-high</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Return the 8 bit unsigned value that represents the most significant\nbyte of the `clk-seq` multiplexed with the `variant` of this UUID.</pre></div></div><div class=\"public anchor\" id=\"var-get-clk-low\"><h3>get-clk-low</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Return the 8 bit unsigned value that represents the least significant\nbyte of the `clk-seq` associated with this UUID.</pre></div></div><div class=\"public anchor\" id=\"var-get-clk-seq\"><h3>get-clk-seq</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Return the clock-sequence number associated with this UUID. For time-based\n(v1, v6) UUID's the 'clock-sequence' value is a somewhat counter-intuitively\nnamed seed-value that is used to reduce the potential that duplicate UUID's\nmight be generated under unusual situations, such as if the system hardware\nclock is set backward in time or if, despite all efforts otherwise, a\nduplicate node-id happens to be generated. This value is initialized to\na random 16-bit number once per lifetime of the system.  For\nnon-gregorian-time-based (v3, v4, v5, v7, v8, squuid) UUID's, always\nreturns `nil`.</pre></div></div><div class=\"public anchor\" id=\"var-get-instant\"><h3>get-instant</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">For time-based (v1, v6, v7) UUID's, return a java.util.Date\nobject that represents the system time at which this UUID was\ngenerated. NOTE: the returned value may not necessarily be\ntemporally unique. For non-time-based\n(v3, v4, v5, v8, squuid) UUID's, always returns `nil`.</pre></div></div><div class=\"public anchor\" id=\"var-get-node-id\"><h3>get-node-id</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Return the 48 bit unsigned value that represents the spatially unique\nnode identifier associated with this UUID.</pre></div></div><div class=\"public anchor\" id=\"var-get-time-high\"><h3>get-time-high</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Return the 16 bit unsigned value that represents the `time-high` field\nof the `timestamp` multiplexed with the `version` of this UUID.</pre></div></div><div class=\"public anchor\" id=\"var-get-time-low\"><h3>get-time-low</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Return the 32 bit unsigned value that represents the `time-low` field\nof the `timestamp` associated with this UUID.</pre></div></div><div class=\"public anchor\" id=\"var-get-time-mid\"><h3>get-time-mid</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Return the 16 bit unsigned value that represents the `time-mid` field\nof the `timestamp` associated with this UUID.</pre></div></div><div class=\"public anchor\" id=\"var-get-timestamp\"><h3>get-timestamp</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Return the time of UUID creation.  For Gregorian time-based (v1,\nv6) UUID's, this is 60 bit unsigned value that represents a\ntemporally unique timestamp associated with this UUID.  The result\nencodes the number of 100 nanosecond intervals since the adoption of\nthe Gregorian calendar.  For v7 UUID's this encodes the more common\nunix time in milliseconds since midnight, January 1, 1970 UTC.  For\nnon-time-based (v3, v4, v5, v8, squuid) UUID's, always returns\n`nil`.</pre></div></div><div class=\"public anchor\" id=\"var-get-unix-time\"><h3>get-unix-time</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">For time-based (v1, v6, v7) UUIDs return the timestamp portion in\napproximately milliseconds since the Unix epoch 1970-01-01T00:00:00.000Z.\nFor non-time-based (v3, v4, v5, v8, squuid) UUID's, always returns `nil`.</pre></div></div><div class=\"public anchor\" id=\"var-get-variant\"><h3>get-variant</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Return the variant number associated with this UUID.  The variant field\ncontains a value which identifies the layout of the UUID.  The bit-layout\nimplemented by this protocol supports UUID's with a variant value of 0x2,\nwhich indicates Leach-Salz layout.  Defined UUID variant values are:\n\n0x0   Null\n0x2   Leach-Salz\n0x6   Microsoft\n0x7   Max\n\nIn the canonical representation, xxxxxxxx-xxxx-xxxx-Nxxx-xxxxxxxxxxxx,\nthe most significant bits of N indicate the variant (depending on the\nvariant one, two, or three bits are used). The variant covered by RFC9562\nis indicated by the two most significant bits of N being 1 0 (i.e., the\nhexadecimal N will always be 8, 9, A, or B).</pre></div></div><div class=\"public anchor\" id=\"var-get-version\"><h3>get-version</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Return the version number associated with this UUID.  The version\nfield contains a value which describes the nature of the UUID.  There\nare five versions of Leach-Salz UUID, plus the null and max UUIDs:\n\n0x0   Null\n0x1   Time based\n0x2   DCE security with POSIX UID\n0x3   Namespaced, deterministic (MD5 Digest)\n0x4   Cryptographic random\n0x5   Namespaced, deterministic (SHA1 Digest)\n0x6   Time based, lexically ordered\n0x7   POSIX Time based, lexically ordered, cryptographically secure\n0x8   User Customizable\n0xF   Max\n\nIn the canonical representation, xxxxxxxx-xxxx-Mxxx-xxxx-xxxxxxxxxxxx,\nthe four bits of M indicate the UUID version (i.e., the hexadecimal M\nwill be either 1, 2, 3, 4, 5, 6, 7, or 8).</pre></div></div><div class=\"public anchor\" id=\"var-get-word-high\"><h3>get-word-high</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Return the most significant 64 bits of UUID's 128 bit value.\n</pre></div></div><div class=\"public anchor\" id=\"var-get-word-low\"><h3>get-word-low</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Return the least significant 64 bits of UUID's 128 bit value.\n</pre></div></div><div class=\"public anchor\" id=\"var-hash-code\"><h3>hash-code</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Return a suitable 64-bit hash value for `uuid`.  Extend with\nspecialized hash computation.</pre></div></div><div class=\"public anchor\" id=\"var-max\"><h3>max</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Generates the v15 (maximum) UUID, ffffffff-ffff-ffff-ffff-ffffffffffff.\n</pre></div></div><div class=\"public anchor\" id=\"var-max.3F\"><h3>max?</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Return `true` only if `uuid` has all 128 bits set and is\ntherefore equal to the maximum UUID, ffffffff-ffff-ffff-ffff-ffffffffffff.</pre></div></div><div class=\"public anchor\" id=\"var-monotonic-time\"><h3>monotonic-time</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Return a monotonic timestamp (guaranteed always increasing) based on\nthe number of 100-nanosecond intervals elapsed since the adoption of\nthe Gregorian calendar in the West, 12:00am Friday October 15, 1582 UTC.</pre></div></div><div class=\"public anchor\" id=\"var-null\"><h3>null</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Generates the v0 (null) UUID, 00000000-0000-0000-0000-000000000000.\n</pre></div></div><div class=\"public anchor\" id=\"var-null.3F\"><h3>null?</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Return `true` only if `uuid` has all 128 bits set to zero and is\ntherefore equal to the null UUID, 00000000-0000-0000-0000-000000000000.</pre></div></div><div class=\"public anchor\" id=\"var-squuid\"><h3>squuid</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Generate a SQUUID (sequential, random) unique identifier.  SQUUID's\nare a nonstandard variation on v4 (random) UUIDs that have the\ndesirable property that they increase sequentially over time as well\nas encode retrievably the posix time at which they were generated.\nSplits and reassembles a v4 UUID to merge current POSIX\ntime (seconds since 12:00am January 1, 1970 UTC) with the most\nsignificant 32 bits of the UUID.</pre></div></div><div class=\"public anchor\" id=\"var-to-byte-array\"><h3>to-byte-array</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Return an array of 16 bytes that represents `uuid` as a decomposed\noctet serialization encoded in most-significant-byte first order.</pre></div></div><div class=\"public anchor\" id=\"var-to-hex-string\"><h3>to-hex-string</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Return a String object that represents `uuid` as the 32 hexadecimal\ncharacters directly encodong the UUID's 128 bit value:\n\n    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</pre></div></div><div class=\"public anchor\" id=\"var-to-string\"><h3>to-string</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Return a String object that represents `uuid` in the canonical\n36 character hex-string format:\n\n    xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx</pre></div></div><div class=\"public anchor\" id=\"var-to-uri\"><h3>to-uri</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Return the unique URN URI associated with this UUID.\n</pre></div></div><div class=\"public anchor\" id=\"var-to-urn-string\"><h3>to-urn-string</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Return a String object that represents `uuid` as a the string\nserialization of the URN URI based on the canonical 36 character\nhex-string representation:\n\n    urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx</pre></div></div><div class=\"public anchor\" id=\"var-uuid-string.3F\"><h3>uuid-string?</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-uuid-urn-string.3F\"><h3>uuid-urn-string?</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-uuid-vec.3F\"><h3>uuid-vec?</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-uuid.3C\"><h3>uuid&lt;</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Directly compare two UUID's for &lt; relation based on the ordinality\nsemantics defined by [RFC4122:3 RULES FOR LEXICAL EQUIVALENCE].\nSee: `clj-uuid/&lt;`</pre></div></div><div class=\"public anchor\" id=\"var-uuid.3D\"><h3>uuid=</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Directly compare two UUID's for = relation based on the equality\nsemantics defined by [RFC4122:3 RULES FOR LEXICAL EQUIVALENCE].\nSee: `clj-uuid/=`</pre></div></div><div class=\"public anchor\" id=\"var-uuid.3E\"><h3>uuid&gt;</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Directly compare two UUID's for &gt; relation based on the ordinality\nsemantics defined by [RFC4122:3 RULES FOR LEXICAL EQUIVALENCE].\nSee: `clj-uuid/&gt;`</pre></div></div><div class=\"public anchor\" id=\"var-uuid.3F\"><h3>uuid?</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Return `true` if `x` implements an RFC9562 unique identifier.\n</pre></div></div><div class=\"public anchor\" id=\"var-UUIDable\"><h3>UUIDable</h3><h4 class=\"type\">protocol</h4><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-uuidable.3F\"><h3>uuidable?</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Return 'true' if 'x' can be coerced to UUID.\n</pre></div></div><div class=\"public anchor\" id=\"var-UUIDNameBytes\"><h3>UUIDNameBytes</h3><h4 class=\"type\">protocol</h4><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-UUIDRfc4122\"><h3>UUIDRfc4122</h3><h4 class=\"type\">protocol</h4><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-UUIDRfc9562\"><h3>UUIDRfc9562</h3><h4 class=\"type\">protocol</h4><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-v0\"><h3>v0</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Generates the v0 (null) UUID, 00000000-0000-0000-0000-000000000000.\n</pre></div></div><div class=\"public anchor\" id=\"var-v1\"><h3>v1</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Generate a v1 (time-based) unique identifier, guaranteed to be unique\nand thread-safe regardless of clock precision or degree of concurrency.\nCreation of v1 UUID's does not require any call to a cryptographic\ngenerator and can be accomplished much more efficiently than v3, v4, v5, v7,\nor squuid's.  A v1 UUID reveals both the identity of the computer that\ngenerated the UUID and the time at which it did so.  Its uniqueness across\ncomputers is guaranteed as long as MAC addresses are not duplicated.</pre></div></div><div class=\"public anchor\" id=\"var-v3\"><h3>v3</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Generate a v3 (name based, MD5 hash) UUID. 'context' must be UUIDable.\nv3 identifiers are intended for generating UUID's from names that are\ndrawn from, and unique within, some namespace.  The concept of name and\nnamespace should be broadly construed, and not limited to textual names.\nThe requirements for a v3 UUID are as follows:\n\n* v3 UUID's generated at different times from the same name in the same\n  namespace MUST be equal.\n\n* v3 UUID's generated from two different names in the same namespace\n  SHOULD be distinct with a high degree of certainty.\n\n* v3 UUID's generated from the same name in two different namespaces\n  SHOULD be distinct with a high degree of certainty.\n\n* If two v3 UUID's are equal, then there is a high degree of certainty\n  that they were generated from the same name in the same namespace.</pre></div></div><div class=\"public anchor\" id=\"var-v4\"><h3>v4</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Generate a v4 (random) UUID.  Uses default JVM implementation.  If two\narguments, lsb and msb (both long) are provided, then construct a valid,\nproperly formatted v4 UUID based on those values.  So, for example the\nfollowing UUID, created from all zero bits, is indeed distinct from the\nnull UUID:\n\n    (v4)\n     =&gt; #uuid \"dcf0035f-ea29-4d1c-b52e-4ea499c6323e\"\n\n    (v4 0 0)\n     =&gt; #uuid \"00000000-0000-4000-8000-000000000000\"\n\n    (null)\n     =&gt; #uuid \"00000000-0000-0000-0000-000000000000\"</pre></div></div><div class=\"public anchor\" id=\"var-v5\"><h3>v5</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Generate a v5 (name based, SHA1 hash) UUID. 'context' must be UUIDable.\nv5 identifiers are intended for generating UUID's from names that are\ndrawn from, and unique within, some namespace.  The concept of name and\nnamespace should be broadly construed, and not limited to textual names.\nThe requirements for a v5 UUID are as follows:\n\n* v5 UUID's generated at different times from the same name in the same\n  namespace MUST be equal.\n\n* v5 UUID's generated from two different names in the same namespace\n  SHOULD be distinct with a high degree of certainty.\n\n* v5 UUID's generated from the same name in two different namespaces\n  SHOULD be distinct with a high degree of certainty.\n\n* If two v5 UUID's are equal, then there is a high degree of certainty\n  that they were generated from the same name in the same namespace.</pre></div></div><div class=\"public anchor\" id=\"var-v6\"><h3>v6</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Generate a v6 (time-based), LEXICALLY SORTABLE, unique identifier,\nv6 is a field-compatible version of v1, reordered for improved DB\nlocality.  Creation of v6 UUID's does not require any call to a\ncryptographic generator and can be accomplished much more efficiently\nthan v3, v4, v5, v7, or squuid's.  A v6 UUID uses a cryptographically\nsecure, hard to guess random node id. It DOES NOT reveal the identity\nof the computer on which it was created.</pre></div></div><div class=\"public anchor\" id=\"var-v7\"><h3>v7</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Generate a v7 unix time-based, LEXICALLY SORTABLE UUID with monotonic\ncounter and cryptographically secure random portion and POSIX time encoding.\nAs such, creation of v7 UUIDs may be significantly slower, but have improved\nentropy chararacteristics compared to v1 or v6 UUIDs.</pre></div></div><div class=\"public anchor\" id=\"var-v7nc\"><h3>v7nc</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Generate a v7 UUID using non-cryptographic randomness (ThreadLocalRandom).\nProduces valid RFC 9562 v7 UUIDs with the same timestamp/version/variant\nstructure as v7, but uses java.util.concurrent.ThreadLocalRandom instead\nof SecureRandom and a per-thread monotonic counter instead of a global\nAtomicLong.  This trades cryptographic unguessability for significantly\nhigher throughput -- comparable to JUG's TimeBasedEpochGenerator.\n\nThe per-thread counter uses rand_a (12 bits) as a fixed seed per\nmillisecond and rand_b (62 bits) as a strictly increasing counter,\ngiving 2^62 UUIDs per millisecond per thread before overflow.</pre></div></div><div class=\"public anchor\" id=\"var-v8\"><h3>v8</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\">Generate a v8 custom UUID with up to 122 bits of user data.\n</pre></div></div></div></body></html>"
  },
  {
    "path": "doc/api/clj-uuid.node.html",
    "content": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>clj-uuid.node documentation</title><link rel=\"stylesheet\" type=\"text/css\" href=\"css/default.css\" /><link rel=\"stylesheet\" type=\"text/css\" href=\"css/highlight.css\" /><script type=\"text/javascript\" src=\"js/highlight.min.js\"></script><script type=\"text/javascript\" src=\"js/jquery.min.js\"></script><script type=\"text/javascript\" src=\"js/page_effects.js\"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id=\"header\"><h2>Generated by <a href=\"https://github.com/weavejester/codox\">Codox</a></h2><h1><a href=\"index.html\"><span class=\"project-title\"><span class=\"project-name\">clj-uuid</span> <span class=\"project-version\">0.2.5-SNAPSHOT</span></span></a></h1></div><div class=\"sidebar primary\"><h3 class=\"no-link\"><span class=\"inner\">Project</span></h3><ul class=\"index-link\"><li class=\"depth-1 \"><a href=\"index.html\"><div class=\"inner\">Index</div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Namespaces</span></h3><ul><li class=\"depth-1\"><a href=\"clj-uuid.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>clj-uuid</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.bitmop.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>bitmop</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.clock.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>clock</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.constants.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>constants</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.core.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>core</span></div></a></li><li class=\"depth-2 branch current\"><a href=\"clj-uuid.node.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>node</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.random.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>random</span></div></a></li><li class=\"depth-2\"><a href=\"clj-uuid.util.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>util</span></div></a></li></ul></div><div class=\"sidebar secondary\"><h3><a href=\"#top\"><span class=\"inner\">Public Vars</span></a></h3><ul><li class=\"depth-1\"><a href=\"clj-uuid.node.html#var-.2Bclock-sequence.2B\"><div class=\"inner\"><span>+clock-sequence+</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.node.html#var-.2Bnode-id.2B\"><div class=\"inner\"><span>+node-id+</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.node.html#var-.2Bv1-lsb.2B\"><div class=\"inner\"><span>+v1-lsb+</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.node.html#var-.2Bv6-lsb.2B\"><div class=\"inner\"><span>+v6-lsb+</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.node.html#var-node-id\"><div class=\"inner\"><span>node-id</span></div></a></li></ul></div><div class=\"namespace-docs\" id=\"content\"><h1 class=\"anchor\" id=\"top\">clj-uuid.node</h1><div class=\"doc\"><pre class=\"plaintext\"></pre></div><div class=\"public anchor\" id=\"var-.2Bclock-sequence.2B\"><h3>+clock-sequence+</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-.2Bnode-id.2B\"><h3>+node-id+</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-.2Bv1-lsb.2B\"><h3>+v1-lsb+</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-.2Bv6-lsb.2B\"><h3>+v6-lsb+</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-node-id\"><h3>node-id</h3><div class=\"usage\"></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div></div></body></html>"
  },
  {
    "path": "doc/api/clj-uuid.random.html",
    "content": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>clj-uuid.random documentation</title><link rel=\"stylesheet\" type=\"text/css\" href=\"css/default.css\" /><link rel=\"stylesheet\" type=\"text/css\" href=\"css/highlight.css\" /><script type=\"text/javascript\" src=\"js/highlight.min.js\"></script><script type=\"text/javascript\" src=\"js/jquery.min.js\"></script><script type=\"text/javascript\" src=\"js/page_effects.js\"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id=\"header\"><h2>Generated by <a href=\"https://github.com/weavejester/codox\">Codox</a></h2><h1><a href=\"index.html\"><span class=\"project-title\"><span class=\"project-name\">clj-uuid</span> <span class=\"project-version\">0.2.5-SNAPSHOT</span></span></a></h1></div><div class=\"sidebar primary\"><h3 class=\"no-link\"><span class=\"inner\">Project</span></h3><ul class=\"index-link\"><li class=\"depth-1 \"><a href=\"index.html\"><div class=\"inner\">Index</div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Namespaces</span></h3><ul><li class=\"depth-1\"><a href=\"clj-uuid.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>clj-uuid</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.bitmop.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>bitmop</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.clock.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>clock</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.constants.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>constants</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.core.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>core</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.node.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>node</span></div></a></li><li class=\"depth-2 branch current\"><a href=\"clj-uuid.random.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>random</span></div></a></li><li class=\"depth-2\"><a href=\"clj-uuid.util.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>util</span></div></a></li></ul></div><div class=\"sidebar secondary\"><h3><a href=\"#top\"><span class=\"inner\">Public Vars</span></a></h3><ul><li class=\"depth-1\"><a href=\"clj-uuid.random.html#var-bytes\"><div class=\"inner\"><span>bytes</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.random.html#var-eight-bits\"><div class=\"inner\"><span>eight-bits</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.random.html#var-eleven-bits\"><div class=\"inner\"><span>eleven-bits</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.random.html#var-long\"><div class=\"inner\"><span>long</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.random.html#var-ten-bits\"><div class=\"inner\"><span>ten-bits</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.random.html#var-twelve-bits\"><div class=\"inner\"><span>twelve-bits</span></div></a></li></ul></div><div class=\"namespace-docs\" id=\"content\"><h1 class=\"anchor\" id=\"top\">clj-uuid.random</h1><div class=\"doc\"><pre class=\"plaintext\"></pre></div><div class=\"public anchor\" id=\"var-bytes\"><h3>bytes</h3><div class=\"usage\"><code>(bytes n)</code></div><div class=\"doc\"><pre class=\"plaintext\">Generate `n` random bytes.\n</pre></div></div><div class=\"public anchor\" id=\"var-eight-bits\"><h3>eight-bits</h3><div class=\"usage\"><code>(eight-bits)</code></div><div class=\"doc\"><pre class=\"plaintext\">Generate a hard-to-guess long value between 0 and 255\n</pre></div></div><div class=\"public anchor\" id=\"var-eleven-bits\"><h3>eleven-bits</h3><div class=\"usage\"><code>(eleven-bits)</code></div><div class=\"doc\"><pre class=\"plaintext\">Generate a hard-to-guess long value between 0 and 2047\n</pre></div></div><div class=\"public anchor\" id=\"var-long\"><h3>long</h3><div class=\"usage\"><code>(long)</code><code>(long n-bytes)</code></div><div class=\"doc\"><pre class=\"plaintext\">Generate a long value that is hard to guess. Randomness limited to the\nnumber of bytes.</pre></div></div><div class=\"public anchor\" id=\"var-ten-bits\"><h3>ten-bits</h3><div class=\"usage\"><code>(ten-bits)</code></div><div class=\"doc\"><pre class=\"plaintext\">Generate a hard-to-guess long value between 0 and 1023\n</pre></div></div><div class=\"public anchor\" id=\"var-twelve-bits\"><h3>twelve-bits</h3><div class=\"usage\"><code>(twelve-bits)</code></div><div class=\"doc\"><pre class=\"plaintext\">Generate a hard-to-guess long value between 0 and 4095\n</pre></div></div></div></body></html>"
  },
  {
    "path": "doc/api/clj-uuid.util.html",
    "content": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>clj-uuid.util documentation</title><link rel=\"stylesheet\" type=\"text/css\" href=\"css/default.css\" /><link rel=\"stylesheet\" type=\"text/css\" href=\"css/highlight.css\" /><script type=\"text/javascript\" src=\"js/highlight.min.js\"></script><script type=\"text/javascript\" src=\"js/jquery.min.js\"></script><script type=\"text/javascript\" src=\"js/page_effects.js\"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id=\"header\"><h2>Generated by <a href=\"https://github.com/weavejester/codox\">Codox</a></h2><h1><a href=\"index.html\"><span class=\"project-title\"><span class=\"project-name\">clj-uuid</span> <span class=\"project-version\">0.2.5-SNAPSHOT</span></span></a></h1></div><div class=\"sidebar primary\"><h3 class=\"no-link\"><span class=\"inner\">Project</span></h3><ul class=\"index-link\"><li class=\"depth-1 \"><a href=\"index.html\"><div class=\"inner\">Index</div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Namespaces</span></h3><ul><li class=\"depth-1\"><a href=\"clj-uuid.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>clj-uuid</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.bitmop.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>bitmop</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.clock.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>clock</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.constants.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>constants</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.core.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>core</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.node.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>node</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.random.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>random</span></div></a></li><li class=\"depth-2 current\"><a href=\"clj-uuid.util.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>util</span></div></a></li></ul></div><div class=\"sidebar secondary\"><h3><a href=\"#top\"><span class=\"inner\">Public Vars</span></a></h3><ul><li class=\"depth-1\"><a href=\"clj-uuid.util.html#var-compile-if\"><div class=\"inner\"><span>compile-if</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.util.html#var-import-vars\"><div class=\"inner\"><span>import-vars</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.util.html#var-java6.3F\"><div class=\"inner\"><span>java6?</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.util.html#var-lines-of-file\"><div class=\"inner\"><span>lines-of-file</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.util.html#var-returning\"><div class=\"inner\"><span>returning</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.util.html#var-with-temp-file\"><div class=\"inner\"><span>with-temp-file</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.util.html#var-with-timing\"><div class=\"inner\"><span>with-timing</span></div></a></li><li class=\"depth-1\"><a href=\"clj-uuid.util.html#var-wrap-fn\"><div class=\"inner\"><span>wrap-fn</span></div></a></li></ul></div><div class=\"namespace-docs\" id=\"content\"><h1 class=\"anchor\" id=\"top\">clj-uuid.util</h1><div class=\"doc\"><pre class=\"plaintext\"></pre></div><div class=\"public anchor\" id=\"var-compile-if\"><h3>compile-if</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(compile-if exp then else)</code></div><div class=\"doc\"><pre class=\"plaintext\">Evaluate `exp` and if it returns logical true and doesn't error, expand to\n`then` otherwise expand to `else`.\ncredit: &lt;clojure/src/clj/clojure/core/reducers.clj#L24&gt;\n\n(compile-if (Class/forName \"java.util.concurrent.ForkJoinTask\")\n  (do-cool-stuff-with-fork-join)\n  (fall-back-to-executor-services))</pre></div></div><div class=\"public anchor\" id=\"var-import-vars\"><h3>import-vars</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(import-vars src-ns &amp; var-syms)</code></div><div class=\"doc\"><pre class=\"plaintext\">Import public vars from src-ns into the current namespace.\n</pre></div></div><div class=\"public anchor\" id=\"var-java6.3F\"><h3>java6?</h3><div class=\"usage\"><code>(java6?)</code></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-lines-of-file\"><h3>lines-of-file</h3><div class=\"usage\"><code>(lines-of-file file-name)</code></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-returning\"><h3>returning</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(returning value &amp; forms)</code></div><div class=\"doc\"><pre class=\"plaintext\">Compute a return value, then execute other forms for side effects.\nLike prog1 in common lisp, or a (do) that returns the first form.</pre></div></div><div class=\"public anchor\" id=\"var-with-temp-file\"><h3>with-temp-file</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(with-temp-file f-sym &amp; body)</code></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div><div class=\"public anchor\" id=\"var-with-timing\"><h3>with-timing</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(with-timing &amp; body)</code></div><div class=\"doc\"><pre class=\"plaintext\">Same as clojure.core/time but returns a vector of a the result of\nthe code and the milliseconds rather than printing a string. Runs\nthe code in an implicit do.</pre></div></div><div class=\"public anchor\" id=\"var-wrap-fn\"><h3>wrap-fn</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(wrap-fn name args &amp; body)</code></div><div class=\"doc\"><pre class=\"plaintext\"></pre></div></div></div></body></html>"
  },
  {
    "path": "doc/api/css/default.css",
    "content": "body {\n    font-family: Helvetica, Arial, sans-serif;\n    font-size: 15px;\n}\n\npre, code {\n    font-family: Monaco, DejaVu Sans Mono, Consolas, monospace;\n    font-size: 9pt;\n    margin: 15px 0;\n}\n\nh1 {\n    font-weight: normal;\n    font-size: 29px;\n    margin: 10px 0 2px 0;\n    padding: 0;\n}\n\nh2 {\n    font-weight: normal;\n    font-size: 25px;\n}\n\nh5.license {\n    margin: 9px 0 22px 0;\n    color: #555;\n    font-weight: normal;\n    font-size: 12px;\n    font-style: italic;\n}\n\n.document h1, .namespace-index h1 {\n    font-size: 32px;\n    margin-top: 12px;\n}\n\n#header, #content, .sidebar {\n    position: fixed;\n}\n\n#header {\n    top: 0;\n    left: 0;\n    right: 0;\n    height: 22px;\n    color: #f5f5f5;\n    padding: 5px 7px;\n}\n\n#content {\n    top: 32px;\n    right: 0;\n    bottom: 0;\n    overflow: auto;\n    background: #fff;\n    color: #333;\n    padding: 0 18px;\n}\n\n.sidebar {\n    position: fixed;\n    top: 32px;\n    bottom: 0;\n    overflow: auto;\n}\n\n.sidebar.primary {\n    background: #e2e2e2;\n    border-right: solid 1px #cccccc;\n    left: 0;\n    width: 250px;\n}\n\n.sidebar.secondary {\n    background: #f2f2f2;\n    border-right: solid 1px #d7d7d7;\n    left: 251px;\n    width: 200px;\n}\n\n#content.namespace-index, #content.document {\n    left: 251px;\n}\n\n#content.namespace-docs {\n    left: 452px;\n}\n\n#content.document {\n    padding-bottom: 10%;\n}\n\n#header {\n    background: #3f3f3f;\n    box-shadow: 0 0 8px rgba(0, 0, 0, 0.4);\n    z-index: 100;\n}\n\n#header h1 {\n    margin: 0;\n    padding: 0;\n    font-size: 18px;\n    font-weight: lighter;\n    text-shadow: -1px -1px 0px #333;\n}\n\n#header h1 .project-version {\n    font-weight: normal;\n}\n\n.project-version {\n    padding-left: 0.15em;\n}\n\n#header a, .sidebar a {\n    display: block;\n    text-decoration: none;\n}\n\n#header a {\n    color: #f5f5f5;\n}\n\n.sidebar a {\n    color: #333;\n}\n\n#header h2 {\n    float: right;\n    font-size: 9pt;\n    font-weight: normal;\n    margin: 4px 3px;\n    padding: 0;\n    color: #bbb;\n}\n\n#header h2 a {\n    display: inline;\n}\n\n.sidebar h3 {\n    margin: 0;\n    padding: 10px 13px 0 13px;\n    font-size: 19px;\n    font-weight: lighter;\n}\n\n.sidebar h3 a {\n    color: #444;\n}\n\n.sidebar h3.no-link {\n    color: #636363;\n}\n\n.sidebar ul {\n    padding: 7px 0 6px 0;\n    margin: 0;\n}\n\n.sidebar ul.index-link {\n    padding-bottom: 4px;\n}\n\n.sidebar li {\n    display: block;\n    vertical-align: middle;\n}\n\n.sidebar li a, .sidebar li .no-link {\n    border-left: 3px solid transparent;\n    padding: 0 10px;\n    white-space: nowrap;\n}\n\n.sidebar li .no-link {\n    display: block;\n    color: #777;\n    font-style: italic;\n}\n\n.sidebar li .inner {\n    display: inline-block;\n    padding-top: 7px;\n    height: 24px;\n}\n\n.sidebar li a, .sidebar li .tree {\n    height: 31px;\n}\n\n.depth-1 .inner { padding-left: 2px; }\n.depth-2 .inner { padding-left: 6px; }\n.depth-3 .inner { padding-left: 20px; }\n.depth-4 .inner { padding-left: 34px; }\n.depth-5 .inner { padding-left: 48px; }\n.depth-6 .inner { padding-left: 62px; }\n\n.sidebar li .tree {\n    display: block;\n    float: left;\n    position: relative;\n    top: -10px;\n    margin: 0 4px 0 0;\n    padding: 0;\n}\n\n.sidebar li.depth-1 .tree {\n    display: none;\n}\n\n.sidebar li .tree .top, .sidebar li .tree .bottom {\n    display: block;\n    margin: 0;\n    padding: 0;\n    width: 7px;\n}\n\n.sidebar li .tree .top {\n    border-left: 1px solid #aaa;\n    border-bottom: 1px solid #aaa;\n    height: 19px;\n}\n\n.sidebar li .tree .bottom {\n    height: 22px;\n}\n\n.sidebar li.branch .tree .bottom {\n    border-left: 1px solid #aaa;\n}\n\n.sidebar.primary li.current a {\n    border-left: 3px solid #a33;\n    color: #a33;\n}\n\n.sidebar.secondary li.current a {\n    border-left: 3px solid #33a;\n    color: #33a;\n}\n\n.namespace-index h2 {\n    margin: 30px 0 0 0;\n}\n\n.namespace-index h3 {\n    font-size: 16px;\n    font-weight: bold;\n    margin-bottom: 0;\n}\n\n.namespace-index .topics {\n    padding-left: 30px;\n    margin: 11px 0 0 0;\n}\n\n.namespace-index .topics li {\n    padding: 5px 0;\n}\n\n.namespace-docs h3 {\n    font-size: 18px;\n    font-weight: bold;\n}\n\n.public h3 {\n    margin: 0;\n    float: left;\n}\n\n.usage {\n    clear: both;\n}\n\n.public {\n    margin: 0;\n    border-top: 1px solid #e0e0e0;\n    padding-top: 14px;\n    padding-bottom: 6px;\n}\n\n.public:last-child {\n    margin-bottom: 20%;\n}\n\n.members .public:last-child {\n    margin-bottom: 0;\n}\n\n.members {\n    margin: 15px 0;\n}\n\n.members h4 {\n    color: #555;\n    font-weight: normal;\n    font-variant: small-caps;\n    margin: 0 0 5px 0;\n}\n\n.members .inner {\n    padding-top: 5px;\n    padding-left: 12px;\n    margin-top: 2px;\n    margin-left: 7px;\n    border-left: 1px solid #bbb;\n}\n\n#content .members .inner h3 {\n    font-size: 12pt;\n}\n\n.members .public {\n    border-top: none;\n    margin-top: 0;\n    padding-top: 6px;\n    padding-bottom: 0;\n}\n\n.members .public:first-child {\n    padding-top: 0;\n}\n\nh4.type,\nh4.dynamic,\nh4.added,\nh4.deprecated {\n    float: left;\n    margin: 3px 10px 15px 0;\n    font-size: 15px;\n    font-weight: bold;\n    font-variant: small-caps;\n}\n\n.public h4.type,\n.public h4.dynamic,\n.public h4.added,\n.public h4.deprecated {\n    font-size: 13px;\n    font-weight: bold;\n    margin: 3px 0 0 10px;\n}\n\n.members h4.type,\n.members h4.added,\n.members h4.deprecated {\n    margin-top: 1px;\n}\n\nh4.type {\n    color: #717171;\n}\n\nh4.dynamic {\n    color: #9933aa;\n}\n\nh4.added {\n    color: #508820;\n}\n\nh4.deprecated {\n    color: #880000;\n}\n\n.namespace {\n    margin-bottom: 30px;\n}\n\n.namespace:last-child {\n    margin-bottom: 10%;\n}\n\n.index {\n    padding: 0;\n    font-size: 80%;\n    margin: 15px 0;\n    line-height: 16px;\n}\n\n.index * {\n    display: inline;\n}\n\n.index p {\n    padding-right: 3px;\n}\n\n.index li {\n    padding-right: 5px;\n}\n\n.index ul {\n    padding-left: 0;\n}\n\n.type-sig {\n    clear: both;\n    color: #088;\n}\n\n.type-sig pre {\n    padding-top: 10px;\n    margin: 0;\n}\n\n.usage code {\n    display: block;\n    color: #008;\n    margin: 2px 0;\n}\n\n.usage code:first-child {\n    padding-top: 10px;\n}\n\np {\n    margin: 15px 0;\n}\n\n.public p:first-child, .public pre.plaintext {\n    margin-top: 12px;\n}\n\n.doc {\n    margin: 0 0 26px 0;\n    clear: both;\n}\n\n.public .doc {\n    margin: 0;\n}\n\n.namespace-index .doc {\n    margin-bottom: 20px;\n}\n\n.namespace-index .namespace .doc {\n    margin-bottom: 10px;\n}\n\n.markdown p, .markdown li, .markdown dt, .markdown dd, .markdown td {\n    line-height: 22px;\n}\n\n.markdown li {\n    padding: 2px 0;\n}\n\n.markdown h2 {\n    font-weight: normal;\n    font-size: 25px;\n    margin: 30px 0 10px 0;\n}\n\n.markdown h3 {\n    font-weight: normal;\n    font-size: 20px;\n    margin: 30px 0 0 0;\n}\n\n.markdown h4 {\n    font-size: 15px;\n    margin: 22px 0 -4px 0;\n}\n\n.doc, .public, .namespace .index {\n    max-width: 680px;\n    overflow-x: visible;\n}\n\n.markdown pre > code {\n    display: block;\n    padding: 10px;\n}\n\n.markdown pre > code, .src-link a {\n    border: 1px solid #e4e4e4;\n    border-radius: 2px;\n}\n\n.markdown code:not(.hljs), .src-link a {\n    background: #f6f6f6;\n}\n\npre.deps {\n    display: inline-block;\n    margin: 0 10px;\n    border: 1px solid #e4e4e4;\n    border-radius: 2px;\n    padding: 10px;\n    background-color: #f6f6f6;\n}\n\n.markdown hr {\n    border-style: solid;\n    border-top: none;\n    color: #ccc;\n}\n\n.doc ul, .doc ol {\n    padding-left: 30px;\n}\n\n.doc table {\n    border-collapse: collapse;\n    margin: 0 10px;\n}\n\n.doc table td, .doc table th {\n    border: 1px solid #dddddd;\n    padding: 4px 6px;\n}\n\n.doc table th {\n    background: #f2f2f2;\n}\n\n.doc dl {\n    margin: 0 10px 20px 10px;\n}\n\n.doc dl dt {\n    font-weight: bold;\n    margin: 0;\n    padding: 3px 0;\n    border-bottom: 1px solid #ddd;\n}\n\n.doc dl dd {\n    padding: 5px 0;\n    margin: 0 0 5px 10px;\n}\n\n.doc abbr {\n    border-bottom: 1px dotted #333;\n    font-variant: none;\n    cursor: help;\n}\n\n.src-link {\n    margin-bottom: 15px;\n}\n\n.src-link a {\n    font-size: 70%;\n    padding: 1px 4px;\n    text-decoration: none;\n    color: #5555bb;\n}\n"
  },
  {
    "path": "doc/api/css/highlight.css",
    "content": "/*\ngithub.com style (c) Vasily Polovnyov <vast@whiteants.net>\n*/\n\n.hljs {\n  display: block;\n  overflow-x: auto;\n  padding: 0.5em;\n  color: #333;\n  background: #f8f8f8;\n}\n\n.hljs-comment,\n.hljs-quote {\n  color: #998;\n  font-style: italic;\n}\n\n.hljs-keyword,\n.hljs-selector-tag,\n.hljs-subst {\n  color: #333;\n  font-weight: bold;\n}\n\n.hljs-number,\n.hljs-literal,\n.hljs-variable,\n.hljs-template-variable,\n.hljs-tag .hljs-attr {\n  color: #008080;\n}\n\n.hljs-string,\n.hljs-doctag {\n  color: #d14;\n}\n\n.hljs-title,\n.hljs-section,\n.hljs-selector-id {\n  color: #900;\n  font-weight: bold;\n}\n\n.hljs-subst {\n  font-weight: normal;\n}\n\n.hljs-type,\n.hljs-class .hljs-title {\n  color: #458;\n  font-weight: bold;\n}\n\n.hljs-tag,\n.hljs-name,\n.hljs-attribute {\n  color: #000080;\n  font-weight: normal;\n}\n\n.hljs-regexp,\n.hljs-link {\n  color: #009926;\n}\n\n.hljs-symbol,\n.hljs-bullet {\n  color: #990073;\n}\n\n.hljs-built_in,\n.hljs-builtin-name {\n  color: #0086b3;\n}\n\n.hljs-meta {\n  color: #999;\n  font-weight: bold;\n}\n\n.hljs-deletion {\n  background: #fdd;\n}\n\n.hljs-addition {\n  background: #dfd;\n}\n\n.hljs-emphasis {\n  font-style: italic;\n}\n\n.hljs-strong {\n  font-weight: bold;\n}\n"
  },
  {
    "path": "doc/api/index.html",
    "content": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>clj-uuid 0.2.5-SNAPSHOT</title><link rel=\"stylesheet\" type=\"text/css\" href=\"css/default.css\" /><link rel=\"stylesheet\" type=\"text/css\" href=\"css/highlight.css\" /><script type=\"text/javascript\" src=\"js/highlight.min.js\"></script><script type=\"text/javascript\" src=\"js/jquery.min.js\"></script><script type=\"text/javascript\" src=\"js/page_effects.js\"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id=\"header\"><h2>Generated by <a href=\"https://github.com/weavejester/codox\">Codox</a></h2><h1><a href=\"index.html\"><span class=\"project-title\"><span class=\"project-name\">clj-uuid</span> <span class=\"project-version\">0.2.5-SNAPSHOT</span></span></a></h1></div><div class=\"sidebar primary\"><h3 class=\"no-link\"><span class=\"inner\">Project</span></h3><ul class=\"index-link\"><li class=\"depth-1 current\"><a href=\"index.html\"><div class=\"inner\">Index</div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Namespaces</span></h3><ul><li class=\"depth-1\"><a href=\"clj-uuid.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>clj-uuid</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.bitmop.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>bitmop</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.clock.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>clock</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.constants.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>constants</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.core.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>core</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.node.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>node</span></div></a></li><li class=\"depth-2 branch\"><a href=\"clj-uuid.random.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>random</span></div></a></li><li class=\"depth-2\"><a href=\"clj-uuid.util.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>util</span></div></a></li></ul></div><div class=\"namespace-index\" id=\"content\"><h1><span class=\"project-title\"><span class=\"project-name\">clj-uuid</span> <span class=\"project-version\">0.2.5-SNAPSHOT</span></span></h1><h5 class=\"license\">Released under the <a href=\"http://www.eclipse.org/legal/epl-v10.html\">Eclipse Public License</a></h5><div class=\"doc\"><p>A Clojure library for generation and utilization of\n                UUIDs (Universally Unique Identifiers) as described by\n                RFC-9562. This library extends the standard Java\n                UUID class to provide true v1, v6, v7 (time based) and\n                v3/v5 (namespace based), and v8 (user customizable)\n                identifier generation. Additionally, a number of useful\n                utilities are provided to support serialization and\n                manipulation of these UUIDs in a simple, efficient\n                manner.</p></div><h2>Installation</h2><p>To install, add the following dependency to your project or build file:</p><pre class=\"deps\">[danlentz/clj-uuid \"0.2.5-SNAPSHOT\"]</pre><h2>Namespaces</h2><div class=\"namespace\"><h3><a href=\"clj-uuid.html\">clj-uuid</a></h3><div class=\"doc\"><pre class=\"plaintext\">RFC 9562 UUID implementation for Clojure.</pre></div><div class=\"index\"><p>Public variables and functions:</p><ul><li> <a href=\"clj-uuid.html#var-.2Bmax.2B\">+max+</a> </li><li> <a href=\"clj-uuid.html#var-.2Bnamespace-dns.2B\">+namespace-dns+</a> </li><li> <a href=\"clj-uuid.html#var-.2Bnamespace-oid.2B\">+namespace-oid+</a> </li><li> <a href=\"clj-uuid.html#var-.2Bnamespace-url.2B\">+namespace-url+</a> </li><li> <a href=\"clj-uuid.html#var-.2Bnamespace-x500.2B\">+namespace-x500+</a> </li><li> <a href=\"clj-uuid.html#var-.2Bnull.2B\">+null+</a> </li><li> <a href=\"clj-uuid.html#var-.3C\">&lt;</a> </li><li> <a href=\"clj-uuid.html#var-.3D\">=</a> </li><li> <a href=\"clj-uuid.html#var-.3E\">&gt;</a> </li><li> <a href=\"clj-uuid.html#var-as-byte-array\">as-byte-array</a> </li><li> <a href=\"clj-uuid.html#var-as-uuid\">as-uuid</a> </li><li> <a href=\"clj-uuid.html#var-get-clk-high\">get-clk-high</a> </li><li> <a href=\"clj-uuid.html#var-get-clk-low\">get-clk-low</a> </li><li> <a href=\"clj-uuid.html#var-get-clk-seq\">get-clk-seq</a> </li><li> <a href=\"clj-uuid.html#var-get-instant\">get-instant</a> </li><li> <a href=\"clj-uuid.html#var-get-node-id\">get-node-id</a> </li><li> <a href=\"clj-uuid.html#var-get-time-high\">get-time-high</a> </li><li> <a href=\"clj-uuid.html#var-get-time-low\">get-time-low</a> </li><li> <a href=\"clj-uuid.html#var-get-time-mid\">get-time-mid</a> </li><li> <a href=\"clj-uuid.html#var-get-timestamp\">get-timestamp</a> </li><li> <a href=\"clj-uuid.html#var-get-unix-time\">get-unix-time</a> </li><li> <a href=\"clj-uuid.html#var-get-variant\">get-variant</a> </li><li> <a href=\"clj-uuid.html#var-get-version\">get-version</a> </li><li> <a href=\"clj-uuid.html#var-get-word-high\">get-word-high</a> </li><li> <a href=\"clj-uuid.html#var-get-word-low\">get-word-low</a> </li><li> <a href=\"clj-uuid.html#var-hash-code\">hash-code</a> </li><li> <a href=\"clj-uuid.html#var-max\">max</a> </li><li> <a href=\"clj-uuid.html#var-max.3F\">max?</a> </li><li> <a href=\"clj-uuid.html#var-monotonic-time\">monotonic-time</a> </li><li> <a href=\"clj-uuid.html#var-null\">null</a> </li><li> <a href=\"clj-uuid.html#var-null.3F\">null?</a> </li><li> <a href=\"clj-uuid.html#var-squuid\">squuid</a> </li><li> <a href=\"clj-uuid.html#var-to-byte-array\">to-byte-array</a> </li><li> <a href=\"clj-uuid.html#var-to-hex-string\">to-hex-string</a> </li><li> <a href=\"clj-uuid.html#var-to-string\">to-string</a> </li><li> <a href=\"clj-uuid.html#var-to-uri\">to-uri</a> </li><li> <a href=\"clj-uuid.html#var-to-urn-string\">to-urn-string</a> </li><li> <a href=\"clj-uuid.html#var-uuid-string.3F\">uuid-string?</a> </li><li> <a href=\"clj-uuid.html#var-uuid-urn-string.3F\">uuid-urn-string?</a> </li><li> <a href=\"clj-uuid.html#var-uuid-vec.3F\">uuid-vec?</a> </li><li> <a href=\"clj-uuid.html#var-uuid.3C\">uuid&lt;</a> </li><li> <a href=\"clj-uuid.html#var-uuid.3D\">uuid=</a> </li><li> <a href=\"clj-uuid.html#var-uuid.3E\">uuid&gt;</a> </li><li> <a href=\"clj-uuid.html#var-uuid.3F\">uuid?</a> </li><li> <a href=\"clj-uuid.html#var-UUIDable\">UUIDable</a> </li><li> <a href=\"clj-uuid.html#var-uuidable.3F\">uuidable?</a> </li><li> <a href=\"clj-uuid.html#var-UUIDNameBytes\">UUIDNameBytes</a> </li><li> <a href=\"clj-uuid.html#var-UUIDRfc4122\">UUIDRfc4122</a> </li><li> <a href=\"clj-uuid.html#var-UUIDRfc9562\">UUIDRfc9562</a> </li><li> <a href=\"clj-uuid.html#var-v0\">v0</a> </li><li> <a href=\"clj-uuid.html#var-v1\">v1</a> </li><li> <a href=\"clj-uuid.html#var-v3\">v3</a> </li><li> <a href=\"clj-uuid.html#var-v4\">v4</a> </li><li> <a href=\"clj-uuid.html#var-v5\">v5</a> </li><li> <a href=\"clj-uuid.html#var-v6\">v6</a> </li><li> <a href=\"clj-uuid.html#var-v7\">v7</a> </li><li> <a href=\"clj-uuid.html#var-v7nc\">v7nc</a> </li><li> <a href=\"clj-uuid.html#var-v8\">v8</a> </li></ul></div></div><div class=\"namespace\"><h3><a href=\"clj-uuid.bitmop.html\">clj-uuid.bitmop</a></h3><div class=\"doc\"><pre class=\"plaintext\">Unsigned Long and ByteBuffer-based bitwise operation primitives for\nUUID manipulation.</pre></div><div class=\"index\"><p>Public variables and functions:</p><ul><li> <a href=\"clj-uuid.bitmop.html#var-assemble-bytes\">assemble-bytes</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-bit-count\">bit-count</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-buf-.3Ebytes\">buf-&gt;bytes</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-buf-.3Euuid\">buf-&gt;uuid</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-buf-compare\">buf-compare</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-buf-hex\">buf-hex</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-buf-str\">buf-str</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-buffer\">buffer</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-buffer-from-bytes\">buffer-from-bytes</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-bytes-.3Elong\">bytes-&gt;long</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-dpb\">dpb</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-dpb-buf\">dpb-buf</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-duplicate\">duplicate</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-expt2\">expt2</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-get-byte\">get-byte</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-get-int\">get-int</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-get-long\">get-long</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-get-lsb\">get-lsb</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-get-msb\">get-msb</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-get-short\">get-short</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-hex\">hex</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-hex-.3Ebuf\">hex-&gt;buf</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-ldb\">ldb</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-ldb-buf\">ldb-buf</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-long-.3Ebytes\">long-&gt;bytes</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-mask\">mask</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-mask-offset\">mask-offset</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-mask-width\">mask-width</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-octet-hex\">octet-hex</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-pphex\">pphex</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-put-byte\">put-byte</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-put-int\">put-int</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-put-long\">put-long</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-put-short\">put-short</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-sb16\">sb16</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-sb32\">sb32</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-sb64\">sb64</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-sb8\">sb8</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-set-lsb\">set-lsb</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-set-msb\">set-msb</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-ub16\">ub16</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-ub24\">ub24</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-ub32\">ub32</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-ub4\">ub4</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-ub48\">ub48</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-ub56\">ub56</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-ub8\">ub8</a> </li><li> <a href=\"clj-uuid.bitmop.html#var-uuid-.3Ebuf\">uuid-&gt;buf</a> </li></ul></div></div><div class=\"namespace\"><h3><a href=\"clj-uuid.clock.html\">clj-uuid.clock</a></h3><div class=\"doc\"><pre class=\"plaintext\">Lock-Free, Thread-safe Monotonic Clocks</pre></div><div class=\"index\"><p>Public variables and functions:</p><ul><li> <a href=\"clj-uuid.clock.html#var-.2Brandom-counter-resolution.2B\">+random-counter-resolution+</a> </li><li> <a href=\"clj-uuid.clock.html#var-.2Bsubcounter-resolution.2B\">+subcounter-resolution+</a> </li><li> <a href=\"clj-uuid.clock.html#var--gregorian-packed-\">-gregorian-packed-</a> </li><li> <a href=\"clj-uuid.clock.html#var-monotonic-time\">monotonic-time</a> </li><li> <a href=\"clj-uuid.clock.html#var-monotonic-unix-time-and-random-counter\">monotonic-unix-time-and-random-counter</a> </li><li> <a href=\"clj-uuid.clock.html#var-posix-time\">posix-time</a> </li><li> <a href=\"clj-uuid.clock.html#var-universal-time\">universal-time</a> </li></ul></div></div><div class=\"namespace\"><h3><a href=\"clj-uuid.constants.html\">clj-uuid.constants</a></h3><div class=\"doc\"><pre class=\"plaintext\"></pre></div><div class=\"index\"><p>Public variables and functions:</p><ul><li> <a href=\"clj-uuid.constants.html#var-.2Bhex-chars.2B\">+hex-chars+</a> </li><li> <a href=\"clj-uuid.constants.html#var-.2Bmd5.2B\">+md5+</a> </li><li> <a href=\"clj-uuid.constants.html#var-.2Bsha1.2B\">+sha1+</a> </li><li> <a href=\"clj-uuid.constants.html#var-.2Bub1-mask.2B\">+ub1-mask+</a> </li><li> <a href=\"clj-uuid.constants.html#var-.2Bub12-mask.2B\">+ub12-mask+</a> </li><li> <a href=\"clj-uuid.constants.html#var-.2Bub16-mask.2B\">+ub16-mask+</a> </li><li> <a href=\"clj-uuid.constants.html#var-.2Bub24-mask.2B\">+ub24-mask+</a> </li><li> <a href=\"clj-uuid.constants.html#var-.2Bub32-mask.2B\">+ub32-mask+</a> </li><li> <a href=\"clj-uuid.constants.html#var-.2Bub4-mask.2B\">+ub4-mask+</a> </li><li> <a href=\"clj-uuid.constants.html#var-.2Bub40-mask.2B\">+ub40-mask+</a> </li><li> <a href=\"clj-uuid.constants.html#var-.2Bub48-mask.2B\">+ub48-mask+</a> </li><li> <a href=\"clj-uuid.constants.html#var-.2Bub56-mask.2B\">+ub56-mask+</a> </li><li> <a href=\"clj-uuid.constants.html#var-.2Bub60-mask.2B\">+ub60-mask+</a> </li><li> <a href=\"clj-uuid.constants.html#var-.2Bub63-mask.2B\">+ub63-mask+</a> </li><li> <a href=\"clj-uuid.constants.html#var-.2Bub8-mask.2B\">+ub8-mask+</a> </li><li> <a href=\"clj-uuid.constants.html#var-hex-regex\">hex-regex</a> </li><li> <a href=\"clj-uuid.constants.html#var-urn-regex\">urn-regex</a> </li><li> <a href=\"clj-uuid.constants.html#var-uuid-regex\">uuid-regex</a> </li></ul></div></div><div class=\"namespace\"><h3><a href=\"clj-uuid.core.html\">clj-uuid.core</a></h3><div class=\"doc\"><pre class=\"plaintext\"></pre></div><div class=\"index\"><p>Public variables and functions:</p><ul><li> <a href=\"clj-uuid.core.html#var-.2Bmax.2B\">+max+</a> </li><li> <a href=\"clj-uuid.core.html#var-.2Bnamespace-dns.2B\">+namespace-dns+</a> </li><li> <a href=\"clj-uuid.core.html#var-.2Bnamespace-oid.2B\">+namespace-oid+</a> </li><li> <a href=\"clj-uuid.core.html#var-.2Bnamespace-url.2B\">+namespace-url+</a> </li><li> <a href=\"clj-uuid.core.html#var-.2Bnamespace-x500.2B\">+namespace-x500+</a> </li><li> <a href=\"clj-uuid.core.html#var-.2Bnull.2B\">+null+</a> </li><li> <a href=\"clj-uuid.core.html#var-.3C\">&lt;</a> </li><li> <a href=\"clj-uuid.core.html#var-.3D\">=</a> </li><li> <a href=\"clj-uuid.core.html#var-.3E\">&gt;</a> </li><li> <a href=\"clj-uuid.core.html#var-max\">max</a> </li><li> <a href=\"clj-uuid.core.html#var-monotonic-time\">monotonic-time</a> </li><li> <a href=\"clj-uuid.core.html#var-null\">null</a> </li><li> <a href=\"clj-uuid.core.html#var-squuid\">squuid</a> </li><li> <a href=\"clj-uuid.core.html#var-uuid-string.3F\">uuid-string?</a> </li><li> <a href=\"clj-uuid.core.html#var-uuid-urn-string.3F\">uuid-urn-string?</a> </li><li> <a href=\"clj-uuid.core.html#var-uuid-vec.3F\">uuid-vec?</a> </li><li> <a href=\"clj-uuid.core.html#var-UUIDable\">UUIDable</a> </li><li> <a href=\"clj-uuid.core.html#var-UUIDNameBytes\">UUIDNameBytes</a> </li><li> <a href=\"clj-uuid.core.html#var-UUIDRfc4122\">UUIDRfc4122</a> </li><li> <a href=\"clj-uuid.core.html#var-UUIDRfc9562\">UUIDRfc9562</a> </li><li> <a href=\"clj-uuid.core.html#var-v0\">v0</a> </li><li> <a href=\"clj-uuid.core.html#var-v1\">v1</a> </li><li> <a href=\"clj-uuid.core.html#var-v3\">v3</a> </li><li> <a href=\"clj-uuid.core.html#var-v4\">v4</a> </li><li> <a href=\"clj-uuid.core.html#var-v5\">v5</a> </li><li> <a href=\"clj-uuid.core.html#var-v6\">v6</a> </li><li> <a href=\"clj-uuid.core.html#var-v7\">v7</a> </li><li> <a href=\"clj-uuid.core.html#var-v7nc\">v7nc</a> </li><li> <a href=\"clj-uuid.core.html#var-v8\">v8</a> </li></ul></div></div><div class=\"namespace\"><h3><a href=\"clj-uuid.node.html\">clj-uuid.node</a></h3><div class=\"doc\"><pre class=\"plaintext\"></pre></div><div class=\"index\"><p>Public variables and functions:</p><ul><li> <a href=\"clj-uuid.node.html#var-.2Bclock-sequence.2B\">+clock-sequence+</a> </li><li> <a href=\"clj-uuid.node.html#var-.2Bnode-id.2B\">+node-id+</a> </li><li> <a href=\"clj-uuid.node.html#var-.2Bv1-lsb.2B\">+v1-lsb+</a> </li><li> <a href=\"clj-uuid.node.html#var-.2Bv6-lsb.2B\">+v6-lsb+</a> </li><li> <a href=\"clj-uuid.node.html#var-node-id\">node-id</a> </li></ul></div></div><div class=\"namespace\"><h3><a href=\"clj-uuid.random.html\">clj-uuid.random</a></h3><div class=\"doc\"><pre class=\"plaintext\"></pre></div><div class=\"index\"><p>Public variables and functions:</p><ul><li> <a href=\"clj-uuid.random.html#var-bytes\">bytes</a> </li><li> <a href=\"clj-uuid.random.html#var-eight-bits\">eight-bits</a> </li><li> <a href=\"clj-uuid.random.html#var-eleven-bits\">eleven-bits</a> </li><li> <a href=\"clj-uuid.random.html#var-long\">long</a> </li><li> <a href=\"clj-uuid.random.html#var-ten-bits\">ten-bits</a> </li><li> <a href=\"clj-uuid.random.html#var-twelve-bits\">twelve-bits</a> </li></ul></div></div><div class=\"namespace\"><h3><a href=\"clj-uuid.util.html\">clj-uuid.util</a></h3><div class=\"doc\"><pre class=\"plaintext\"></pre></div><div class=\"index\"><p>Public variables and functions:</p><ul><li> <a href=\"clj-uuid.util.html#var-compile-if\">compile-if</a> </li><li> <a href=\"clj-uuid.util.html#var-import-vars\">import-vars</a> </li><li> <a href=\"clj-uuid.util.html#var-java6.3F\">java6?</a> </li><li> <a href=\"clj-uuid.util.html#var-lines-of-file\">lines-of-file</a> </li><li> <a href=\"clj-uuid.util.html#var-returning\">returning</a> </li><li> <a href=\"clj-uuid.util.html#var-with-temp-file\">with-temp-file</a> </li><li> <a href=\"clj-uuid.util.html#var-with-timing\">with-timing</a> </li><li> <a href=\"clj-uuid.util.html#var-wrap-fn\">wrap-fn</a> </li></ul></div></div></div></body></html>"
  },
  {
    "path": "doc/api/js/page_effects.js",
    "content": "function visibleInParent(element) {\n    var position = $(element).position().top\n    return position > -50 && position < ($(element).offsetParent().height() - 50)\n}\n\nfunction hasFragment(link, fragment) {\n    return $(link).attr(\"href\").indexOf(\"#\" + fragment) != -1\n}\n\nfunction findLinkByFragment(elements, fragment) {\n    return $(elements).filter(function(i, e) { return hasFragment(e, fragment)}).first()\n}\n\nfunction scrollToCurrentVarLink(elements) {\n    var elements = $(elements);\n    var parent   = elements.offsetParent();\n\n    if (elements.length == 0) return;\n\n    var top    = elements.first().position().top;\n    var bottom = elements.last().position().top + elements.last().height();\n\n    if (top >= 0 && bottom <= parent.height()) return;\n\n    if (top < 0) {\n        parent.scrollTop(parent.scrollTop() + top);\n    }\n    else if (bottom > parent.height()) {\n        parent.scrollTop(parent.scrollTop() + bottom - parent.height());\n    }\n}\n\nfunction setCurrentVarLink() {\n    $('.secondary a').parent().removeClass('current')\n    $('.anchor').\n        filter(function(index) { return visibleInParent(this) }).\n        each(function(index, element) {\n            findLinkByFragment(\".secondary a\", element.id).\n                parent().\n                addClass('current')\n        });\n    scrollToCurrentVarLink('.secondary .current');\n}\n\nvar hasStorage = (function() { try { return localStorage.getItem } catch(e) {} }())\n\nfunction scrollPositionId(element) {\n    var directory = window.location.href.replace(/[^\\/]+\\.html$/, '')\n    return 'scroll::' + $(element).attr('id') + '::' + directory\n}\n\nfunction storeScrollPosition(element) {\n    if (!hasStorage) return;\n    localStorage.setItem(scrollPositionId(element) + \"::x\", $(element).scrollLeft())\n    localStorage.setItem(scrollPositionId(element) + \"::y\", $(element).scrollTop())\n}\n\nfunction recallScrollPosition(element) {\n    if (!hasStorage) return;\n    $(element).scrollLeft(localStorage.getItem(scrollPositionId(element) + \"::x\"))\n    $(element).scrollTop(localStorage.getItem(scrollPositionId(element) + \"::y\"))\n}\n\nfunction persistScrollPosition(element) {\n    recallScrollPosition(element)\n    $(element).scroll(function() { storeScrollPosition(element) })\n}\n\nfunction sidebarContentWidth(element) {\n    var widths = $(element).find('.inner').map(function() { return $(this).innerWidth() })\n    return Math.max.apply(Math, widths)\n}\n\nfunction calculateSize(width, snap, margin, minimum) {\n    if (width == 0) {\n        return 0\n    }\n    else {\n        return Math.max(minimum, (Math.ceil(width / snap) * snap) + (margin * 2))\n    }\n}\n\nfunction resizeSidebars() {\n    var primaryWidth   = sidebarContentWidth('.primary')\n    var secondaryWidth = 0\n\n    if ($('.secondary').length != 0) {\n        secondaryWidth = sidebarContentWidth('.secondary')\n    }\n\n    // snap to grid\n    primaryWidth   = calculateSize(primaryWidth, 32, 13, 160)\n    secondaryWidth = calculateSize(secondaryWidth, 32, 13, 160)\n\n    $('.primary').css('width', primaryWidth)\n    $('.secondary').css('width', secondaryWidth).css('left', primaryWidth + 1)\n\n    if (secondaryWidth > 0) {\n        $('#content').css('left', primaryWidth + secondaryWidth + 2)\n    }\n    else {\n        $('#content').css('left', primaryWidth + 1)\n    }\n}\n\n$(window).ready(resizeSidebars)\n$(window).ready(setCurrentVarLink)\n$(window).ready(function() { persistScrollPosition('.primary')})\n$(window).ready(function() {\n    $('#content').scroll(setCurrentVarLink)\n    $(window).resize(setCurrentVarLink)\n})\n"
  },
  {
    "path": "doc/apples.md",
    "content": "# Comparative Benchmarks: clj-uuid vs JUG vs uuid-creator vs JDK\n\nApples-to-apples performance comparison of UUID generation across\nfour JVM implementations, measured on the same machine in the same\nJVM process.\n\n## Libraries\n\n| Library | Version | Coordinates |\n|---|---|---|\n| **clj-uuid** | 0.2.5-SNAPSHOT | `danlentz/clj-uuid` |\n| **JUG** (FasterXML) | 5.2.0 | `com.fasterxml.uuid/java-uuid-generator` |\n| **uuid-creator** (f4b6a3) | 6.1.1 | `com.github.f4b6a3/uuid-creator` |\n| **JDK** | OpenJDK 25.0.1 | `java.util.UUID` (built-in) |\n\n## Environment\n\n- **CPU:** Intel Core i9-9880H @ 2.30 GHz (8 cores / 16 threads)\n- **RAM:** 32 GB\n- **OS:** macOS (Darwin 25.2.0, x86_64)\n- **JVM:** OpenJDK 25.0.1 (Homebrew, mixed mode, sharing)\n- **Clojure:** 1.12.0\n\n## Method\n\n500,000 iterations per benchmark after a 50,000 iteration JIT warmup.\nEach cell is the average ns/op.  Source: `test/clj_uuid/compare_bench.clj`.\n\n## Results\n\n| Operation          | clj-uuid (ns) | JUG 5.2 (ns) | uuid-creator (ns) | JDK (ns) |\n|--------------------|---------------:|--------------:|-------------------:|---------:|\n| v1 (time-based)    |          100.1 |          58.6 |               72.1 |       -- |\n| v4 (random)        |          340.9 |         340.9 |              369.1 |    338.1 |\n| v5 (SHA1)          |          260.5 |         253.8 |              301.9 |       -- |\n| v6 (time-ordered)  |          100.0 |          46.4 |               54.9 |       -- |\n| v7 (unix epoch)    |          333.2 |          51.1 |              272.2 |       -- |\n| v7nc (fast epoch)  |           39.4 |          49.6 |                 -- |       -- |\n| to-string          |           18.8 |            -- |                 -- |     14.4 |\n| to-byte-array      |           13.7 |            -- |                 -- |       -- |\n\n## Analysis\n\n### v4 (random)\n\nAll four implementations cluster between 338-370 ns.  The dominant\ncost is `SecureRandom.nextLong()`, which is common to all of them.\nclj-uuid delegates directly to `java.util.UUID/randomUUID` and is\neffectively at parity with the JDK.\n\n### v1 (time-based)\n\nclj-uuid is **1.7x** slower than JUG.  JUG uses raw `System.currentTimeMillis()`\nwith an internal synchronized counter.  clj-uuid uses an `AtomicLong`\nCAS-based monotonic clock that computes a Gregorian-epoch 100 ns\ntimestamp with inlined bit-field packing.  The remaining gap is\nClojure `defn` dispatch overhead and Gregorian epoch arithmetic.\n\n### v5 (SHA1, name-based)\n\nclj-uuid is **1.03x** slower than JUG -- effectively at parity.\nBoth use `ThreadLocal<MessageDigest>`.  The fused ByteBuffer\nimplementation eliminated intermediate allocations and var lookups\nin the digest pipeline, closing the gap that previously existed.\n\n### v6 (time-ordered)\n\nclj-uuid is **2.2x** slower than JUG.  Same clock as v1, with different\nbit-field ordering for lexical sorting.  The gap is wider than v1 because\nJUG's v6 is exceptionally fast (46 ns), leaving Clojure `defn` dispatch\nand Gregorian arithmetic as a proportionally larger overhead.\n\n### v7 (unix epoch, CSPRNG)\n\nclj-uuid `v7` is **6.5x** slower than JUG.  This reflects a **design\nchoice, not a deficiency**.  The v7 UUID layout includes a 62-bit\nrandom field (`rand_b`).  The libraries differ in how they fill it:\n\n| Library | rand_b source | Cost |\n|---|---|---|\n| **JUG** | Monotonic counter (no per-call randomness) | ~0 ns |\n| **uuid-creator** | `SecureRandom` | ~280 ns |\n| **clj-uuid v7** | `SecureRandom` | ~280 ns |\n\nRFC 9562 Section 6.9 (\"Unguessability\") recommends that\nimplementations \"utilize a cryptographically secure pseudorandom\nnumber generator (CSPRNG) to provide values that are both difficult\nto predict (unguessable) and have a low likelihood of collision.\"\n\nclj-uuid `v7` and uuid-creator follow the RFC recommendation by\ncalling `SecureRandom` on every generation, paying ~280 ns for\nthe CSPRNG call.\n\n### v7nc (fast epoch, ThreadLocalRandom) -- fastest v7\n\nclj-uuid `v7nc` is **1.26x faster** than JUG (39.4 ns vs 49.6 ns).\n\n`v7nc` uses `ThreadLocalRandom` instead of `SecureRandom` and a\nper-thread monotonic counter instead of a global `AtomicLong`.\nThe per-thread design eliminates CAS contention entirely, and the\nhot path (same millisecond) requires no random number generation --\njust an increment and a UUID constructor call.\n\nThis is the appropriate choice for applications that prioritize\nthroughput over cryptographic unguessability of the random portion.\n\n### to-string\n\nclj-uuid calls `java.util.UUID.toString()` directly.  The ~4 ns\noverhead versus the JDK measurement is Clojure protocol dispatch.\n\n## Summary\n\nclj-uuid is at parity with JUG for v4 (random) and v5 (SHA1)\ngeneration, and **faster** than JUG for non-cryptographic v7\ngeneration via `v7nc`.  JUG is faster for time-based v1 and v6\ngeneration due to pure-Java code paths with no Clojure dispatch\noverhead.\n\n| Category | vs JUG |\n|---|---|\n| v7nc (fast epoch) | **1.26x faster** |\n| v4 (random) | ~1.0x (parity) |\n| v5 (SHA1) | ~1.0x (parity) |\n| v1 (time-based) | 1.7x slower |\n| v6 (time-ordered) | 2.2x slower |\n| v7 (CSPRNG) | 6.5x slower (by design) |\n\nclj-uuid provides both `v7` (CSPRNG, RFC 6.9 compliant) and `v7nc`\n(ThreadLocalRandom, maximum throughput), letting applications choose\nthe appropriate tradeoff.\n"
  },
  {
    "path": "doc/draft-peabody-dispatch-new-uuid-format-04.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\" class=\"Internet-Draft\">\n<head>\n<meta charset=\"utf-8\">\n<meta content=\"Common,Latin\" name=\"scripts\">\n<meta content=\"initial-scale=1.0\" name=\"viewport\">\n<title>New UUID Formats</title>\n<meta content=\"Brad G. Peabody\" name=\"author\">\n<meta content=\"Kyzer R. Davis\" name=\"author\">\n<meta content=\"\n       \n This document presents new Universally Unique Identifier (UUID) formats for use in modern applications and databases.\n       \n    \" name=\"description\">\n<meta content=\"xml2rfc 3.12.10\" name=\"generator\">\n<meta content=\"uuid\" name=\"keyword\">\n<meta content=\"draft-peabody-dispatch-new-uuid-format-04\" name=\"ietf.draft\">\n<!-- Generator version information:\n  xml2rfc 3.12.10\n    Python 3.9.10\n    appdirs 1.4.4\n    ConfigArgParse 1.5.3\n    google-i18n-address 2.5.1\n    html5lib 1.1\n    intervaltree 3.1.0\n    Jinja2 2.11.3\n    kitchen 1.2.6\n    lxml 4.9.0\n    MarkupSafe 2.0.1\n    pycountry 22.3.5\n    pyflakes 2.4.0\n    PyYAML 6.0\n    requests 2.28.0\n    setuptools 62.4.0\n    six 1.16.0\n    WeasyPrint 52.5\n-->\n<link href=\"/tmp/draft-peabody-dispatch-new-uuid-format-04-tifrsxst.xml\" rel=\"alternate\" type=\"application/rfc+xml\">\n<link href=\"#copyright\" rel=\"license\">\n<style type=\"text/css\">/*\n\n  NOTE: Changes at the bottom of this file overrides some earlier settings.\n\n  Once the style has stabilized and has been adopted as an official RFC style,\n  this can be consolidated so that style settings occur only in one place, but\n  for now the contents of this file consists first of the initial CSS work as\n  provided to the RFC Formatter (xml2rfc) work, followed by itemized and\n  commented changes found necssary during the development of the v3\n  formatters.\n\n*/\n\n/* fonts */\n@import url('https://fonts.googleapis.com/css?family=Noto+Sans'); /* Sans-serif */\n@import url('https://fonts.googleapis.com/css?family=Noto+Serif'); /* Serif (print) */\n@import url('https://fonts.googleapis.com/css?family=Roboto+Mono'); /* Monospace */\n\n@viewport {\n  zoom: 1.0;\n  width: extend-to-zoom;\n}\n@-ms-viewport {\n  width: extend-to-zoom;\n  zoom: 1.0;\n}\n/* general and mobile first */\nhtml {\n}\nbody {\n  max-width: 90%;\n  margin: 1.5em auto;\n  color: #222;\n  background-color: #fff;\n  font-size: 14px;\n  font-family: 'Noto Sans', Arial, Helvetica, sans-serif;\n  line-height: 1.6;\n  scroll-behavior: smooth;\n}\n.ears {\n  display: none;\n}\n\n/* headings */\n#title, h1, h2, h3, h4, h5, h6 {\n  margin: 1em 0 0.5em;\n  font-weight: bold;\n  line-height: 1.3;\n}\n#title {\n  clear: both;\n  border-bottom: 1px solid #ddd;\n  margin: 0 0 0.5em 0;\n  padding: 1em 0 0.5em;\n}\n.author {\n  padding-bottom: 4px;\n}\nh1 {\n  font-size: 26px;\n  margin: 1em 0;\n}\nh2 {\n  font-size: 22px;\n  margin-top: -20px;  /* provide offset for in-page anchors */\n  padding-top: 33px;\n}\nh3 {\n  font-size: 18px;\n  margin-top: -36px;  /* provide offset for in-page anchors */\n  padding-top: 42px;\n}\nh4 {\n  font-size: 16px;\n  margin-top: -36px;  /* provide offset for in-page anchors */\n  padding-top: 42px;\n}\nh5, h6 {\n  font-size: 14px;\n}\n#n-copyright-notice {\n  border-bottom: 1px solid #ddd;\n  padding-bottom: 1em;\n  margin-bottom: 1em;\n}\n/* general structure */\np {\n  padding: 0;\n  margin: 0 0 1em 0;\n  text-align: left;\n}\ndiv, span {\n  position: relative;\n}\ndiv {\n  margin: 0;\n}\n.alignRight.art-text {\n  background-color: #f9f9f9;\n  border: 1px solid #eee;\n  border-radius: 3px;\n  padding: 1em 1em 0;\n  margin-bottom: 1.5em;\n}\n.alignRight.art-text pre {\n  padding: 0;\n}\n.alignRight {\n  margin: 1em 0;\n}\n.alignRight > *:first-child {\n  border: none;\n  margin: 0;\n  float: right;\n  clear: both;\n}\n.alignRight > *:nth-child(2) {\n  clear: both;\n  display: block;\n  border: none;\n}\nsvg {\n  display: block;\n}\n.alignCenter.art-text {\n  background-color: #f9f9f9;\n  border: 1px solid #eee;\n  border-radius: 3px;\n  padding: 1em 1em 0;\n  margin-bottom: 1.5em;\n}\n.alignCenter.art-text pre {\n  padding: 0;\n}\n.alignCenter {\n  margin: 1em 0;\n}\n.alignCenter > *:first-child {\n  border: none;\n  margin: 0 auto;\n}\n\n/* lists */\nol, ul {\n  padding: 0;\n  margin: 0 0 1em 2em;\n}\nol ol, ul ul, ol ul, ul ol {\n  margin-left: 1em;\n}\nli {\n  margin: 0 0 0.25em 0;\n}\n.ulCompact li {\n  margin: 0;\n}\nul.empty, .ulEmpty {\n  list-style-type: none;\n}\nul.empty li, .ulEmpty li {\n  margin-top: 0.5em;\n}\nul.ulBare, li.ulBare {\n  margin-left: 0em !important;\n}\nul.compact, .ulCompact,\nol.compact, .olCompact {\n  line-height: 100%;\n  margin: 0 0 0 2em;\n}\n\n/* definition lists */\ndl {\n}\ndl > dt {\n  float: left;\n  margin-right: 1em;\n}\n/* \ndl.nohang > dt {\n  float: none;\n}\n*/\ndl > dd {\n  margin-bottom: .8em;\n  min-height: 1.3em;\n}\ndl.compact > dd, .dlCompact > dd {\n  margin-bottom: 0em;\n}\ndl > dd > dl {\n  margin-top: 0.5em;\n  margin-bottom: 0em;\n}\n\n/* links */\na {\n  text-decoration: none;\n}\na[href] {\n  color: #22e; /* Arlen: WCAG 2019 */\n}\na[href]:hover {\n  background-color: #f2f2f2;\n}\nfigcaption a[href],\na[href].selfRef {\n  color: #222;\n}\n/* XXX probably not this:\na.selfRef:hover {\n  background-color: transparent;\n  cursor: default;\n} */\n\n/* Figures */\ntt, code, pre, code {\n  background-color: #f9f9f9;\n  font-family: 'Roboto Mono', monospace;\n}\npre {\n  border: 1px solid #eee;\n  margin: 0;\n  padding: 1em;\n}\nimg {\n  max-width: 100%;\n}\nfigure {\n  margin: 0;\n}\nfigure blockquote {\n  margin: 0.8em 0.4em 0.4em;\n}\nfigcaption {\n  font-style: italic;\n  margin: 0 0 1em 0;\n}\n@media screen {\n  pre {\n    overflow-x: auto;\n    max-width: 100%;\n    max-width: calc(100% - 22px);\n  }\n}\n\n/* aside, blockquote */\naside, blockquote {\n  margin-left: 0;\n  padding: 1.2em 2em;\n}\nblockquote {\n  background-color: #f9f9f9;\n  color: #111; /* Arlen: WCAG 2019 */\n  border: 1px solid #ddd;\n  border-radius: 3px;\n  margin: 1em 0;\n}\ncite {\n  display: block;\n  text-align: right;\n  font-style: italic;\n}\n\n/* tables */\ntable {\n  width: 100%;\n  margin: 0 0 1em;\n  border-collapse: collapse;\n  border: 1px solid #eee;\n}\nth, td {\n  text-align: left;\n  vertical-align: top;\n  padding: 0.5em 0.75em;\n}\nth {\n  text-align: left;\n  background-color: #e9e9e9;\n}\ntr:nth-child(2n+1) > td {\n  background-color: #f5f5f5;\n}\ntable caption {\n  font-style: italic;\n  margin: 0;\n  padding: 0;\n  text-align: left;\n}\ntable p {\n  /* XXX to avoid bottom margin on table row signifiers. If paragraphs should\n     be allowed within tables more generally, it would be far better to select on a class. */\n  margin: 0;\n}\n\n/* pilcrow */\na.pilcrow {\n  color: #666; /* Arlen: AHDJ 2019 */\n  text-decoration: none;\n  visibility: hidden;\n  user-select: none;\n  -ms-user-select: none;\n  -o-user-select:none;\n  -moz-user-select: none;\n  -khtml-user-select: none;\n  -webkit-user-select: none;\n  -webkit-touch-callout: none;\n}\n@media screen {\n  aside:hover > a.pilcrow,\n  p:hover > a.pilcrow,\n  blockquote:hover > a.pilcrow,\n  div:hover > a.pilcrow,\n  li:hover > a.pilcrow,\n  pre:hover > a.pilcrow {\n    visibility: visible;\n  }\n  a.pilcrow:hover {\n    background-color: transparent;\n  }\n}\n\n/* misc */\nhr {\n  border: 0;\n  border-top: 1px solid #eee;\n}\n.bcp14 {\n  font-variant: small-caps;\n}\n\n.role {\n  font-variant: all-small-caps;\n}\n\n/* info block */\n#identifiers {\n  margin: 0;\n  font-size: 0.9em;\n}\n#identifiers dt {\n  width: 3em;\n  clear: left;\n}\n#identifiers dd {\n  float: left;\n  margin-bottom: 0;\n}\n/* Fix PDF info block run off issue */\n@media print {\n  #identifiers dd {\n    float: none;\n  }\n}\n#identifiers .authors .author {\n  display: inline-block;\n  margin-right: 1.5em;\n}\n#identifiers .authors .org {\n  font-style: italic;\n}\n\n/* The prepared/rendered info at the very bottom of the page */\n.docInfo {\n  color: #666; /* Arlen: WCAG 2019 */\n  font-size: 0.9em;\n  font-style: italic;\n  margin-top: 2em;\n}\n.docInfo .prepared {\n  float: left;\n}\n.docInfo .prepared {\n  float: right;\n}\n\n/* table of contents */\n#toc  {\n  padding: 0.75em 0 2em 0;\n  margin-bottom: 1em;\n}\nnav.toc ul {\n  margin: 0 0.5em 0 0;\n  padding: 0;\n  list-style: none;\n}\nnav.toc li {\n  line-height: 1.3em;\n  margin: 0.75em 0;\n  padding-left: 1.2em;\n  text-indent: -1.2em;\n}\n/* references */\n.references dt {\n  text-align: right;\n  font-weight: bold;\n  min-width: 7em;\n}\n.references dd {\n  margin-left: 8em;\n  overflow: auto;\n}\n\n.refInstance {\n  margin-bottom: 1.25em;\n}\n\n.references .ascii {\n  margin-bottom: 0.25em;\n}\n\n/* index */\n.index ul {\n  margin: 0 0 0 1em;\n  padding: 0;\n  list-style: none;\n}\n.index ul ul {\n  margin: 0;\n}\n.index li {\n  margin: 0;\n  text-indent: -2em;\n  padding-left: 2em;\n  padding-bottom: 5px;\n}\n.indexIndex {\n  margin: 0.5em 0 1em;\n}\n.index a {\n  font-weight: 700;\n}\n/* make the index two-column on all but the smallest screens */\n@media (min-width: 600px) {\n  .index ul {\n    -moz-column-count: 2;\n    -moz-column-gap: 20px;\n  }\n  .index ul ul {\n    -moz-column-count: 1;\n    -moz-column-gap: 0;\n  }\n}\n\n/* authors */\naddress.vcard {\n  font-style: normal;\n  margin: 1em 0;\n}\n\naddress.vcard .nameRole {\n  font-weight: 700;\n  margin-left: 0;\n}\naddress.vcard .label {\n  font-family: \"Noto Sans\",Arial,Helvetica,sans-serif;\n  margin: 0.5em 0;\n}\naddress.vcard .type {\n  display: none;\n}\n.alternative-contact {\n  margin: 1.5em 0 1em;\n}\nhr.addr {\n  border-top: 1px dashed;\n  margin: 0;\n  color: #ddd;\n  max-width: calc(100% - 16px);\n}\n\n/* temporary notes */\n.rfcEditorRemove::before {\n  position: absolute;\n  top: 0.2em;\n  right: 0.2em;\n  padding: 0.2em;\n  content: \"The RFC Editor will remove this note\";\n  color: #9e2a00; /* Arlen: WCAG 2019 */\n  background-color: #ffd; /* Arlen: WCAG 2019 */\n}\n.rfcEditorRemove {\n  position: relative;\n  padding-top: 1.8em;\n  background-color: #ffd; /* Arlen: WCAG 2019 */\n  border-radius: 3px;\n}\n.cref {\n  background-color: #ffd; /* Arlen: WCAG 2019 */\n  padding: 2px 4px;\n}\n.crefSource {\n  font-style: italic;\n}\n/* alternative layout for smaller screens */\n@media screen and (max-width: 1023px) {\n  body {\n    padding-top: 2em;\n  }\n  #title {\n    padding: 1em 0;\n  }\n  h1 {\n    font-size: 24px;\n  }\n  h2 {\n    font-size: 20px;\n    margin-top: -18px;  /* provide offset for in-page anchors */\n    padding-top: 38px;\n  }\n  #identifiers dd {\n    max-width: 60%;\n  }\n  #toc {\n    position: fixed;\n    z-index: 2;\n    top: 0;\n    right: 0;\n    padding: 0;\n    margin: 0;\n    background-color: inherit;\n    border-bottom: 1px solid #ccc;\n  }\n  #toc h2 {\n    margin: -1px 0 0 0;\n    padding: 4px 0 4px 6px;\n    padding-right: 1em;\n    min-width: 190px;\n    font-size: 1.1em;\n    text-align: right;\n    background-color: #444;\n    color: white;\n    cursor: pointer;\n  }\n  #toc h2::before { /* css hamburger */\n    float: right;\n    position: relative;\n    width: 1em;\n    height: 1px;\n    left: -164px;\n    margin: 6px 0 0 0;\n    background: white none repeat scroll 0 0;\n    box-shadow: 0 4px 0 0 white, 0 8px 0 0 white;\n    content: \"\";\n  }\n  #toc nav {\n    display: none;\n    padding: 0.5em 1em 1em;\n    overflow: auto;\n    height: calc(100vh - 48px);\n    border-left: 1px solid #ddd;\n  }\n}\n\n/* alternative layout for wide screens */\n@media screen and (min-width: 1024px) {\n  body {\n    max-width: 724px;\n    margin: 42px auto;\n    padding-left: 1.5em;\n    padding-right: 29em;\n  }\n  #toc {\n    position: fixed;\n    top: 42px;\n    right: 42px;\n    width: 25%;\n    margin: 0;\n    padding: 0 1em;\n    z-index: 1;\n  }\n  #toc h2 {\n    border-top: none;\n    border-bottom: 1px solid #ddd;\n    font-size: 1em;\n    font-weight: normal;\n    margin: 0;\n    padding: 0.25em 1em 1em 0;\n  }\n  #toc nav {\n    display: block;\n    height: calc(90vh - 84px);\n    bottom: 0;\n    padding: 0.5em 0 0;\n    overflow: auto;\n  }\n  img { /* future proofing */\n    max-width: 100%;\n    height: auto;\n  }\n}\n\n/* pagination */\n@media print {\n  body {\n\n    width: 100%;\n  }\n  p {\n    orphans: 3;\n    widows: 3;\n  }\n  #n-copyright-notice {\n    border-bottom: none;\n  }\n  #toc, #n-introduction {\n    page-break-before: always;\n  }\n  #toc {\n    border-top: none;\n    padding-top: 0;\n  }\n  figure, pre {\n    page-break-inside: avoid;\n  }\n  figure {\n    overflow: scroll;\n  }\n  pre.breakable {\n    break-inside: auto;\n  }\n  h1, h2, h3, h4, h5, h6 {\n    page-break-after: avoid;\n  }\n  h2+*, h3+*, h4+*, h5+*, h6+* {\n    page-break-before: avoid;\n  }\n  pre {\n    white-space: pre-wrap;\n    word-wrap: break-word;\n    font-size: 10pt;\n  }\n  table {\n    border: 1px solid #ddd;\n  }\n  td {\n    border-top: 1px solid #ddd;\n  }\n}\n\n/* This is commented out here, as the string-set: doesn't\n   pass W3C validation currently */\n/*\n.ears thead .left {\n  string-set: ears-top-left content();\n}\n\n.ears thead .center {\n  string-set: ears-top-center content();\n}\n\n.ears thead .right {\n  string-set: ears-top-right content();\n}\n\n.ears tfoot .left {\n  string-set: ears-bottom-left content();\n}\n\n.ears tfoot .center {\n  string-set: ears-bottom-center content();\n}\n\n.ears tfoot .right {\n  string-set: ears-bottom-right content();\n}\n*/\n\n@page :first {\n  padding-top: 0;\n  @top-left {\n    content: normal;\n    border: none;\n  }\n  @top-center {\n    content: normal;\n    border: none;\n  }\n  @top-right {\n    content: normal;\n    border: none;\n  }\n}\n\n@page {\n  size: A4;\n  margin-bottom: 45mm;\n  padding-top: 20px;\n  /* The follwing is commented out here, but set appropriately by in code, as\n     the content depends on the document */\n  /*\n  @top-left {\n    content: 'Internet-Draft';\n    vertical-align: bottom;\n    border-bottom: solid 1px #ccc;\n  }\n  @top-left {\n    content: string(ears-top-left);\n    vertical-align: bottom;\n    border-bottom: solid 1px #ccc;\n  }\n  @top-center {\n    content: string(ears-top-center);\n    vertical-align: bottom;\n    border-bottom: solid 1px #ccc;\n  }\n  @top-right {\n    content: string(ears-top-right);\n    vertical-align: bottom;\n    border-bottom: solid 1px #ccc;\n  }\n  @bottom-left {\n    content: string(ears-bottom-left);\n    vertical-align: top;\n    border-top: solid 1px #ccc;\n  }\n  @bottom-center {\n    content: string(ears-bottom-center);\n    vertical-align: top;\n    border-top: solid 1px #ccc;\n  }\n  @bottom-right {\n      content: '[Page ' counter(page) ']';\n      vertical-align: top;\n      border-top: solid 1px #ccc;\n  }\n  */\n\n}\n\n/* Changes introduced to fix issues found during implementation */\n/* Make sure links are clickable even if overlapped by following H* */\na {\n  z-index: 2;\n}\n/* Separate body from document info even without intervening H1 */\nsection {\n  clear: both;\n}\n\n\n/* Top align author divs, to avoid names without organization dropping level with org names */\n.author {\n  vertical-align: top;\n}\n\n/* Leave room in document info to show Internet-Draft on one line */\n#identifiers dt {\n  width: 8em;\n}\n\n/* Don't waste quite as much whitespace between label and value in doc info */\n#identifiers dd {\n  margin-left: 1em;\n}\n\n/* Give floating toc a background color (needed when it's a div inside section */\n#toc {\n  background-color: white;\n}\n\n/* Make the collapsed ToC header render white on gray also when it's a link */\n@media screen and (max-width: 1023px) {\n  #toc h2 a,\n  #toc h2 a:link,\n  #toc h2 a:focus,\n  #toc h2 a:hover,\n  #toc a.toplink,\n  #toc a.toplink:hover {\n    color: white;\n    background-color: #444;\n    text-decoration: none;\n  }\n}\n\n/* Give the bottom of the ToC some whitespace */\n@media screen and (min-width: 1024px) {\n  #toc {\n    padding: 0 0 1em 1em;\n  }\n}\n\n/* Style section numbers with more space between number and title */\n.section-number {\n  padding-right: 0.5em;\n}\n\n/* prevent monospace from becoming overly large */\ntt, code, pre, code {\n  font-size: 95%;\n}\n\n/* Fix the height/width aspect for ascii art*/\npre.sourcecode,\n.art-text pre {\n  line-height: 1.12;\n}\n\n\n/* Add styling for a link in the ToC that points to the top of the document */\na.toplink {\n  float: right;\n  margin-right: 0.5em;\n}\n\n/* Fix the dl styling to match the RFC 7992 attributes */\ndl > dt,\ndl.dlParallel > dt {\n  float: left;\n  margin-right: 1em;\n}\ndl.dlNewline > dt {\n  float: none;\n}\n\n/* Provide styling for table cell text alignment */\ntable td.text-left,\ntable th.text-left {\n  text-align: left;\n}\ntable td.text-center,\ntable th.text-center {\n  text-align: center;\n}\ntable td.text-right,\ntable th.text-right {\n  text-align: right;\n}\n\n/* Make the alternative author contact informatio look less like just another\n   author, and group it closer with the primary author contact information */\n.alternative-contact {\n  margin: 0.5em 0 0.25em 0;\n}\naddress .non-ascii {\n  margin: 0 0 0 2em;\n}\n\n/* With it being possible to set tables with alignment\n  left, center, and right, { width: 100%; } does not make sense */\ntable {\n  width: auto;\n}\n\n/* Avoid reference text that sits in a block with very wide left margin,\n   because of a long floating dt label.*/\n.references dd {\n  overflow: visible;\n}\n\n/* Control caption placement */\ncaption {\n  caption-side: bottom;\n}\n\n/* Limit the width of the author address vcard, so names in right-to-left\n   script don't end up on the other side of the page. */\n\naddress.vcard {\n  max-width: 30em;\n  margin-right: auto;\n}\n\n/* For address alignment dependent on LTR or RTL scripts */\naddress div.left {\n  text-align: left;\n}\naddress div.right {\n  text-align: right;\n}\n\n/* Provide table alignment support.  We can't use the alignX classes above\n   since they do unwanted things with caption and other styling. */\ntable.right {\n margin-left: auto;\n margin-right: 0;\n}\ntable.center {\n margin-left: auto;\n margin-right: auto;\n}\ntable.left {\n margin-left: 0;\n margin-right: auto;\n}\n\n/* Give the table caption label the same styling as the figcaption */\ncaption a[href] {\n  color: #222;\n}\n\n@media print {\n  .toplink {\n    display: none;\n  }\n\n  /* avoid overwriting the top border line with the ToC header */\n  #toc {\n    padding-top: 1px;\n  }\n\n  /* Avoid page breaks inside dl and author address entries */\n  .vcard {\n    page-break-inside: avoid;\n  }\n\n}\n/* Tweak the bcp14 keyword presentation */\n.bcp14 {\n  font-variant: small-caps;\n  font-weight: bold;\n  font-size: 0.9em;\n}\n/* Tweak the invisible space above H* in order not to overlay links in text above */\n h2 {\n  margin-top: -18px;  /* provide offset for in-page anchors */\n  padding-top: 31px;\n }\n h3 {\n  margin-top: -18px;  /* provide offset for in-page anchors */\n  padding-top: 24px;\n }\n h4 {\n  margin-top: -18px;  /* provide offset for in-page anchors */\n  padding-top: 24px;\n }\n/* Float artwork pilcrow to the right */\n@media screen {\n  .artwork a.pilcrow {\n    display: block;\n    line-height: 0.7;\n    margin-top: 0.15em;\n  }\n}\n/* Make pilcrows on dd visible */\n@media screen {\n  dd:hover > a.pilcrow {\n    visibility: visible;\n  }\n}\n/* Make the placement of figcaption match that of a table's caption\n   by removing the figure's added bottom margin */\n.alignLeft.art-text,\n.alignCenter.art-text,\n.alignRight.art-text {\n   margin-bottom: 0;\n}\n.alignLeft,\n.alignCenter,\n.alignRight {\n  margin: 1em 0 0 0;\n}\n/* In print, the pilcrow won't show on hover, so prevent it from taking up space,\n   possibly even requiring a new line */\n@media print {\n  a.pilcrow {\n    display: none;\n  }\n}\n/* Styling for the external metadata */\ndiv#external-metadata {\n  background-color: #eee;\n  padding: 0.5em;\n  margin-bottom: 0.5em;\n  display: none;\n}\ndiv#internal-metadata {\n  padding: 0.5em;                       /* to match the external-metadata padding */\n}\n/* Styling for title RFC Number */\nh1#rfcnum {\n  clear: both;\n  margin: 0 0 -1em;\n  padding: 1em 0 0 0;\n}\n/* Make .olPercent look the same as <ol><li> */\ndl.olPercent > dd {\n  margin-bottom: 0.25em;\n  min-height: initial;\n}\n/* Give aside some styling to set it apart */\naside {\n  border-left: 1px solid #ddd;\n  margin: 1em 0 1em 2em;\n  padding: 0.2em 2em;\n}\naside > dl,\naside > ol,\naside > ul,\naside > table,\naside > p {\n  margin-bottom: 0.5em;\n}\n/* Additional page break settings */\n@media print {\n  figcaption, table caption {\n    page-break-before: avoid;\n  }\n}\n/* Font size adjustments for print */\n@media print {\n  body  { font-size: 10pt;      line-height: normal; max-width: 96%; }\n  h1    { font-size: 1.72em;    padding-top: 1.5em; } /* 1*1.2*1.2*1.2 */\n  h2    { font-size: 1.44em;    padding-top: 1.5em; } /* 1*1.2*1.2 */\n  h3    { font-size: 1.2em;     padding-top: 1.5em; } /* 1*1.2 */\n  h4    { font-size: 1em;       padding-top: 1.5em; }\n  h5, h6 { font-size: 1em;      margin: initial; padding: 0.5em 0 0.3em; }\n}\n/* Sourcecode margin in print, when there's no pilcrow */\n@media print {\n  .artwork,\n  .sourcecode {\n    margin-bottom: 1em;\n  }\n}\n/* Avoid narrow tables forcing too narrow table captions, which may render badly */\ntable {\n  min-width: 20em;\n}\n/* ol type a */\nol.type-a { list-style-type: lower-alpha; }\nol.type-A { list-style-type: upper-alpha; }\nol.type-i { list-style-type: lower-roman; }\nol.type-I { list-style-type: lower-roman; }\n/* Apply the print table and row borders in general, on request from the RPC,\nand increase the contrast between border and odd row background sligthtly */\ntable {\n  border: 1px solid #ddd;\n}\ntd {\n  border-top: 1px solid #ddd;\n}\ntr:nth-child(2n+1) > td {\n  background-color: #f8f8f8;\n}\n/* Use style rules to govern display of the TOC. */\n@media screen and (max-width: 1023px) {\n  #toc nav { display: none; }\n  #toc.active nav { display: block; }\n}\n/* Add support for keepWithNext */\n.keepWithNext {\n  break-after: avoid-page;\n  break-after: avoid-page;\n}\n/* Add support for keepWithPrevious */\n.keepWithPrevious {\n  break-before: avoid-page;\n}\n/* Change the approach to avoiding breaks inside artwork etc. */\nfigure, pre, table, .artwork, .sourcecode  {\n  break-before: auto;\n  break-after: auto;\n}\n/* Avoid breaks between <dt> and <dd> */\ndl {\n  break-before: auto;\n  break-inside: auto;\n}\ndt {\n  break-before: auto;\n  break-after: avoid-page;\n}\ndd {\n  break-before: avoid-page;\n  break-after: auto;\n  orphans: 3;\n  widows: 3\n}\nspan.break, dd.break {\n  margin-bottom: 0;\n  min-height: 0;\n  break-before: auto;\n  break-inside: auto;\n  break-after: auto;\n}\n/* Undo break-before ToC */\n@media print {\n  #toc {\n    break-before: auto;\n  }\n}\n/* Text in compact lists should not get extra bottim margin space,\n   since that would makes the list not compact */\nul.compact p, .ulCompact p,\nol.compact p, .olCompact p {\n margin: 0;\n}\n/* But the list as a whole needs the extra space at the end */\nsection ul.compact,\nsection .ulCompact,\nsection ol.compact,\nsection .olCompact {\n  margin-bottom: 1em;                    /* same as p not within ul.compact etc. */\n}\n/* The tt and code background above interferes with for instance table cell\n   backgrounds.  Changed to something a bit more selective. */\ntt, code {\n  background-color: transparent;\n}\np tt, p code, li tt, li code {\n  background-color: #f8f8f8;\n}\n/* Tweak the pre margin -- 0px doesn't come out well */\npre {\n   margin-top: 0.5px;\n}\n/* Tweak the comact list text */\nul.compact, .ulCompact,\nol.compact, .olCompact,\ndl.compact, .dlCompact {\n  line-height: normal;\n}\n/* Don't add top margin for nested lists */\nli > ul, li > ol, li > dl,\ndd > ul, dd > ol, dd > dl,\ndl > dd > dl {\n  margin-top: initial;\n}\n/* Elements that should not be rendered on the same line as a <dt> */\n/* This should match the element list in writer.text.TextWriter.render_dl() */\ndd > div.artwork:first-child,\ndd > aside:first-child,\ndd > figure:first-child,\ndd > ol:first-child,\ndd > div:first-child > pre.sourcecode,\ndd > table:first-child,\ndd > ul:first-child {\n  clear: left;\n}\n/* fix for weird browser behaviour when <dd/> is empty */\ndt+dd:empty::before{\n  content: \"\\00a0\";\n}\n/* Make paragraph spacing inside <li> smaller than in body text, to fit better within the list */\nli > p {\n  margin-bottom: 0.5em\n}\n/* Don't let p margin spill out from inside list items */\nli > p:last-of-type {\n  margin-bottom: 0;\n}\n</style>\n<link href=\"rfc-local.css\" rel=\"stylesheet\" type=\"text/css\">\n<script type=\"application/javascript\">async function addMetadata(){try{const e=document.styleSheets[0].cssRules;for(let t=0;t<e.length;t++)if(/#identifiers/.exec(e[t].selectorText)){const a=e[t].cssText.replace(\"#identifiers\",\"#external-updates\");document.styleSheets[0].insertRule(a,document.styleSheets[0].cssRules.length)}}catch(e){console.log(e)}const e=document.getElementById(\"external-metadata\");if(e)try{var t,a=\"\",o=function(e){const t=document.getElementsByTagName(\"meta\");for(let a=0;a<t.length;a++)if(t[a].getAttribute(\"name\")===e)return t[a].getAttribute(\"content\");return\"\"}(\"rfc.number\");if(o){t=\"https://www.rfc-editor.org/rfc/rfc\"+o+\".json\";try{const e=await fetch(t);a=await e.json()}catch(e){t=document.URL.indexOf(\"html\")>=0?document.URL.replace(/html$/,\"json\"):document.URL+\".json\";const o=await fetch(t);a=await o.json()}}if(!a)return;e.style.display=\"block\";const s=\"\",d=\"https://datatracker.ietf.org/doc\",n=\"https://datatracker.ietf.org/ipr/search\",c=\"https://www.rfc-editor.org/info\",l=a.doc_id.toLowerCase(),i=a.doc_id.slice(0,3).toLowerCase(),f=a.doc_id.slice(3).replace(/^0+/,\"\"),u={status:\"Status\",obsoletes:\"Obsoletes\",obsoleted_by:\"Obsoleted By\",updates:\"Updates\",updated_by:\"Updated By\",see_also:\"See Also\",errata_url:\"Errata\"};let h=\"<dl style='overflow:hidden' id='external-updates'>\";[\"status\",\"obsoletes\",\"obsoleted_by\",\"updates\",\"updated_by\",\"see_also\",\"errata_url\"].forEach(e=>{if(\"status\"==e){a[e]=a[e].toLowerCase();var t=a[e].split(\" \"),o=t.length,w=\"\",p=1;for(let e=0;e<o;e++)p<o?w=w+r(t[e])+\" \":w+=r(t[e]),p++;a[e]=w}else if(\"obsoletes\"==e||\"obsoleted_by\"==e||\"updates\"==e||\"updated_by\"==e){var g,m=\"\",b=1;g=a[e].length;for(let t=0;t<g;t++)a[e][t]&&(a[e][t]=String(a[e][t]).toLowerCase(),m=b<g?m+\"<a href='\"+s+\"/rfc/\".concat(a[e][t])+\"'>\"+a[e][t].slice(3)+\"</a>, \":m+\"<a href='\"+s+\"/rfc/\".concat(a[e][t])+\"'>\"+a[e][t].slice(3)+\"</a>\",b++);a[e]=m}else if(\"see_also\"==e){var y,L=\"\",C=1;y=a[e].length;for(let t=0;t<y;t++)if(a[e][t]){a[e][t]=String(a[e][t]);var _=a[e][t].slice(0,3),v=a[e][t].slice(3).replace(/^0+/,\"\");L=C<y?\"RFC\"!=_?L+\"<a href='\"+s+\"/info/\"+_.toLowerCase().concat(v.toLowerCase())+\"'>\"+_+\" \"+v+\"</a>, \":L+\"<a href='\"+s+\"/info/\"+_.toLowerCase().concat(v.toLowerCase())+\"'>\"+v+\"</a>, \":\"RFC\"!=_?L+\"<a href='\"+s+\"/info/\"+_.toLowerCase().concat(v.toLowerCase())+\"'>\"+_+\" \"+v+\"</a>\":L+\"<a href='\"+s+\"/info/\"+_.toLowerCase().concat(v.toLowerCase())+\"'>\"+v+\"</a>\",C++}a[e]=L}else if(\"errata_url\"==e){var R=\"\";R=a[e]?R+\"<a href='\"+a[e]+\"'>Errata exist</a> | <a href='\"+d+\"/\"+l+\"'>Datatracker</a>| <a href='\"+n+\"/?\"+i+\"=\"+f+\"&submit=\"+i+\"'>IPR</a> | <a href='\"+c+\"/\"+l+\"'>Info page</a>\":\"<a href='\"+d+\"/\"+l+\"'>Datatracker</a> | <a href='\"+n+\"/?\"+i+\"=\"+f+\"&submit=\"+i+\"'>IPR</a> | <a href='\"+c+\"/\"+l+\"'>Info page</a>\",a[e]=R}\"\"!=a[e]?\"Errata\"==u[e]?h+=`<dt>More info:</dt><dd>${a[e]}</dd>`:h+=`<dt>${u[e]}:</dt><dd>${a[e]}</dd>`:\"Errata\"==u[e]&&(h+=`<dt>More info:</dt><dd>${a[e]}</dd>`)}),h+=\"</dl>\",e.innerHTML=h}catch(e){console.log(e)}else console.log(\"Could not locate metadata <div> element\");function r(e){return e.charAt(0).toUpperCase()+e.slice(1)}}window.removeEventListener(\"load\",addMetadata),window.addEventListener(\"load\",addMetadata);</script>\n</head>\n<body>\n<script src=\"metadata.min.js\"></script>\n<table class=\"ears\">\n<thead><tr>\n<td class=\"left\">Internet-Draft</td>\n<td class=\"center\">new-uuid-format</td>\n<td class=\"right\">June 2022</td>\n</tr></thead>\n<tfoot><tr>\n<td class=\"left\">Peabody &amp; Davis</td>\n<td class=\"center\">Expires 25 December 2022</td>\n<td class=\"right\">[Page]</td>\n</tr></tfoot>\n</table>\n<div id=\"external-metadata\" class=\"document-information\"></div>\n<div id=\"internal-metadata\" class=\"document-information\">\n<dl id=\"identifiers\">\n<dt class=\"label-workgroup\">Workgroup:</dt>\n<dd class=\"workgroup\">dispatch</dd>\n<dt class=\"label-internet-draft\">Internet-Draft:</dt>\n<dd class=\"internet-draft\">draft-peabody-dispatch-new-uuid-format-04</dd>\n<dt class=\"label-updates\">Updates:</dt>\n<dd class=\"updates\">\n<a href=\"https://www.rfc-editor.org/rfc/rfc4122\" class=\"eref\">4122</a> (if approved)</dd>\n<dt class=\"label-published\">Published:</dt>\n<dd class=\"published\">\n<time datetime=\"2022-06-23\" class=\"published\">23 June 2022</time>\n    </dd>\n<dt class=\"label-intended-status\">Intended Status:</dt>\n<dd class=\"intended-status\">Standards Track</dd>\n<dt class=\"label-expires\">Expires:</dt>\n<dd class=\"expires\"><time datetime=\"2022-12-25\">25 December 2022</time></dd>\n<dt class=\"label-authors\">Authors:</dt>\n<dd class=\"authors\">\n<div class=\"author\">\n      <div class=\"author-name\">BGP. Peabody</div>\n</div>\n<div class=\"author\">\n      <div class=\"author-name\">K. Davis</div>\n</div>\n</dd>\n</dl>\n</div>\n<h1 id=\"title\">New UUID Formats</h1>\n<section id=\"section-abstract\">\n      <h2 id=\"abstract\"><a href=\"#abstract\" class=\"selfRef\">Abstract</a></h2>\n<p id=\"section-abstract-1\">\n This document presents new Universally Unique Identifier (UUID) formats for use in modern applications and databases.<a href=\"#section-abstract-1\" class=\"pilcrow\">¶</a></p>\n</section>\n<div id=\"status-of-memo\">\n<section id=\"section-boilerplate.1\">\n        <h2 id=\"name-status-of-this-memo-2\">\n<a href=\"#name-status-of-this-memo-2\" class=\"section-name selfRef\">Status of This Memo</a>\n        </h2>\n<p id=\"section-boilerplate.1-1\">\n        This Internet-Draft is submitted in full conformance with the\n        provisions of BCP 78 and BCP 79.<a href=\"#section-boilerplate.1-1\" class=\"pilcrow\">¶</a></p>\n<p id=\"section-boilerplate.1-2\">\n        Internet-Drafts are working documents of the Internet Engineering Task\n        Force (IETF). Note that other groups may also distribute working\n        documents as Internet-Drafts. The list of current Internet-Drafts is\n        at <span><a href=\"https://datatracker.ietf.org/drafts/current/\">https://datatracker.ietf.org/drafts/current/</a></span>.<a href=\"#section-boilerplate.1-2\" class=\"pilcrow\">¶</a></p>\n<p id=\"section-boilerplate.1-3\">\n        Internet-Drafts are draft documents valid for a maximum of six months\n        and may be updated, replaced, or obsoleted by other documents at any\n        time. It is inappropriate to use Internet-Drafts as reference\n        material or to cite them other than as \"work in progress.\"<a href=\"#section-boilerplate.1-3\" class=\"pilcrow\">¶</a></p>\n<p id=\"section-boilerplate.1-4\">\n        This Internet-Draft will expire on 25 December 2022.<a href=\"#section-boilerplate.1-4\" class=\"pilcrow\">¶</a></p>\n</section>\n</div>\n<div id=\"copyright\">\n<section id=\"section-boilerplate.2\">\n        <h2 id=\"name-copyright-notice-2\">\n<a href=\"#name-copyright-notice-2\" class=\"section-name selfRef\">Copyright Notice</a>\n        </h2>\n<p id=\"section-boilerplate.2-1\">\n            Copyright (c) 2022 IETF Trust and the persons identified as the\n            document authors. All rights reserved.<a href=\"#section-boilerplate.2-1\" class=\"pilcrow\">¶</a></p>\n<p id=\"section-boilerplate.2-2\">\n            This document is subject to BCP 78 and the IETF Trust's Legal\n            Provisions Relating to IETF Documents\n            (<span><a href=\"https://trustee.ietf.org/license-info\">https://trustee.ietf.org/license-info</a></span>) in effect on the date of\n            publication of this document. Please review these documents\n            carefully, as they describe your rights and restrictions with\n            respect to this document. Code Components extracted from this\n            document must include Revised BSD License text as described in\n            Section 4.e of the Trust Legal Provisions and are provided without\n            warranty as described in the Revised BSD License.<a href=\"#section-boilerplate.2-2\" class=\"pilcrow\">¶</a></p>\n</section>\n</div>\n<div id=\"toc\">\n<section id=\"section-toc.1\">\n        <a href=\"#\" onclick=\"scroll(0,0)\" class=\"toplink\">▲</a><h2 id=\"name-table-of-contents-2\">\n<a href=\"#name-table-of-contents-2\" class=\"section-name selfRef\">Table of Contents</a>\n        </h2>\n<nav class=\"toc\"><ul class=\"compact toc ulBare ulEmpty\">\n<li class=\"compact toc ulBare ulEmpty\" id=\"section-toc.1-1.1\">\n            <p id=\"section-toc.1-1.1.1\" class=\"keepWithNext\"><a href=\"#section-1\" class=\"xref\">1</a>.  <a href=\"#name-introduction-2\" class=\"xref\">Introduction</a></p>\n</li>\n          <li class=\"compact toc ulBare ulEmpty\" id=\"section-toc.1-1.2\">\n            <p id=\"section-toc.1-1.2.1\"><a href=\"#section-2\" class=\"xref\">2</a>.  <a href=\"#name-terminology-2\" class=\"xref\">Terminology</a></p>\n<ul class=\"compact toc ulBare ulEmpty\">\n<li class=\"compact toc ulBare ulEmpty\" id=\"section-toc.1-1.2.2.1\">\n                <p id=\"section-toc.1-1.2.2.1.1\" class=\"keepWithNext\"><a href=\"#section-2.1\" class=\"xref\">2.1</a>.  <a href=\"#name-requirements-language\" class=\"xref\">Requirements Language</a></p>\n</li>\n              <li class=\"compact toc ulBare ulEmpty\" id=\"section-toc.1-1.2.2.2\">\n                <p id=\"section-toc.1-1.2.2.2.1\" class=\"keepWithNext\"><a href=\"#section-2.2\" class=\"xref\">2.2</a>.  <a href=\"#name-abbreviations\" class=\"xref\">Abbreviations</a></p>\n</li>\n            </ul>\n</li>\n          <li class=\"compact toc ulBare ulEmpty\" id=\"section-toc.1-1.3\">\n            <p id=\"section-toc.1-1.3.1\"><a href=\"#section-3\" class=\"xref\">3</a>.  <a href=\"#name-summary-of-changes\" class=\"xref\">Summary of Changes</a></p>\n<ul class=\"compact toc ulBare ulEmpty\">\n<li class=\"compact toc ulBare ulEmpty\" id=\"section-toc.1-1.3.2.1\">\n                <p id=\"section-toc.1-1.3.2.1.1\"><a href=\"#section-3.1\" class=\"xref\">3.1</a>.  <a href=\"#name-changelog\" class=\"xref\">changelog</a></p>\n</li>\n            </ul>\n</li>\n          <li class=\"compact toc ulBare ulEmpty\" id=\"section-toc.1-1.4\">\n            <p id=\"section-toc.1-1.4.1\"><a href=\"#section-4\" class=\"xref\">4</a>.  <a href=\"#name-variant-and-version-fields\" class=\"xref\">Variant and Version Fields</a></p>\n</li>\n          <li class=\"compact toc ulBare ulEmpty\" id=\"section-toc.1-1.5\">\n            <p id=\"section-toc.1-1.5.1\"><a href=\"#section-5\" class=\"xref\">5</a>.  <a href=\"#name-new-formats\" class=\"xref\">New Formats</a></p>\n<ul class=\"compact toc ulBare ulEmpty\">\n<li class=\"compact toc ulBare ulEmpty\" id=\"section-toc.1-1.5.2.1\">\n                <p id=\"section-toc.1-1.5.2.1.1\"><a href=\"#section-5.1\" class=\"xref\">5.1</a>.  <a href=\"#name-uuid-version-6\" class=\"xref\">UUID Version 6</a></p>\n</li>\n              <li class=\"compact toc ulBare ulEmpty\" id=\"section-toc.1-1.5.2.2\">\n                <p id=\"section-toc.1-1.5.2.2.1\"><a href=\"#section-5.2\" class=\"xref\">5.2</a>.  <a href=\"#name-uuid-version-7\" class=\"xref\">UUID Version 7</a></p>\n</li>\n              <li class=\"compact toc ulBare ulEmpty\" id=\"section-toc.1-1.5.2.3\">\n                <p id=\"section-toc.1-1.5.2.3.1\"><a href=\"#section-5.3\" class=\"xref\">5.3</a>.  <a href=\"#name-uuid-version-8\" class=\"xref\">UUID Version 8</a></p>\n</li>\n              <li class=\"compact toc ulBare ulEmpty\" id=\"section-toc.1-1.5.2.4\">\n                <p id=\"section-toc.1-1.5.2.4.1\"><a href=\"#section-5.4\" class=\"xref\">5.4</a>.  <a href=\"#name-max-uuid\" class=\"xref\">Max UUID</a></p>\n</li>\n            </ul>\n</li>\n          <li class=\"compact toc ulBare ulEmpty\" id=\"section-toc.1-1.6\">\n            <p id=\"section-toc.1-1.6.1\"><a href=\"#section-6\" class=\"xref\">6</a>.  <a href=\"#name-uuid-best-practices\" class=\"xref\">UUID Best Practices</a></p>\n<ul class=\"compact toc ulBare ulEmpty\">\n<li class=\"compact toc ulBare ulEmpty\" id=\"section-toc.1-1.6.2.1\">\n                <p id=\"section-toc.1-1.6.2.1.1\"><a href=\"#section-6.1\" class=\"xref\">6.1</a>.  <a href=\"#name-timestamp-granularity\" class=\"xref\">Timestamp Granularity</a></p>\n</li>\n              <li class=\"compact toc ulBare ulEmpty\" id=\"section-toc.1-1.6.2.2\">\n                <p id=\"section-toc.1-1.6.2.2.1\"><a href=\"#section-6.2\" class=\"xref\">6.2</a>.  <a href=\"#name-monotonicity-and-counters\" class=\"xref\">Monotonicity and Counters</a></p>\n</li>\n              <li class=\"compact toc ulBare ulEmpty\" id=\"section-toc.1-1.6.2.3\">\n                <p id=\"section-toc.1-1.6.2.3.1\"><a href=\"#section-6.3\" class=\"xref\">6.3</a>.  <a href=\"#name-distributed-uuid-generation\" class=\"xref\">Distributed UUID Generation</a></p>\n</li>\n              <li class=\"compact toc ulBare ulEmpty\" id=\"section-toc.1-1.6.2.4\">\n                <p id=\"section-toc.1-1.6.2.4.1\"><a href=\"#section-6.4\" class=\"xref\">6.4</a>.  <a href=\"#name-collision-resistance\" class=\"xref\">Collision Resistance</a></p>\n</li>\n              <li class=\"compact toc ulBare ulEmpty\" id=\"section-toc.1-1.6.2.5\">\n                <p id=\"section-toc.1-1.6.2.5.1\"><a href=\"#section-6.5\" class=\"xref\">6.5</a>.  <a href=\"#name-global-and-local-uniqueness\" class=\"xref\">Global and Local Uniqueness</a></p>\n</li>\n              <li class=\"compact toc ulBare ulEmpty\" id=\"section-toc.1-1.6.2.6\">\n                <p id=\"section-toc.1-1.6.2.6.1\"><a href=\"#section-6.6\" class=\"xref\">6.6</a>.  <a href=\"#name-unguessability\" class=\"xref\">Unguessability</a></p>\n</li>\n              <li class=\"compact toc ulBare ulEmpty\" id=\"section-toc.1-1.6.2.7\">\n                <p id=\"section-toc.1-1.6.2.7.1\"><a href=\"#section-6.7\" class=\"xref\">6.7</a>.  <a href=\"#name-sorting\" class=\"xref\">Sorting</a></p>\n</li>\n              <li class=\"compact toc ulBare ulEmpty\" id=\"section-toc.1-1.6.2.8\">\n                <p id=\"section-toc.1-1.6.2.8.1\"><a href=\"#section-6.8\" class=\"xref\">6.8</a>.  <a href=\"#name-opacity\" class=\"xref\">Opacity</a></p>\n</li>\n              <li class=\"compact toc ulBare ulEmpty\" id=\"section-toc.1-1.6.2.9\">\n                <p id=\"section-toc.1-1.6.2.9.1\"><a href=\"#section-6.9\" class=\"xref\">6.9</a>.  <a href=\"#name-dbms-and-database-considera\" class=\"xref\">DBMS and Database Considerations</a></p>\n</li>\n            </ul>\n</li>\n          <li class=\"compact toc ulBare ulEmpty\" id=\"section-toc.1-1.7\">\n            <p id=\"section-toc.1-1.7.1\"><a href=\"#section-7\" class=\"xref\">7</a>.  <a href=\"#name-iana-considerations-2\" class=\"xref\">IANA Considerations</a></p>\n</li>\n          <li class=\"compact toc ulBare ulEmpty\" id=\"section-toc.1-1.8\">\n            <p id=\"section-toc.1-1.8.1\"><a href=\"#section-8\" class=\"xref\">8</a>.  <a href=\"#name-security-considerations-2\" class=\"xref\">Security Considerations</a></p>\n</li>\n          <li class=\"compact toc ulBare ulEmpty\" id=\"section-toc.1-1.9\">\n            <p id=\"section-toc.1-1.9.1\"><a href=\"#section-9\" class=\"xref\">9</a>.  <a href=\"#name-acknowledgements-2\" class=\"xref\">Acknowledgements</a></p>\n</li>\n          <li class=\"compact toc ulBare ulEmpty\" id=\"section-toc.1-1.10\">\n            <p id=\"section-toc.1-1.10.1\"><a href=\"#section-10\" class=\"xref\">10</a>. <a href=\"#name-normative-references-2\" class=\"xref\">Normative References</a></p>\n</li>\n          <li class=\"compact toc ulBare ulEmpty\" id=\"section-toc.1-1.11\">\n            <p id=\"section-toc.1-1.11.1\"><a href=\"#section-11\" class=\"xref\">11</a>. <a href=\"#name-informative-references-2\" class=\"xref\">Informative References</a></p>\n</li>\n          <li class=\"compact toc ulBare ulEmpty\" id=\"section-toc.1-1.12\">\n            <p id=\"section-toc.1-1.12.1\"><a href=\"#appendix-A\" class=\"xref\">Appendix A</a>.  <a href=\"#name-example-code\" class=\"xref\">Example Code</a></p>\n<ul class=\"compact toc ulBare ulEmpty\">\n<li class=\"compact toc ulBare ulEmpty\" id=\"section-toc.1-1.12.2.1\">\n                <p id=\"section-toc.1-1.12.2.1.1\"><a href=\"#appendix-A.1\" class=\"xref\">A.1</a>.  <a href=\"#name-creating-a-uuidv6-value\" class=\"xref\">Creating a UUIDv6 Value</a></p>\n</li>\n              <li class=\"compact toc ulBare ulEmpty\" id=\"section-toc.1-1.12.2.2\">\n                <p id=\"section-toc.1-1.12.2.2.1\"><a href=\"#appendix-A.2\" class=\"xref\">A.2</a>.  <a href=\"#name-creating-a-uuidv7-value\" class=\"xref\">Creating a UUIDv7 Value</a></p>\n</li>\n              <li class=\"compact toc ulBare ulEmpty\" id=\"section-toc.1-1.12.2.3\">\n                <p id=\"section-toc.1-1.12.2.3.1\"><a href=\"#appendix-A.3\" class=\"xref\">A.3</a>.  <a href=\"#name-creating-a-uuidv8-value\" class=\"xref\">Creating a UUIDv8 Value</a></p>\n</li>\n            </ul>\n</li>\n          <li class=\"compact toc ulBare ulEmpty\" id=\"section-toc.1-1.13\">\n            <p id=\"section-toc.1-1.13.1\"><a href=\"#appendix-B\" class=\"xref\">Appendix B</a>.  <a href=\"#name-test-vectors\" class=\"xref\">Test Vectors</a></p>\n<ul class=\"compact toc ulBare ulEmpty\">\n<li class=\"compact toc ulBare ulEmpty\" id=\"section-toc.1-1.13.2.1\">\n                <p id=\"section-toc.1-1.13.2.1.1\"><a href=\"#appendix-B.1\" class=\"xref\">B.1</a>.  <a href=\"#name-example-of-a-uuidv6-value\" class=\"xref\">Example of a UUIDv6 Value</a></p>\n</li>\n              <li class=\"compact toc ulBare ulEmpty\" id=\"section-toc.1-1.13.2.2\">\n                <p id=\"section-toc.1-1.13.2.2.1\"><a href=\"#appendix-B.2\" class=\"xref\">B.2</a>.  <a href=\"#name-example-of-a-uuidv7-value\" class=\"xref\">Example of a UUIDv7 Value</a></p>\n</li>\n              <li class=\"compact toc ulBare ulEmpty\" id=\"section-toc.1-1.13.2.3\">\n                <p id=\"section-toc.1-1.13.2.3.1\"><a href=\"#appendix-B.3\" class=\"xref\">B.3</a>.  <a href=\"#name-example-of-a-uuidv8-value\" class=\"xref\">Example of a UUIDv8 Value</a></p>\n</li>\n            </ul>\n</li>\n          <li class=\"compact toc ulBare ulEmpty\" id=\"section-toc.1-1.14\">\n            <p id=\"section-toc.1-1.14.1\"><a href=\"#appendix-C\" class=\"xref\">Appendix C</a>.  <a href=\"#name-version-and-variant-tables\" class=\"xref\">Version and Variant Tables</a></p>\n<ul class=\"compact toc ulBare ulEmpty\">\n<li class=\"compact toc ulBare ulEmpty\" id=\"section-toc.1-1.14.2.1\">\n                <p id=\"section-toc.1-1.14.2.1.1\"><a href=\"#appendix-C.1\" class=\"xref\">C.1</a>.  <a href=\"#name-variant-10xx-versions\" class=\"xref\">Variant 10xx Versions</a></p>\n</li>\n            </ul>\n</li>\n          <li class=\"compact toc ulBare ulEmpty\" id=\"section-toc.1-1.15\">\n            <p id=\"section-toc.1-1.15.1\"><a href=\"#appendix-D\" class=\"xref\"></a><a href=\"#name-authors-addresses-2\" class=\"xref\">Authors' Addresses</a></p>\n</li>\n        </ul>\n</nav>\n</section>\n</div>\n<div id=\"Background\">\n<section id=\"section-1\">\n      <h2 id=\"name-introduction-2\">\n<a href=\"#section-1\" class=\"section-number selfRef\">1. </a><a href=\"#name-introduction-2\" class=\"section-name selfRef\">Introduction</a>\n      </h2>\n<p id=\"section-1-1\">\n Many things have changed in the time since UUIDs were originally created.\n Modern applications have a need to create and utilize UUIDs as the primary\n identifier for a variety of different items in complex computational systems,\n including but not limited to database keys, file names, machine or system names, and identifiers for event-driven transactions.<a href=\"#section-1-1\" class=\"pilcrow\">¶</a></p>\n<p id=\"section-1-2\">\n One area UUIDs have gained popularity is as database keys.\n This stems from the increasingly distributed nature of modern applications.\n In such cases, \"auto increment\" schemes often used by databases do not work well, as the effort required to coordinate unique numeric identifiers across a network can easily become a burden.\n The fact that UUIDs can be used to create unique, reasonably short values in distributed systems without requiring synchronization makes them a good alternative, but UUID versions 1-5 lack certain other desirable characteristics:<a href=\"#section-1-2\" class=\"pilcrow\">¶</a></p>\n<ol start=\"1\" type=\"1\" class=\"normal type-1\" id=\"section-1-3\">\n <li id=\"section-1-3.1\">\n          <p id=\"section-1-3.1.1\">Non-time-ordered UUID versions such as UUIDv4 have poor database index locality.\n Meaning new values created in succession are not close to each other in the index and thus require \n inserts to be performed at random locations. The negative performance effects of which on \n common structures used for this (B-tree and its variants) can be dramatic.<a href=\"#section-1-3.1.1\" class=\"pilcrow\">¶</a></p>\n</li>\n        <li id=\"section-1-3.2\">\n          <p id=\"section-1-3.2.1\">\n The 100-nanosecond, Gregorian epoch used in UUIDv1 timestamps is uncommon and difficult to represent accurately using a standard number format such as <span>[<a href=\"#IEEE754\" class=\"xref\">IEEE754</a>]</span>.<a href=\"#section-1-3.2.1\" class=\"pilcrow\">¶</a></p>\n</li>\n        <li id=\"section-1-3.3\">\n          <p id=\"section-1-3.3.1\">\n Introspection/parsing is required to order by time sequence; as opposed to being able to perform a simple byte-by-byte comparison.<a href=\"#section-1-3.3.1\" class=\"pilcrow\">¶</a></p>\n</li>\n        <li id=\"section-1-3.4\">\n          <p id=\"section-1-3.4.1\">\n Privacy and network security issues arise from using a MAC address in the node field of Version 1 UUIDs.\n Exposed MAC addresses can be used as an attack surface to locate machines and reveal various other\n information about such machines (minimally manufacturer, potentially other details). Additionally, with the advent of virtual machines and containers, MAC address uniqueness is no longer guaranteed.<a href=\"#section-1-3.4.1\" class=\"pilcrow\">¶</a></p>\n</li>\n        <li id=\"section-1-3.5\">\n          <p id=\"section-1-3.5.1\">\n Many of the implementation details specified in <span>[<a href=\"#RFC4122\" class=\"xref\">RFC4122</a>]</span> involve trade offs that are neither possible to specify for all applications nor necessary to produce interoperable implementations.<a href=\"#section-1-3.5.1\" class=\"pilcrow\">¶</a></p>\n</li>\n        <li id=\"section-1-3.6\">\n          <p id=\"section-1-3.6.1\">\n <span>[<a href=\"#RFC4122\" class=\"xref\">RFC4122</a>]</span> does not distinguish between the requirements for generation of a UUID versus an application which simply stores one, which are often different.<a href=\"#section-1-3.6.1\" class=\"pilcrow\">¶</a></p>\n</li>\n      </ol>\n<p id=\"section-1-4\">\n Due to the aforementioned issue, many widely distributed database applications \n and large application vendors have sought to solve the problem of creating a better \n time-based, sortable unique identifier for use as a database key. This has lead to numerous implementations \n over the past 10+ years solving the same problem in slightly different ways.<a href=\"#section-1-4\" class=\"pilcrow\">¶</a></p>\n<p id=\"section-1-5\">\n While preparing this specification the following 16 different implementations were analyzed for trends in total ID length, bit Layout, lexical formatting/encoding, timestamp type, timestamp format, timestamp accuracy, node format/components, collision handling and multi-timestamp tick generation sequencing.<a href=\"#section-1-5\" class=\"pilcrow\">¶</a></p>\n<ol start=\"1\" type=\"1\" class=\"compact type-1\" id=\"section-1-6\">\n <li id=\"section-1-6.1\">\n          <p id=\"section-1-6.1.1\"><span>[<a href=\"#ULID\" class=\"xref\">ULID</a>]</span> by A. Feerasta<a href=\"#section-1-6.1.1\" class=\"pilcrow\">¶</a></p>\n</li>\n        <li id=\"section-1-6.2\">\n          <p id=\"section-1-6.2.1\"><span>[<a href=\"#LexicalUUID\" class=\"xref\">LexicalUUID</a>]</span> by Twitter<a href=\"#section-1-6.2.1\" class=\"pilcrow\">¶</a></p>\n</li>\n        <li id=\"section-1-6.3\">\n          <p id=\"section-1-6.3.1\"><span>[<a href=\"#Snowflake\" class=\"xref\">Snowflake</a>]</span> by Twitter<a href=\"#section-1-6.3.1\" class=\"pilcrow\">¶</a></p>\n</li>\n        <li id=\"section-1-6.4\">\n          <p id=\"section-1-6.4.1\"><span>[<a href=\"#Flake\" class=\"xref\">Flake</a>]</span> by Boundary<a href=\"#section-1-6.4.1\" class=\"pilcrow\">¶</a></p>\n</li>\n        <li id=\"section-1-6.5\">\n          <p id=\"section-1-6.5.1\"><span>[<a href=\"#ShardingID\" class=\"xref\">ShardingID</a>]</span> by Instagram<a href=\"#section-1-6.5.1\" class=\"pilcrow\">¶</a></p>\n</li>\n        <li id=\"section-1-6.6\">\n          <p id=\"section-1-6.6.1\"><span>[<a href=\"#KSUID\" class=\"xref\">KSUID</a>]</span> by Segment<a href=\"#section-1-6.6.1\" class=\"pilcrow\">¶</a></p>\n</li>\n        <li id=\"section-1-6.7\">\n          <p id=\"section-1-6.7.1\"><span>[<a href=\"#Elasticflake\" class=\"xref\">Elasticflake</a>]</span> by P. Pearcy<a href=\"#section-1-6.7.1\" class=\"pilcrow\">¶</a></p>\n</li>\n        <li id=\"section-1-6.8\">\n          <p id=\"section-1-6.8.1\"><span>[<a href=\"#FlakeID\" class=\"xref\">FlakeID</a>]</span> by T. Pawlak<a href=\"#section-1-6.8.1\" class=\"pilcrow\">¶</a></p>\n</li>\n        <li id=\"section-1-6.9\">\n          <p id=\"section-1-6.9.1\"><span>[<a href=\"#Sonyflake\" class=\"xref\">Sonyflake</a>]</span> by Sony<a href=\"#section-1-6.9.1\" class=\"pilcrow\">¶</a></p>\n</li>\n        <li id=\"section-1-6.10\">\n          <p id=\"section-1-6.10.1\"><span>[<a href=\"#orderedUuid\" class=\"xref\">orderedUuid</a>]</span> by IT. Cabrera<a href=\"#section-1-6.10.1\" class=\"pilcrow\">¶</a></p>\n</li>\n        <li id=\"section-1-6.11\">\n          <p id=\"section-1-6.11.1\"><span>[<a href=\"#COMBGUID\" class=\"xref\">COMBGUID</a>]</span> by R. Tallent<a href=\"#section-1-6.11.1\" class=\"pilcrow\">¶</a></p>\n</li>\n        <li id=\"section-1-6.12\">\n          <p id=\"section-1-6.12.1\"><span>[<a href=\"#SID\" class=\"xref\">SID</a>]</span> by A. Chilton<a href=\"#section-1-6.12.1\" class=\"pilcrow\">¶</a></p>\n</li>\n        <li id=\"section-1-6.13\">\n          <p id=\"section-1-6.13.1\"><span>[<a href=\"#pushID\" class=\"xref\">pushID</a>]</span> by Google<a href=\"#section-1-6.13.1\" class=\"pilcrow\">¶</a></p>\n</li>\n        <li id=\"section-1-6.14\">\n          <p id=\"section-1-6.14.1\"><span>[<a href=\"#XID\" class=\"xref\">XID</a>]</span> by O. Poitrey<a href=\"#section-1-6.14.1\" class=\"pilcrow\">¶</a></p>\n</li>\n        <li id=\"section-1-6.15\">\n          <p id=\"section-1-6.15.1\"><span>[<a href=\"#ObjectID\" class=\"xref\">ObjectID</a>]</span> by MongoDB<a href=\"#section-1-6.15.1\" class=\"pilcrow\">¶</a></p>\n</li>\n        <li id=\"section-1-6.16\">\n          <p id=\"section-1-6.16.1\"><span>[<a href=\"#CUID\" class=\"xref\">CUID</a>]</span> by E. Elliott<a href=\"#section-1-6.16.1\" class=\"pilcrow\">¶</a></p>\n</li>\n      </ol>\n<p id=\"section-1-7\">\n An inspection of these implementations and the issues described above has led to this document which attempts to adapt UUIDs to address these issues.<a href=\"#section-1-7\" class=\"pilcrow\">¶</a></p>\n</section>\n</div>\n<section id=\"section-2\">\n      <h2 id=\"name-terminology-2\">\n<a href=\"#section-2\" class=\"section-number selfRef\">2. </a><a href=\"#name-terminology-2\" class=\"section-name selfRef\">Terminology</a>\n      </h2>\n<div id=\"requirements_language\">\n<section id=\"section-2.1\">\n        <h3 id=\"name-requirements-language\">\n<a href=\"#section-2.1\" class=\"section-number selfRef\">2.1. </a><a href=\"#name-requirements-language\" class=\"section-name selfRef\">Requirements Language</a>\n        </h3>\n<p id=\"section-2.1-1\">\n The key words \"MUST\", \"MUST NOT\", \"REQUIRED\", \"SHALL\", \"SHALL NOT\", \"SHOULD\", \"SHOULD NOT\", \"RECOMMENDED\", \"NOT RECOMMENDED\", \"MAY\", and \"OPTIONAL\" in this document are to be interpreted as described in BCP 14 <span>[<a href=\"#RFC2119\" class=\"xref\">RFC2119</a>]</span> <span>[<a href=\"#RFC8174\" class=\"xref\">RFC8174</a>]</span> when, and only when, they appear in all capitals, as shown here.<a href=\"#section-2.1-1\" class=\"pilcrow\">¶</a></p>\n</section>\n</div>\n<div id=\"acronyms\">\n<section id=\"section-2.2\">\n        <h3 id=\"name-abbreviations\">\n<a href=\"#section-2.2\" class=\"section-number selfRef\">2.2. </a><a href=\"#name-abbreviations\" class=\"section-name selfRef\">Abbreviations</a>\n        </h3>\n<p id=\"section-2.2-1\">The following abbreviations are used in this document:<a href=\"#section-2.2-1\" class=\"pilcrow\">¶</a></p>\n<span class=\"break\"></span><dl class=\"dlParallel\" id=\"section-2.2-2\">\n          <dt id=\"section-2.2-2.1\">UUID</dt>\n          <dd style=\"margin-left: 7.0em\" id=\"section-2.2-2.2\">Universally Unique Identifier <span>[<a href=\"#RFC4122\" class=\"xref\">RFC4122</a>]</span><a href=\"#section-2.2-2.2\" class=\"pilcrow\">¶</a>\n</dd>\n          <dd class=\"break\"></dd>\n<dt id=\"section-2.2-2.3\">CSPRNG</dt>\n          <dd style=\"margin-left: 7.0em\" id=\"section-2.2-2.4\">Cryptographically Secure Pseudo-Random Number Generator<a href=\"#section-2.2-2.4\" class=\"pilcrow\">¶</a>\n</dd>\n          <dd class=\"break\"></dd>\n<dt id=\"section-2.2-2.5\">MAC</dt>\n          <dd style=\"margin-left: 7.0em\" id=\"section-2.2-2.6\">Media Access Control<a href=\"#section-2.2-2.6\" class=\"pilcrow\">¶</a>\n</dd>\n          <dd class=\"break\"></dd>\n<dt id=\"section-2.2-2.7\">MSB</dt>\n          <dd style=\"margin-left: 7.0em\" id=\"section-2.2-2.8\">Most Significant Bit<a href=\"#section-2.2-2.8\" class=\"pilcrow\">¶</a>\n</dd>\n          <dd class=\"break\"></dd>\n<dt id=\"section-2.2-2.9\">DBMS</dt>\n          <dd style=\"margin-left: 7.0em\" id=\"section-2.2-2.10\">Database Management System<a href=\"#section-2.2-2.10\" class=\"pilcrow\">¶</a>\n</dd>\n        <dd class=\"break\"></dd>\n</dl>\n</section>\n</div>\n</section>\n<div id=\"Changes\">\n<section id=\"section-3\">\n      <h2 id=\"name-summary-of-changes\">\n<a href=\"#section-3\" class=\"section-number selfRef\">3. </a><a href=\"#name-summary-of-changes\" class=\"section-name selfRef\">Summary of Changes</a>\n      </h2>\n<p id=\"section-3-1\">\n The following UUIDs are hereby introduced:<a href=\"#section-3-1\" class=\"pilcrow\">¶</a></p>\n<span class=\"break\"></span><dl class=\"dlNewline\" id=\"section-3-2\">\n        <dt id=\"section-3-2.1\">UUID version 6 (UUIDv6)</dt>\n        <dd style=\"margin-left: 1.5em\" id=\"section-3-2.2\">A re-ordering of UUID version 1 so it is sortable as an opaque sequence of bytes.  Easy to implement given an existing UUIDv1 implementation. See <a href=\"#uuidv6\" class=\"xref\">Section 5.1</a><a href=\"#section-3-2.2\" class=\"pilcrow\">¶</a>\n</dd>\n        <dd class=\"break\"></dd>\n<dt id=\"section-3-2.3\">UUID version 7 (UUIDv7)</dt>\n        <dd style=\"margin-left: 1.5em\" id=\"section-3-2.4\">An entirely new time-based UUID bit layout sourced from the widely implemented and well known Unix Epoch timestamp source. See <a href=\"#v7\" class=\"xref\">Section 5.2</a><a href=\"#section-3-2.4\" class=\"pilcrow\">¶</a>\n</dd>\n        <dd class=\"break\"></dd>\n<dt id=\"section-3-2.5\">UUID version 8 (UUIDv8)</dt>\n        <dd style=\"margin-left: 1.5em\" id=\"section-3-2.6\">A free-form UUID format which has no explicit requirements except maintaining backward compatibility. See <a href=\"#v8\" class=\"xref\">Section 5.3</a><a href=\"#section-3-2.6\" class=\"pilcrow\">¶</a>\n</dd>\n        <dd class=\"break\"></dd>\n<dt id=\"section-3-2.7\">Max UUID</dt>\n        <dd style=\"margin-left: 1.5em\" id=\"section-3-2.8\">A specialized UUID which is the inverse of <span>[<a href=\"#RFC4122\" class=\"xref\">RFC4122</a>], <a href=\"https://rfc-editor.org/rfc/rfc4122#section-4.1.7\" class=\"relref\">Section 4.1.7</a></span> See <a href=\"#maxuuid\" class=\"xref\">Section 5.4</a><a href=\"#section-3-2.8\" class=\"pilcrow\">¶</a>\n</dd>\n      <dd class=\"break\"></dd>\n</dl>\n<div id=\"changelog\">\n<section id=\"section-3.1\">\n        <h3 id=\"name-changelog\">\n<a href=\"#section-3.1\" class=\"section-number selfRef\">3.1. </a><a href=\"#name-changelog\" class=\"section-name selfRef\">changelog</a>\n        </h3>\n<p id=\"section-3.1-1\">RFC EDITOR PLEASE DELETE THIS SECTION.<a href=\"#section-3.1-1\" class=\"pilcrow\">¶</a></p>\n<p id=\"section-3.1-2\">draft-04<a href=\"#section-3.1-2\" class=\"pilcrow\">¶</a></p>\n<ul class=\"compact ulEmpty\">\n<li class=\"compact ulEmpty\" id=\"section-3.1-3.1\">\n            <p id=\"section-3.1-3.1.1\">- Fixed bad title in IEEE754 Normative Reference<a href=\"#section-3.1-3.1.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"compact ulEmpty\" id=\"section-3.1-3.2\">\n            <p id=\"section-3.1-3.2.1\">- Fixed bad GMT offset in Test Vector Appendix<a href=\"#section-3.1-3.2.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"compact ulEmpty\" id=\"section-3.1-3.3\">\n            <p id=\"section-3.1-3.3.1\">- Removed MAY in Counters section<a href=\"#section-3.1-3.3.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"compact ulEmpty\" id=\"section-3.1-3.4\">\n            <p id=\"section-3.1-3.4.1\">- Condensed Counter Type into Counter Methods to reduce text<a href=\"#section-3.1-3.4.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"compact ulEmpty\" id=\"section-3.1-3.5\">\n            <p id=\"section-3.1-3.5.1\">- Removed option for random increment along with fixed-length counter<a href=\"#section-3.1-3.5.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"compact ulEmpty\" id=\"section-3.1-3.6\">\n            <p id=\"section-3.1-3.6.1\">- Described how to handle scenario where New UUID less than Old UUID<a href=\"#section-3.1-3.6.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"compact ulEmpty\" id=\"section-3.1-3.7\">\n            <p id=\"section-3.1-3.7.1\">- Allow timestamp increment if counter overflows<a href=\"#section-3.1-3.7.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"compact ulEmpty\" id=\"section-3.1-3.8\">\n            <p id=\"section-3.1-3.8.1\">- Replaced UUIDv8 C code snippet with full generation example<a href=\"#section-3.1-3.8.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"compact ulEmpty\" id=\"section-3.1-3.9\">\n            <p id=\"section-3.1-3.9.1\">- Fixed RFC4086 Reference link<a href=\"#section-3.1-3.9.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"compact ulEmpty\" id=\"section-3.1-3.10\">\n            <p id=\"section-3.1-3.10.1\">- Describe reseeding best practice for CSPRNG<a href=\"#section-3.1-3.10.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"compact ulEmpty\" id=\"section-3.1-3.11\">\n            <p id=\"section-3.1-3.11.1\">- Changed MUST to SHOULD removing requirement for absolute monotonicity<a href=\"#section-3.1-3.11.1\" class=\"pilcrow\">¶</a></p>\n</li>\n        </ul>\n<p id=\"section-3.1-4\">draft-03<a href=\"#section-3.1-4\" class=\"pilcrow\">¶</a></p>\n<ul class=\"compact ulEmpty\">\n<li class=\"compact ulEmpty\" id=\"section-3.1-5.1\">\n            <p id=\"section-3.1-5.1.1\">- Reworked the draft body to make the content more concise<a href=\"#section-3.1-5.1.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"compact ulEmpty\" id=\"section-3.1-5.2\">\n            <p id=\"section-3.1-5.2.1\">- UUIDv6 section reworked to just the reorder of the timestamp<a href=\"#section-3.1-5.2.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"compact ulEmpty\" id=\"section-3.1-5.3\">\n            <p id=\"section-3.1-5.3.1\">- UUIDv7 changed to simplify timestamp mechanism to just millisecond Unix timestamp<a href=\"#section-3.1-5.3.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"compact ulEmpty\" id=\"section-3.1-5.4\">\n            <p id=\"section-3.1-5.4.1\">- UUIDv8 relaxed to be custom in all elements except version and variant<a href=\"#section-3.1-5.4.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"compact ulEmpty\" id=\"section-3.1-5.5\">\n            <p id=\"section-3.1-5.5.1\">- Introduced Max UUID.<a href=\"#section-3.1-5.5.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"compact ulEmpty\" id=\"section-3.1-5.6\">\n            <p id=\"section-3.1-5.6.1\">- Added C code samples in Appendix.<a href=\"#section-3.1-5.6.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"compact ulEmpty\" id=\"section-3.1-5.7\">\n            <p id=\"section-3.1-5.7.1\">- Added test vectors in Appendix.<a href=\"#section-3.1-5.7.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"compact ulEmpty\" id=\"section-3.1-5.8\">\n            <p id=\"section-3.1-5.8.1\">- Version and Variant section combined into one section.<a href=\"#section-3.1-5.8.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"compact ulEmpty\" id=\"section-3.1-5.9\">\n            <p id=\"section-3.1-5.9.1\">- Changed from pseudo-random number generators to cryptographically secure pseudo-random number generator (CSPRNG).<a href=\"#section-3.1-5.9.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"compact ulEmpty\" id=\"section-3.1-5.10\">\n            <p id=\"section-3.1-5.10.1\">- Combined redundant topics from all UUIDs into sections such as Timestamp granularity, Monotonicity and Counters, Collision Resistance, Sorting, and Unguessability, etc.<a href=\"#section-3.1-5.10.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"compact ulEmpty\" id=\"section-3.1-5.11\">\n            <p id=\"section-3.1-5.11.1\">- Split Encoding and Storage into Opacity and DBMS and Database Considerations<a href=\"#section-3.1-5.11.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"compact ulEmpty\" id=\"section-3.1-5.12\">\n            <p id=\"section-3.1-5.12.1\">- Reworked Global Uniqueness under new section Global and Local Uniqueness<a href=\"#section-3.1-5.12.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"compact ulEmpty\" id=\"section-3.1-5.13\">\n            <p id=\"section-3.1-5.13.1\">- Node verbiage only used in UUIDv6 all others reference random/rand instead<a href=\"#section-3.1-5.13.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"compact ulEmpty\" id=\"section-3.1-5.14\">\n            <p id=\"section-3.1-5.14.1\">- Clock sequence verbiage changed simply to counter in any section other than UUIDv6<a href=\"#section-3.1-5.14.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"compact ulEmpty\" id=\"section-3.1-5.15\">\n            <p id=\"section-3.1-5.15.1\">- Added Abbreviations section<a href=\"#section-3.1-5.15.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"compact ulEmpty\" id=\"section-3.1-5.16\">\n            <p id=\"section-3.1-5.16.1\">- Updated IETF Draft XML Layout<a href=\"#section-3.1-5.16.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"compact ulEmpty\" id=\"section-3.1-5.17\">\n            <p id=\"section-3.1-5.17.1\">- Added information about little-endian UUIDs<a href=\"#section-3.1-5.17.1\" class=\"pilcrow\">¶</a></p>\n</li>\n        </ul>\n<p id=\"section-3.1-6\">draft-02<a href=\"#section-3.1-6\" class=\"pilcrow\">¶</a></p>\n<ul class=\"compact ulEmpty\">\n<li class=\"compact ulEmpty\" id=\"section-3.1-7.1\">\n            <p id=\"section-3.1-7.1.1\">- Added Changelog<a href=\"#section-3.1-7.1.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"compact ulEmpty\" id=\"section-3.1-7.2\">\n            <p id=\"section-3.1-7.2.1\">- Fixed misc. grammatical errors<a href=\"#section-3.1-7.2.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"compact ulEmpty\" id=\"section-3.1-7.3\">\n            <p id=\"section-3.1-7.3.1\">- Fixed section numbering issue<a href=\"#section-3.1-7.3.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"compact ulEmpty\" id=\"section-3.1-7.4\">\n            <p id=\"section-3.1-7.4.1\">- Fixed some UUIDvX reference issues<a href=\"#section-3.1-7.4.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"compact ulEmpty\" id=\"section-3.1-7.5\">\n            <p id=\"section-3.1-7.5.1\">- Changed all instances of \"motonic\" to \"monotonic\"<a href=\"#section-3.1-7.5.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"compact ulEmpty\" id=\"section-3.1-7.6\">\n            <p id=\"section-3.1-7.6.1\">- Changed all instances of \"#-bit\" to \"# bit\"<a href=\"#section-3.1-7.6.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"compact ulEmpty\" id=\"section-3.1-7.7\">\n            <p id=\"section-3.1-7.7.1\">- Changed \"proceeding\" verbiage to \"after\" in section 7<a href=\"#section-3.1-7.7.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"compact ulEmpty\" id=\"section-3.1-7.8\">\n            <p id=\"section-3.1-7.8.1\">- Added details on how to pad 32 bit Unix timestamp to 36 bits in UUIDv7<a href=\"#section-3.1-7.8.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"compact ulEmpty\" id=\"section-3.1-7.9\">\n            <p id=\"section-3.1-7.9.1\">- Added details on how to truncate 64 bit Unix timestamp to 36 bits in UUIDv7<a href=\"#section-3.1-7.9.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"compact ulEmpty\" id=\"section-3.1-7.10\">\n            <p id=\"section-3.1-7.10.1\">- Added forward reference and bullet to UUIDv8 if truncating 64 bit Unix Epoch is not an option.<a href=\"#section-3.1-7.10.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"compact ulEmpty\" id=\"section-3.1-7.11\">\n            <p id=\"section-3.1-7.11.1\">- Fixed bad reference to non-existent \"time_or_node\" in section 4.5.4<a href=\"#section-3.1-7.11.1\" class=\"pilcrow\">¶</a></p>\n</li>\n        </ul>\n<p id=\"section-3.1-8\">draft-01<a href=\"#section-3.1-8\" class=\"pilcrow\">¶</a></p>\n<ul class=\"compact ulEmpty\">\n<li class=\"compact ulEmpty\" id=\"section-3.1-9.1\">\n            <p id=\"section-3.1-9.1.1\">- Complete rewrite of entire document.<a href=\"#section-3.1-9.1.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"compact ulEmpty\" id=\"section-3.1-9.2\">\n            <p id=\"section-3.1-9.2.1\">- The format, flow and verbiage used in the specification has been reworked to mirror the original RFC 4122 and current IETF standards.<a href=\"#section-3.1-9.2.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"compact ulEmpty\" id=\"section-3.1-9.3\">\n            <p id=\"section-3.1-9.3.1\">- Removed the topics of UUID length modification, alternate UUID text formats, and alternate UUID encoding techniques.<a href=\"#section-3.1-9.3.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"compact ulEmpty\" id=\"section-3.1-9.4\">\n            <p id=\"section-3.1-9.4.1\">- Research into 16 different historical and current implementations of time-based universal identifiers was completed at the end of 2020 in attempt to identify trends which have directly influenced design decisions in this draft document (https://github.com/uuid6/uuid6-ietf-draft/tree/master/research)<a href=\"#section-3.1-9.4.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"compact ulEmpty\" id=\"section-3.1-9.5\">\n            <p id=\"section-3.1-9.5.1\">- Prototype implementation have been completed for UUIDv6, UUIDv7, and UUIDv8 in various languages by many GitHub community members. (https://github.com/uuid6/prototypes)<a href=\"#section-3.1-9.5.1\" class=\"pilcrow\">¶</a></p>\n</li>\n        </ul>\n</section>\n</div>\n</section>\n</div>\n<div id=\"variant_and_version_fields\">\n<section id=\"section-4\">\n      <h2 id=\"name-variant-and-version-fields\">\n<a href=\"#section-4\" class=\"section-number selfRef\">4. </a><a href=\"#name-variant-and-version-fields\" class=\"section-name selfRef\">Variant and Version Fields</a>\n      </h2>\n<p id=\"section-4-1\">\n The variant bits utilized by UUIDs in this specification \n remain in the same octet as originally defined by <span>[<a href=\"#RFC4122\" class=\"xref\">RFC4122</a>], <a href=\"https://rfc-editor.org/rfc/rfc4122#section-4.1.1\" class=\"relref\">Section 4.1.1</a></span>.<a href=\"#section-4-1\" class=\"pilcrow\">¶</a></p>\n<p id=\"section-4-2\">\n The next table details Variant 10xx (8/9/A/B) and the new versions defined by this specification. \n A complete guide to all versions within this variant has been includes in <a href=\"#old_var_table\" class=\"xref\">Appendix C.1</a>.<a href=\"#section-4-2\" class=\"pilcrow\">¶</a></p>\n<span id=\"name-new-uuid-variant-10xx-8-9-a\"></span><table class=\"center\" id=\"table-1\">\n        <caption>\n<a href=\"#table-1\" class=\"selfRef\">Table 1</a>:\n<a href=\"#name-new-uuid-variant-10xx-8-9-a\" class=\"selfRef\">New UUID variant 10xx (8/9/A/B) versions defined by this specification</a>\n        </caption>\n<thead>\n          <tr>\n            <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">Msb0</td>\n            <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">Msb1</td>\n            <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">Msb2</td>\n            <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">Msb3</td>\n            <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">Version</td>\n            <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">Description</td>\n          </tr>\n        </thead>\n        <tbody>\n          <tr>\n            <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">0</td>\n            <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">1</td>\n            <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">1</td>\n            <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">0</td>\n            <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">6</td>\n            <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">Reordered Gregorian time-based UUID specified in this document.</td>\n          </tr>\n          <tr>\n            <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">0</td>\n            <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">1</td>\n            <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">1</td>\n            <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">1</td>\n            <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">7</td>\n            <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">Unix Epoch time-based UUID specified in this document.</td>\n          </tr>\n          <tr>\n            <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">1</td>\n            <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">0</td>\n            <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">0</td>\n            <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">0</td>\n            <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">8</td>\n            <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">Reserved for custom UUID formats specified in this document</td>\n          </tr>\n        </tbody>\n      </table>\n<p id=\"section-4-4\">\n For UUID version 6, 7 and 8 the variant field placement from <span>[<a href=\"#RFC4122\" class=\"xref\">RFC4122</a>]</span> are unchanged.\n An example version/variant layout for UUIDv6 follows the table where M is the version and N is the variant.<a href=\"#section-4-4\" class=\"pilcrow\">¶</a></p>\n<span id=\"name-uuidv6-variant-examples\"></span><figure id=\"figure-1\">\n        <div class=\"alignLeft art-text artwork\" id=\"section-4-5.1\">\n<pre>\n00000000-0000-6000-8000-000000000000\n00000000-0000-6000-9000-000000000000\n00000000-0000-6000-A000-000000000000\n00000000-0000-6000-B000-000000000000\nxxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx\n</pre>\n</div>\n<figcaption><a href=\"#figure-1\" class=\"selfRef\">Figure 1</a>:\n<a href=\"#name-uuidv6-variant-examples\" class=\"selfRef\">UUIDv6 Variant Examples</a>\n        </figcaption></figure>\n</section>\n</div>\n<div id=\"format\">\n<section id=\"section-5\">\n      <h2 id=\"name-new-formats\">\n<a href=\"#section-5\" class=\"section-number selfRef\">5. </a><a href=\"#name-new-formats\" class=\"section-name selfRef\">New Formats</a>\n      </h2>\n<p id=\"section-5-1\">\n The UUID format is 16 octets; the variant bits in conjunction with the version bits described in the next section in determine finer structure.<a href=\"#section-5-1\" class=\"pilcrow\">¶</a></p>\n<div id=\"uuidv6\">\n<section id=\"section-5.1\">\n        <h3 id=\"name-uuid-version-6\">\n<a href=\"#section-5.1\" class=\"section-number selfRef\">5.1. </a><a href=\"#name-uuid-version-6\" class=\"section-name selfRef\">UUID Version 6</a>\n        </h3>\n<p id=\"section-5.1-1\">\n UUID version 6 is a field-compatible version of UUIDv1, reordered for improved DB locality. \n It is expected that UUIDv6 will primarily be used in contexts where there are existing v1 UUIDs.\n Systems that do not involve legacy UUIDv1 SHOULD consider using UUIDv7 instead.<a href=\"#section-5.1-1\" class=\"pilcrow\">¶</a></p>\n<p id=\"section-5.1-2\">\n Instead of splitting the timestamp into the low, mid and high sections from UUIDv1, UUIDv6 changes this sequence so timestamp bytes are stored from most to least significant.  \n That is, given a 60 bit timestamp value as specified for UUIDv1 in <span>[<a href=\"#RFC4122\" class=\"xref\">RFC4122</a>], <a href=\"https://rfc-editor.org/rfc/rfc4122#section-4.1.4\" class=\"relref\">Section 4.1.4</a></span>,\n for UUIDv6, the first 48 most significant bits are stored\n first, followed by the 4 bit version (same position), followed by the remaining 12 bits of the original 60 bit timestamp.<a href=\"#section-5.1-2\" class=\"pilcrow\">¶</a></p>\n<p id=\"section-5.1-3\">\n The clock sequence bits remain unchanged from their usage and position in <span>[<a href=\"#RFC4122\" class=\"xref\">RFC4122</a>], <a href=\"https://rfc-editor.org/rfc/rfc4122#section-4.1.5\" class=\"relref\">Section 4.1.5</a></span>.<a href=\"#section-5.1-3\" class=\"pilcrow\">¶</a></p>\n<p id=\"section-5.1-4\">\n The 48 bit node SHOULD be set to a pseudo-random value however implementations MAY choose to retain the old MAC address behavior from <span>[<a href=\"#RFC4122\" class=\"xref\">RFC4122</a>], <a href=\"https://rfc-editor.org/rfc/rfc4122#section-4.1.6\" class=\"relref\">Section 4.1.6</a></span> and <span>[<a href=\"#RFC4122\" class=\"xref\">RFC4122</a>], <a href=\"https://rfc-editor.org/rfc/rfc4122#section-4.5\" class=\"relref\">Section 4.5</a></span>. For more information on MAC address usage within UUIDs see the <a href=\"#Security\" class=\"xref\">Section 8</a><a href=\"#section-5.1-4\" class=\"pilcrow\">¶</a></p>\n<p id=\"section-5.1-5\">\n The format for the 16-byte, 128 bit UUIDv6 is shown in Figure 1<a href=\"#section-5.1-5\" class=\"pilcrow\">¶</a></p>\n<span id=\"name-uuidv6-field-and-bit-layout\"></span><figure id=\"figure-2\">\n          <div class=\"alignLeft art-text artwork\" id=\"section-5.1-6.1\">\n<pre>\n     0                   1                   2                   3\n     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n    |                           time_high                           |\n    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n    |           time_mid            |      time_low_and_version     |\n    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n    |clk_seq_hi_res |  clk_seq_low  |         node (0-1)            |\n    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n    |                         node (2-5)                            |\n    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n</pre>\n</div>\n<figcaption><a href=\"#figure-2\" class=\"selfRef\">Figure 2</a>:\n<a href=\"#name-uuidv6-field-and-bit-layout\" class=\"selfRef\">UUIDv6 Field and Bit Layout</a>\n          </figcaption></figure>\n<span class=\"break\"></span><dl class=\"dlNewline\" id=\"section-5.1-7\">\n          <dt id=\"section-5.1-7.1\">time_high:</dt>\n          <dd style=\"margin-left: 1.5em\" id=\"section-5.1-7.2\">The most significant 32 bits of the 60 bit starting timestamp.\n            Occupies bits 0 through 31 (octets 0-3)<a href=\"#section-5.1-7.2\" class=\"pilcrow\">¶</a>\n</dd>\n          <dd class=\"break\"></dd>\n<dt id=\"section-5.1-7.3\">time_mid:</dt>\n          <dd style=\"margin-left: 1.5em\" id=\"section-5.1-7.4\">The middle 16 bits of the 60 bit starting timestamp.\n            Occupies bits 32 through 47 (octets 4-5)<a href=\"#section-5.1-7.4\" class=\"pilcrow\">¶</a>\n</dd>\n          <dd class=\"break\"></dd>\n<dt id=\"section-5.1-7.5\">time_low_and_version:</dt>\n          <dd style=\"margin-left: 1.5em\" id=\"section-5.1-7.6\">The first four most significant bits MUST contain\n            the UUIDv6 version (0110) while the remaining 12 bits will contain\n            the least significant 12 bits from the 60 bit starting timestamp.\n            Occupies bits 48 through 63 (octets 6-7)<a href=\"#section-5.1-7.6\" class=\"pilcrow\">¶</a>\n</dd>\n          <dd class=\"break\"></dd>\n<dt id=\"section-5.1-7.7\">clk_seq_hi_res:</dt>\n          <dd style=\"margin-left: 1.5em\" id=\"section-5.1-7.8\">The first two bits MUST be set to the UUID variant (10)\n            The remaining 6 bits contain the high portion of the clock sequence.\n            Occupies bits 64 through 71 (octet 8)<a href=\"#section-5.1-7.8\" class=\"pilcrow\">¶</a>\n</dd>\n          <dd class=\"break\"></dd>\n<dt id=\"section-5.1-7.9\">clock_seq_low:</dt>\n          <dd style=\"margin-left: 1.5em\" id=\"section-5.1-7.10\">The 8 bit low portion of the clock sequence.\n            Occupies bits 72 through 79 (octet 9)<a href=\"#section-5.1-7.10\" class=\"pilcrow\">¶</a>\n</dd>\n          <dd class=\"break\"></dd>\n<dt id=\"section-5.1-7.11\">node:</dt>\n          <dd style=\"margin-left: 1.5em\" id=\"section-5.1-7.12\">48 bit spatially unique identifier\n            Occupies bits 80 through 127 (octets 10-15)<a href=\"#section-5.1-7.12\" class=\"pilcrow\">¶</a>\n</dd>\n        <dd class=\"break\"></dd>\n</dl>\n<p id=\"section-5.1-8\">\n With UUIDv6 the steps for splitting the timestamp into time_high and time_mid are OPTIONAL\n since the 48 bits of time_high and time_mid will remain in the same order.\n An extra step of splitting the first 48 bits of the timestamp into the most significant \n 32 bits and least significant 16 bits proves useful when reusing an existing UUIDv1 implementation.<a href=\"#section-5.1-8\" class=\"pilcrow\">¶</a></p>\n</section>\n</div>\n<div id=\"v7\">\n<section id=\"section-5.2\">\n        <h3 id=\"name-uuid-version-7\">\n<a href=\"#section-5.2\" class=\"section-number selfRef\">5.2. </a><a href=\"#name-uuid-version-7\" class=\"section-name selfRef\">UUID Version 7</a>\n        </h3>\n<p id=\"section-5.2-1\">\n UUID version 7 features a time-ordered value field derived from the widely implemented and well known Unix Epoch timestamp source, the number of milliseconds seconds since midnight 1 Jan 1970 UTC, leap seconds excluded.\n As well as improved entropy characteristics over versions 1 or 6.<a href=\"#section-5.2-1\" class=\"pilcrow\">¶</a></p>\n<p id=\"section-5.2-2\">\n Implementations SHOULD utilize UUID version 7 over UUID version 1 and 6 if possible.<a href=\"#section-5.2-2\" class=\"pilcrow\">¶</a></p>\n<span id=\"name-uuidv7-field-and-bit-layout\"></span><figure id=\"figure-3\">\n          <div class=\"alignLeft art-text artwork\" id=\"section-5.2-3.1\">\n<pre>\n 0                   1                   2                   3\n 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n|                           unix_ts_ms                          |\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n|          unix_ts_ms           |  ver  |       rand_a          |\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n|var|                        rand_b                             |\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n|                            rand_b                             |\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n</pre>\n</div>\n<figcaption><a href=\"#figure-3\" class=\"selfRef\">Figure 3</a>:\n<a href=\"#name-uuidv7-field-and-bit-layout\" class=\"selfRef\">UUIDv7 Field and Bit Layout</a>\n          </figcaption></figure>\n<span class=\"break\"></span><dl class=\"dlNewline\" id=\"section-5.2-4\">\n          <dt id=\"section-5.2-4.1\">unix_ts_ms:</dt>\n          <dd style=\"margin-left: 1.5em\" id=\"section-5.2-4.2\">48 bit big-endian unsigned number of Unix epoch timestamp as per <a href=\"#timestamp_granularity\" class=\"xref\">Section 6.1</a>.<a href=\"#section-5.2-4.2\" class=\"pilcrow\">¶</a>\n</dd>\n          <dd class=\"break\"></dd>\n<dt id=\"section-5.2-4.3\">ver:</dt>\n          <dd style=\"margin-left: 1.5em\" id=\"section-5.2-4.4\">4 bit UUIDv7 version set as per <a href=\"#variant_and_version_fields\" class=\"xref\">Section 4</a><a href=\"#section-5.2-4.4\" class=\"pilcrow\">¶</a>\n</dd>\n          <dd class=\"break\"></dd>\n<dt id=\"section-5.2-4.5\">rand_a:</dt>\n          <dd style=\"margin-left: 1.5em\" id=\"section-5.2-4.6\">12 bits pseudo-random data to provide uniqueness as per <a href=\"#monotonicity_counters\" class=\"xref\">Section 6.2</a> and <a href=\"#unguessability\" class=\"xref\">Section 6.6</a>.<a href=\"#section-5.2-4.6\" class=\"pilcrow\">¶</a>\n</dd>\n          <dd class=\"break\"></dd>\n<dt id=\"section-5.2-4.7\">var:</dt>\n          <dd style=\"margin-left: 1.5em\" id=\"section-5.2-4.8\">The 2 bit variant defined by <a href=\"#variant_and_version_fields\" class=\"xref\">Section 4</a>.<a href=\"#section-5.2-4.8\" class=\"pilcrow\">¶</a>\n</dd>\n          <dd class=\"break\"></dd>\n<dt id=\"section-5.2-4.9\">rand_b:</dt>\n          <dd style=\"margin-left: 1.5em\" id=\"section-5.2-4.10\">The final 62 bits of pseudo-random data to provide uniqueness as per <a href=\"#monotonicity_counters\" class=\"xref\">Section 6.2</a> and <a href=\"#unguessability\" class=\"xref\">Section 6.6</a>.<a href=\"#section-5.2-4.10\" class=\"pilcrow\">¶</a>\n</dd>\n        <dd class=\"break\"></dd>\n</dl>\n</section>\n</div>\n<div id=\"v8\">\n<section id=\"section-5.3\">\n        <h3 id=\"name-uuid-version-8\">\n<a href=\"#section-5.3\" class=\"section-number selfRef\">5.3. </a><a href=\"#name-uuid-version-8\" class=\"section-name selfRef\">UUID Version 8</a>\n        </h3>\n<p id=\"section-5.3-1\">\n UUID version 8 provides an RFC-compatible format for experimental or vendor-specific use cases.\n The only requirement is that the variant and version bits MUST be set as defined in <a href=\"#variant_and_version_fields\" class=\"xref\">Section 4</a>. \n UUIDv8's uniqueness will be implementation-specific and SHOULD NOT be assumed.<a href=\"#section-5.3-1\" class=\"pilcrow\">¶</a></p>\n<p id=\"section-5.3-2\">\n The only explicitly defined bits are the Version and Variant leaving 122 bits\n for implementation specific time-based UUIDs. To be clear:\n UUIDv8 is not a replacement for UUIDv4 where all 122 extra bits are\n filled with random data.<a href=\"#section-5.3-2\" class=\"pilcrow\">¶</a></p>\n<p id=\"section-5.3-3\">\n Some example situations in which UUIDv8 usage could occur:<a href=\"#section-5.3-3\" class=\"pilcrow\">¶</a></p>\n<ul class=\"normal\">\n<li class=\"normal\" id=\"section-5.3-4.1\">\n            <p id=\"section-5.3-4.1.1\">An implementation would like to embed extra information\n   within the UUID other than what is defined in this document.<a href=\"#section-5.3-4.1.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"normal\" id=\"section-5.3-4.2\">\n            <p id=\"section-5.3-4.2.1\">An implementation has other application/language restrictions which\n   inhibit the use of one of the current UUIDs.<a href=\"#section-5.3-4.2.1\" class=\"pilcrow\">¶</a></p>\n</li>\n        </ul>\n<span id=\"name-uuidv8-field-and-bit-layout\"></span><figure id=\"figure-4\">\n          <div class=\"alignLeft art-text artwork\" id=\"section-5.3-5.1\">\n<pre>\n 0                   1                   2                   3\n 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n|                           custom_a                            |\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n|          custom_a             |  ver  |       custom_b        |\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n|var|                       custom_c                            |\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n|                           custom_c                            |\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n</pre>\n</div>\n<figcaption><a href=\"#figure-4\" class=\"selfRef\">Figure 4</a>:\n<a href=\"#name-uuidv8-field-and-bit-layout\" class=\"selfRef\">UUIDv8 Field and Bit Layout</a>\n          </figcaption></figure>\n<span class=\"break\"></span><dl class=\"dlNewline\" id=\"section-5.3-6\">\n          <dt id=\"section-5.3-6.1\">custom_a:</dt>\n          <dd style=\"margin-left: 1.5em\" id=\"section-5.3-6.2\">The first 48 bits of the layout that can be filled as an implementation sees fit.<a href=\"#section-5.3-6.2\" class=\"pilcrow\">¶</a>\n</dd>\n          <dd class=\"break\"></dd>\n<dt id=\"section-5.3-6.3\">ver:</dt>\n          <dd style=\"margin-left: 1.5em\" id=\"section-5.3-6.4\">The 4 bit version field as defined by <a href=\"#variant_and_version_fields\" class=\"xref\">Section 4</a><a href=\"#section-5.3-6.4\" class=\"pilcrow\">¶</a>\n</dd>\n          <dd class=\"break\"></dd>\n<dt id=\"section-5.3-6.5\">custom_b:</dt>\n          <dd style=\"margin-left: 1.5em\" id=\"section-5.3-6.6\">12 more bits of the layout that can be filled as an implementation sees fit.<a href=\"#section-5.3-6.6\" class=\"pilcrow\">¶</a>\n</dd>\n          <dd class=\"break\"></dd>\n<dt id=\"section-5.3-6.7\">var:</dt>\n          <dd style=\"margin-left: 1.5em\" id=\"section-5.3-6.8\">The 2 bit variant field as defined by <a href=\"#variant_and_version_fields\" class=\"xref\">Section 4</a>.<a href=\"#section-5.3-6.8\" class=\"pilcrow\">¶</a>\n</dd>\n          <dd class=\"break\"></dd>\n<dt id=\"section-5.3-6.9\">custom_c:</dt>\n          <dd style=\"margin-left: 1.5em\" id=\"section-5.3-6.10\">The final 62 bits of the layout immediatly following the var field to be filled as an implementation sees fit.<a href=\"#section-5.3-6.10\" class=\"pilcrow\">¶</a>\n</dd>\n        <dd class=\"break\"></dd>\n</dl>\n</section>\n</div>\n<div id=\"maxuuid\">\n<section id=\"section-5.4\">\n        <h3 id=\"name-max-uuid\">\n<a href=\"#section-5.4\" class=\"section-number selfRef\">5.4. </a><a href=\"#name-max-uuid\" class=\"section-name selfRef\">Max UUID</a>\n        </h3>\n<p id=\"section-5.4-1\">The Max UUID is special form of UUID that is specified to have all 128 bits set to 1. This UUID can be thought of as the inverse of Nil UUID defined in <span>[<a href=\"#RFC4122\" class=\"xref\">RFC4122</a>], <a href=\"https://rfc-editor.org/rfc/rfc4122#section-4.1.7\" class=\"relref\">Section 4.1.7</a></span><a href=\"#section-5.4-1\" class=\"pilcrow\">¶</a></p>\n<span id=\"name-max-uuid-format\"></span><figure id=\"figure-5\">\n          <div class=\"alignLeft art-text artwork\" id=\"section-5.4-2.1\">\n<pre>\nFFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF\n</pre>\n</div>\n<figcaption><a href=\"#figure-5\" class=\"selfRef\">Figure 5</a>:\n<a href=\"#name-max-uuid-format\" class=\"selfRef\">Max UUID Format</a>\n          </figcaption></figure>\n</section>\n</div>\n</section>\n</div>\n<div id=\"uuid_best_practices\">\n<section id=\"section-6\">\n      <h2 id=\"name-uuid-best-practices\">\n<a href=\"#section-6\" class=\"section-number selfRef\">6. </a><a href=\"#name-uuid-best-practices\" class=\"section-name selfRef\">UUID Best Practices</a>\n      </h2>\n<p id=\"section-6-1\">\n The minimum requirements for generating UUIDs are \n described in this document for each version.\n Everything else is an implementation detail and \n up to the implementer to decide what is appropriate for a given \n implementation. That being said, various relevant factors are covered\n below to help guide an implementer through the different trade-offs among differing UUID implementations.<a href=\"#section-6-1\" class=\"pilcrow\">¶</a></p>\n<div id=\"timestamp_granularity\">\n<section id=\"section-6.1\">\n        <h3 id=\"name-timestamp-granularity\">\n<a href=\"#section-6.1\" class=\"section-number selfRef\">6.1. </a><a href=\"#name-timestamp-granularity\" class=\"section-name selfRef\">Timestamp Granularity</a>\n        </h3>\n<p id=\"section-6.1-1\">\n UUID timestamp source, precision and length was the topic of great debate while creating this specification. As such choosing the right timestamp for your application is a very important topic. This section will detail some of the most common points on this topic.<a href=\"#section-6.1-1\" class=\"pilcrow\">¶</a></p>\n<span class=\"break\"></span><dl class=\"dlNewline\" id=\"section-6.1-2\">\n          <dt id=\"section-6.1-2.1\">Reliability:</dt>\n          <dd style=\"margin-left: 1.5em\" id=\"section-6.1-2.2\">Implementations SHOULD use the current timestamp from a reliable source to provide values that are time-ordered and continually increasing. \n Care SHOULD be taken to ensure that timestamp changes from the environment or operating system are handled in a way that is consistent with implementation requirements.  \n For example, if it is possible for the system clock to move backward due to either manual adjustment or corrections from a time synchronization protocol, implementations must decide how to handle such cases. (See Altering, Fuzzing, or Smearing bullet below.)<a href=\"#section-6.1-2.2\" class=\"pilcrow\">¶</a>\n</dd>\n          <dd class=\"break\"></dd>\n<dt id=\"section-6.1-2.3\">Source:</dt>\n          <dd style=\"margin-left: 1.5em\" id=\"section-6.1-2.4\">UUID version 1 and 6 both utilize a Gregorian epoch timestamp while UUIDv7 utilizes a Unix Epoch timestamp. If other timestamp sources or a custom timestamp epoch are required UUIDv8 SHOULD be leveraged.<a href=\"#section-6.1-2.4\" class=\"pilcrow\">¶</a>\n</dd>\n          <dd class=\"break\"></dd>\n<dt id=\"section-6.1-2.5\">Sub-second Precision and Accuracy:</dt>\n          <dd style=\"margin-left: 1.5em\" id=\"section-6.1-2.6\">\n Many levels of precision exist for timestamps: milliseconds, microseconds, nanoseconds, and beyond.\n Additionally fractional representations of sub-second precision may be desired to mix various levels of precision in a time-ordered manner. \n Furthermore, system clocks themselves have an underlying granularity and it is frequently less than the precision offered by the operating system. \n With UUID version 1 and 6, 100-nanoseconds of precision are present while UUIDv7 features fixed millisecond level of precision within the Unix epoch that does not exceed the granularity capable in most modern systems.\n For other levels of precision UUIDv8 SHOULD be utilized.<a href=\"#section-6.1-2.6\" class=\"pilcrow\">¶</a>\n</dd>\n          <dd class=\"break\"></dd>\n<dt id=\"section-6.1-2.7\">Length:</dt>\n          <dd style=\"margin-left: 1.5em\" id=\"section-6.1-2.8\">The length of a given timestamp directly impacts how long a given UUID will be valid. \n That is, how many timestamp ticks can be contained in a UUID before the maximum value for the timestamp field is reached. \n Care should be given to ensure that the proper length is selected for a given timestamp. \n UUID version 1 and 6 utilize a 60 bit timestamp and UUIDv7 features a 48 bit timestamp.<a href=\"#section-6.1-2.8\" class=\"pilcrow\">¶</a>\n</dd>\n          <dd class=\"break\"></dd>\n<dt id=\"section-6.1-2.9\">Altering, Fuzzing, or Smearing:</dt>\n          <dd style=\"margin-left: 1.5em\" id=\"section-6.1-2.10\">Implementations MAY alter the actual timestamp. Some examples included security considerations around providing a real clock value within a UUID, to correct inaccurate clocks or to handle leap seconds. This specification makes no requirement or guarantee about how close the clock value needs to be to actual time.<a href=\"#section-6.1-2.10\" class=\"pilcrow\">¶</a>\n</dd>\n          <dd class=\"break\"></dd>\n<dt id=\"section-6.1-2.11\">Padding:</dt>\n          <dd style=\"margin-left: 1.5em\" id=\"section-6.1-2.12\">When timestamp padding is required, implementations MUST pad the most significant bits (left-most) bits with zeros. An example is padding the most significant, left-most bits of a 32 bit Unix timestamp with zero's to fill out the 48 bit timestamp in UUIDv7.<a href=\"#section-6.1-2.12\" class=\"pilcrow\">¶</a>\n</dd>\n          <dd class=\"break\"></dd>\n<dt id=\"section-6.1-2.13\">Truncating:</dt>\n          <dd style=\"margin-left: 1.5em\" id=\"section-6.1-2.14\">Similarly, when timestamps need to be truncated: the lower, least significant bits MUST be used. An example would be truncating a 64 bit Unix timestamp to the least significant, right-most 48 bits for UUIDv7.<a href=\"#section-6.1-2.14\" class=\"pilcrow\">¶</a>\n</dd>\n        <dd class=\"break\"></dd>\n</dl>\n</section>\n</div>\n<div id=\"monotonicity_counters\">\n<section id=\"section-6.2\">\n        <h3 id=\"name-monotonicity-and-counters\">\n<a href=\"#section-6.2\" class=\"section-number selfRef\">6.2. </a><a href=\"#name-monotonicity-and-counters\" class=\"section-name selfRef\">Monotonicity and Counters</a>\n        </h3>\n<p id=\"section-6.2-1\">\n Monotonicity is the backbone of time-based sortable UUIDs. Naturally time-based UUIDs from this document will be monotonic due to an embedded timestamp however implementations can guarantee additional monotonicity via the concepts covered in this section.<a href=\"#section-6.2-1\" class=\"pilcrow\">¶</a></p>\n<p id=\"section-6.2-2\">\n Additionally, care SHOULD be taken to ensure UUIDs generated in batches are also monotonic. That is, if one-thousand UUIDs are generated for the same timestamp; there is sufficient logic for organizing the creation order of those one-thousand UUIDs.\n For batch UUID creation implementions MAY utilize a monotonic counter which SHOULD increment for each UUID created during a given timestamp.<a href=\"#section-6.2-2\" class=\"pilcrow\">¶</a></p>\n<p id=\"section-6.2-3\">\n For single-node UUID implementations that do not need to create batches of UUIDs, the embedded timestamp within UUID version 1, 6, and 7 can provide sufficient monotonicity guarantees by simply ensuring that timestamp increments before creating a new UUID. For the topic of Distributed Nodes please refer to <a href=\"#distributed_shared_knowledge\" class=\"xref\">Section 6.3</a><a href=\"#section-6.2-3\" class=\"pilcrow\">¶</a></p>\n<p id=\"section-6.2-4\">\n Implementations SHOULD choose one method for single-node UUID implementations that require batch UUID creation.<a href=\"#section-6.2-4\" class=\"pilcrow\">¶</a></p>\n<span class=\"break\"></span><dl class=\"dlNewline\" id=\"section-6.2-5\">\n          <dt id=\"section-6.2-5.1\">Fixed-Length Dedicated Counter Bits (Method 1):</dt>\n          <dd style=\"margin-left: 1.5em\" id=\"section-6.2-5.2\">\n This references the practice of allocating a specific number of bits in the UUID layout to the sole purpose of tallying the total number of UUIDs created during a given UUID timestamp tick.\n Positioning of a fixed bit-length counter SHOULD be immediatly after the embedded timestamp. This promotes sortability and allows random data generation for each counter increment. \n With this method rand_a section of UUIDv7 SHOULD be utilized as fixed-length dedicated counter bits that are incremented by one for every UUID generation.\n The trailing random bits generated for each new UUID in rand_b can help produce unguessable UUIDs. In the event more counter bits are required the most significant, left-most, bits of rand_b MAY be leveraged as additional counter bits.<a href=\"#section-6.2-5.2\" class=\"pilcrow\">¶</a>\n</dd>\n          <dd class=\"break\"></dd>\n<dt id=\"section-6.2-5.3\">Monotonic Random (Method 2):</dt>\n          <dd style=\"margin-left: 1.5em\" id=\"section-6.2-5.4\">\n With this method the random data is extended to also double as a counter. \n This monotonic random can be thought of as a \"randomly seeded counter\" which MUST be incremented in the least significant position for each UUID created on a given timestamp tick.\n UUIDv7's rand_b section SHOULD be utilized with this method to handle batch UUID generation during a single timestamp tick.\n The increment value for every UUID generation SHOULD be a random integer of any desired length larger than zero. It ensures the UUIDs retain the required level of unguessability characters provided by the underlying entropy.\n The increment value MAY be one when the amount of UUIDs generated in a particular period of time is important and guessability is not an issue. However, it SHOULD NOT be used by implementations that favor unguessiblity, as the resulting values are easily guessable.<a href=\"#section-6.2-5.4\" class=\"pilcrow\">¶</a>\n</dd>\n        <dd class=\"break\"></dd>\n</dl>\n<p id=\"section-6.2-6\">\n The following sub-topics cover topics related solely with creating reliable fixed-length dedicated counters:<a href=\"#section-6.2-6\" class=\"pilcrow\">¶</a></p>\n<span class=\"break\"></span><dl class=\"dlNewline\" id=\"section-6.2-7\">\n          <dt id=\"section-6.2-7.1\">Fixed-Length Dedicated Counter Seeding:</dt>\n          <dd style=\"margin-left: 1.5em\" id=\"section-6.2-7.2\">\n Implementations utilizing fixed-length counter method SHOULD randomly initialize the counter with each new timestamp tick.\n However, when the timestamp has not incremented; the counter SHOULD be frozen and incremented via the desired increment logic.\n When utilizing a randomly seeded counter alongside Method 1; the random MAY be regenerated with each counter increment without impacting sortability.\n The downside is that Method 1 is prone to overflows if a counter of adequate length is not selected or the random data generated leaves little room for the required number of increments. \n Implementations utilizing fixed-length counter method MAY also choose to randomly initialize a portion counter rather than the entire counter. For example, a 24 bit counter could have the 23 bits in least-significant, right-most, position randomly initialized. The remaining most significant, left-most counter bits are initialized as zero for the sole purpose of guarding against counter rollovers.<a href=\"#section-6.2-7.2\" class=\"pilcrow\">¶</a>\n</dd>\n          <dd class=\"break\"></dd>\n<dt id=\"section-6.2-7.3\">Fixed-Length Dedicated Counter Length:</dt>\n          <dd style=\"margin-left: 1.5em\" id=\"section-6.2-7.4\">\n Care MUST be taken to select a counter bit-length that can properly handle the level of timestamp precision in use. \n For example, millisecond precision SHOULD require a larger counter than a timestamp with nanosecond precision. \n General guidance is that the counter SHOULD be at least 12 bits but no longer than 42 bits. \n Care SHOULD also be given to ensure that the counter length selected leaves room for sufficient entropy in the random portion of the UUID after the counter. \n This entropy helps improve the unguessability characteristics of UUIDs created within the batch.<a href=\"#section-6.2-7.4\" class=\"pilcrow\">¶</a>\n</dd>\n        <dd class=\"break\"></dd>\n</dl>\n<p id=\"section-6.2-8\">\n The following sub-topics cover rollover handling with either type of counter method:<a href=\"#section-6.2-8\" class=\"pilcrow\">¶</a></p>\n<span class=\"break\"></span><dl class=\"dlNewline\" id=\"section-6.2-9\">\n          <dt id=\"section-6.2-9.1\">Counter Rollover Guards:</dt>\n          <dd style=\"margin-left: 1.5em\" id=\"section-6.2-9.2\">\n The technique from Fixed-Length Dedicated Counter Seeding which describes allocating a segment of the fixed-length counter as a rollover guard is also helpful to mitigate counter rollover issues.\n This same technique can be leveraged with Monotonic random counter methods by ensuring the total length of a possible increment in the least significant, right most position is less than the total length of the random being incremented.\n As such the most significant, left-most, bits can be incremented as rollover guarding.<a href=\"#section-6.2-9.2\" class=\"pilcrow\">¶</a>\n</dd>\n          <dd class=\"break\"></dd>\n<dt id=\"section-6.2-9.3\">Counter Rollover Handling:</dt>\n          <dd style=\"margin-left: 1.5em\" id=\"section-6.2-9.4\">\n Counter rollovers SHOULD be handled by the application to avoid sorting issues. \n The general guidance is that applications that care about absolute monotonicity and sortability SHOULD freeze the counter and wait for the timestamp to advance which ensures monotonicity is not broken.\n Alternatively, implementations MAY increment the timestamp ahead of the actual time and reinitialize the counter.<a href=\"#section-6.2-9.4\" class=\"pilcrow\">¶</a>\n</dd>\n        <dd class=\"break\"></dd>\n</dl>\n<p id=\"section-6.2-10\">\n Implementations MAY use the following logic to ensure UUIDs featuring embedded counters are monotonic in nature:<a href=\"#section-6.2-10\" class=\"pilcrow\">¶</a></p>\n<ol start=\"1\" type=\"1\" class=\"compact type-1\" id=\"section-6.2-11\">\n <li id=\"section-6.2-11.1\">\n            <p id=\"section-6.2-11.1.1\">Compare the current timestamp against the previously stored timestamp.<a href=\"#section-6.2-11.1.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li id=\"section-6.2-11.2\">\n            <p id=\"section-6.2-11.2.1\">If the current timestamp is equal to the previous timestamp; increment the counter according to the desired method.<a href=\"#section-6.2-11.2.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li id=\"section-6.2-11.3\">\n            <p id=\"section-6.2-11.3.1\">If the current timestamp is greater than the previous timestamp; re-initialize the desired counter method to the new timestamp and generate new random bytes (if the bytes were frozen or being used as the seed for a monotonic counter).<a href=\"#section-6.2-11.3.1\" class=\"pilcrow\">¶</a></p>\n</li>\n        </ol>\n<p id=\"section-6.2-12\">\n Implementations SHOULD check if the the currently generated UUID is greater than the previously generated UUID. If this is not the case then any number of things could have occurred. Such as, but not limited to, clock rollbacks, leap second handling or counter rollovers. Applications SHOULD embed sufficient logic to catch these scenarios and correct the problem ensuring the next UUID generated is greater than the previous. To handle this scenario, the general guidance is that application MAY reuse the previous timestamp and increment the previous counter method.<a href=\"#section-6.2-12\" class=\"pilcrow\">¶</a></p>\n</section>\n</div>\n<div id=\"distributed_shared_knowledge\">\n<section id=\"section-6.3\">\n        <h3 id=\"name-distributed-uuid-generation\">\n<a href=\"#section-6.3\" class=\"section-number selfRef\">6.3. </a><a href=\"#name-distributed-uuid-generation\" class=\"section-name selfRef\">Distributed UUID Generation</a>\n        </h3>\n<p id=\"section-6.3-1\">\n Some implementations MAY desire to utilize multi-node, clustered, applications which involve two or more \n nodes independently generating UUIDs that will be stored in a common location. \n While UUIDs already feature sufficient entropy to ensure that the chances of collision are low as the total number of nodes increase; so does the likelihood of a collision. \n This section will detail the approaches that MAY be utilized by multi-node UUID implementations in distributed environments.<a href=\"#section-6.3-1\" class=\"pilcrow\">¶</a></p>\n<span class=\"break\"></span><dl class=\"dlNewline\" id=\"section-6.3-2\">\n          <dt id=\"section-6.3-2.1\">Centralized Registry:</dt>\n          <dd style=\"margin-left: 1.5em\" id=\"section-6.3-2.2\">With this method all nodes tasked with creating UUIDs consult a central registry and confirm the generated value is unique. As applications scale the communication with the central registry could become a bottleneck and impact UUID generation in a negative way. Utilization of shared knowledge schemes with central/global registries is outside the scope of this specification.<a href=\"#section-6.3-2.2\" class=\"pilcrow\">¶</a>\n</dd>\n          <dd class=\"break\"></dd>\n<dt id=\"section-6.3-2.3\">Node IDs:</dt>\n          <dd style=\"margin-left: 1.5em\" id=\"section-6.3-2.4\">\n With this method, a pseudo-random Node ID value is placed within the UUID layout.\n This identifier helps ensure the bit-space for a given node is unique, resulting in UUIDs that do not conflict with any other UUID created by another node with a different node id.\n Implementations that choose to leverage an embedded node id SHOULD utilize UUIDv8. \n The node id SHOULD NOT be an IEEE 802 MAC address as per <a href=\"#Security\" class=\"xref\">Section 8</a>. \n The location and bit length are left to implementations and are outside the scope of this specification.\n Furthermore, the creation and negotiation of unique node ids among nodes is also out of scope for this specification.<a href=\"#section-6.3-2.4\" class=\"pilcrow\">¶</a>\n</dd>\n        <dd class=\"break\"></dd>\n</dl>\n<p id=\"section-6.3-3\">\n Utilization of either a Centralized Registry or Node ID are not required for implementing UUIDs in this specification. However implementations SHOULD utilize one of the two aforementioned methods if distributed UUID generation is a requirement.<a href=\"#section-6.3-3\" class=\"pilcrow\">¶</a></p>\n</section>\n</div>\n<div id=\"collision_resistance\">\n<section id=\"section-6.4\">\n        <h3 id=\"name-collision-resistance\">\n<a href=\"#section-6.4\" class=\"section-number selfRef\">6.4. </a><a href=\"#name-collision-resistance\" class=\"section-name selfRef\">Collision Resistance</a>\n        </h3>\n<p id=\"section-6.4-1\">\n Implementations SHOULD weigh the consequences of UUID collisions within their application and when deciding between UUID versions that use entropy (random) versus the other components such as <a href=\"#timestamp_granularity\" class=\"xref\">Section 6.1</a> and <a href=\"#monotonicity_counters\" class=\"xref\">Section 6.2</a>. \n This is especially true for distributed node collision resistance as defined by <a href=\"#distributed_shared_knowledge\" class=\"xref\">Section 6.3</a>.<a href=\"#section-6.4-1\" class=\"pilcrow\">¶</a></p>\n<p id=\"section-6.4-2\">\n There are two example scenarios below which help illustrate the varying seriousness of a collision within an application.<a href=\"#section-6.4-2\" class=\"pilcrow\">¶</a></p>\n<span class=\"break\"></span><dl class=\"dlNewline\" id=\"section-6.4-3\">\n          <dt id=\"section-6.4-3.1\">Low Impact</dt>\n          <dd style=\"margin-left: 1.5em\" id=\"section-6.4-3.2\">A UUID collision generated a duplicate log entry which results in incorrect statistics derived from the data. Implementations that are not negatively affected by collisions may continue with the entropy and uniqueness provided by the traditional UUID format.<a href=\"#section-6.4-3.2\" class=\"pilcrow\">¶</a>\n</dd>\n          <dd class=\"break\"></dd>\n<dt id=\"section-6.4-3.3\">High Impact:</dt>\n          <dd style=\"margin-left: 1.5em\" id=\"section-6.4-3.4\"> A duplicate key causes an airplane to receive the wrong course which puts people's lives at risk. In this scenario there is no margin for error. Collisions MUST be avoided and failure is unacceptable. Applications dealing with this type of scenario MUST employ as much collision resistance as possible within the given application context.<a href=\"#section-6.4-3.4\" class=\"pilcrow\">¶</a>\n</dd>\n        <dd class=\"break\"></dd>\n</dl>\n</section>\n</div>\n<div id=\"global_local_uniqueness\">\n<section id=\"section-6.5\">\n        <h3 id=\"name-global-and-local-uniqueness\">\n<a href=\"#section-6.5\" class=\"section-number selfRef\">6.5. </a><a href=\"#name-global-and-local-uniqueness\" class=\"section-name selfRef\">Global and Local Uniqueness</a>\n        </h3>\n<p id=\"section-6.5-1\">\n UUIDs created by this specification MAY be used to provide local uniqueness guarantees. \n For example, ensuring UUIDs created within a local application context are unique within a database MAY be sufficient for some implementations where global uniqueness outside of the application context, in other applications, or around the world is not required.<a href=\"#section-6.5-1\" class=\"pilcrow\">¶</a></p>\n<p id=\"section-6.5-2\">\n Although true global uniqueness is impossible to guarantee without a shared knowledge scheme; a shared knowledge scheme is not required by UUID to provide uniqueness guarantees.\n Implementations MAY implement a shared knowledge scheme introduced in <a href=\"#distributed_shared_knowledge\" class=\"xref\">Section 6.3</a> as they see fit to extend the uniqueness guaranteed this specification and <span>[<a href=\"#RFC4122\" class=\"xref\">RFC4122</a>]</span>.<a href=\"#section-6.5-2\" class=\"pilcrow\">¶</a></p>\n</section>\n</div>\n<div id=\"unguessability\">\n<section id=\"section-6.6\">\n        <h3 id=\"name-unguessability\">\n<a href=\"#section-6.6\" class=\"section-number selfRef\">6.6. </a><a href=\"#name-unguessability\" class=\"section-name selfRef\">Unguessability</a>\n        </h3>\n<p id=\"section-6.6-1\">\n Implementations SHOULD utilize a cryptographically secure pseudo-random number generator (CSPRNG) to provide values that are both difficult to predict (\"unguessable\") and have a low likelihood of collision (\"unique\").\n Care SHOULD be taken to ensure the CSPRNG state is properly reseeded upon state changes, such as process forks, to ensure proper CSPRNG operation.\n CSPRNG ensures the best of <a href=\"#collision_resistance\" class=\"xref\">Section 6.4</a> and <a href=\"#Security\" class=\"xref\">Section 8</a> are present in modern UUIDs.<a href=\"#section-6.6-1\" class=\"pilcrow\">¶</a></p>\n<p id=\"section-6.6-2\">\n Advice on generating cryptographic-quality random numbers can be found in <span>[<a href=\"#RFC4086\" class=\"xref\">RFC4086</a>]</span><a href=\"#section-6.6-2\" class=\"pilcrow\">¶</a></p>\n</section>\n</div>\n<div id=\"sorting\">\n<section id=\"section-6.7\">\n        <h3 id=\"name-sorting\">\n<a href=\"#section-6.7\" class=\"section-number selfRef\">6.7. </a><a href=\"#name-sorting\" class=\"section-name selfRef\">Sorting</a>\n        </h3>\n<p id=\"section-6.7-1\">\n UUIDv6 and UUIDv7 are designed so that implementations that require sorting (e.g. database indexes) SHOULD sort as opaque raw bytes, without need for parsing or introspection.<a href=\"#section-6.7-1\" class=\"pilcrow\">¶</a></p>\n<p id=\"section-6.7-2\">\n Time ordered monotonic UUIDs benefit from greater database index locality because the new values are near each other in the index. \n As a result objects are more easily clustered together for better performance.  \n The real-world differences in this approach of index locality vs random data inserts can be quite large.<a href=\"#section-6.7-2\" class=\"pilcrow\">¶</a></p>\n<p id=\"section-6.7-3\">\n UUIDs formats created by this specification SHOULD be Lexicographically sortable while in the textual representation.<a href=\"#section-6.7-3\" class=\"pilcrow\">¶</a></p>\n<p id=\"section-6.7-4\">\n UUIDs created by this specification are crafted with big-ending byte order (network byte order) in mind. If Little-endian style is required a custom UUID format SHOULD be created using UUIDv8.<a href=\"#section-6.7-4\" class=\"pilcrow\">¶</a></p>\n</section>\n</div>\n<div id=\"opacity\">\n<section id=\"section-6.8\">\n        <h3 id=\"name-opacity\">\n<a href=\"#section-6.8\" class=\"section-number selfRef\">6.8. </a><a href=\"#name-opacity\" class=\"section-name selfRef\">Opacity</a>\n        </h3>\n<p id=\"section-6.8-1\">\n UUIDs SHOULD be treated as opaque values and implementations SHOULD NOT examine the bits in a UUID to whatever extent is possible. However, where necessary, inspectors should refer to <a href=\"#variant_and_version_fields\" class=\"xref\">Section 4</a> for more information on determining UUID version and variant.<a href=\"#section-6.8-1\" class=\"pilcrow\">¶</a></p>\n</section>\n</div>\n<div id=\"database_considerations\">\n<section id=\"section-6.9\">\n        <h3 id=\"name-dbms-and-database-considera\">\n<a href=\"#section-6.9\" class=\"section-number selfRef\">6.9. </a><a href=\"#name-dbms-and-database-considera\" class=\"section-name selfRef\">DBMS and Database Considerations</a>\n        </h3>\n<p id=\"section-6.9-1\">\n For many applications, such as databases, storing UUIDs as text is unnecessarily verbose, requiring 288 bits to represent 128 bit UUID values. \n Thus, where feasible, UUIDs SHOULD be stored within database applications as the underlying 128 bit binary value.<a href=\"#section-6.9-1\" class=\"pilcrow\">¶</a></p>\n<p id=\"section-6.9-2\">\n \n For other systems, UUIDs MAY be stored in binary form or as text, as appropriate. \n The trade-offs to both approaches are as such:<a href=\"#section-6.9-2\" class=\"pilcrow\">¶</a></p>\n<ul class=\"compact\">\n<li class=\"compact\" id=\"section-6.9-3.1\">\n            <p id=\"section-6.9-3.1.1\">Storing as binary requires less space and may result in faster data access.<a href=\"#section-6.9-3.1.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"compact\" id=\"section-6.9-3.2\">\n            <p id=\"section-6.9-3.2.1\">Storing as text requires more space but may require less translation if the resulting text form is to be used after retrieval and thus maybe simpler to implement.<a href=\"#section-6.9-3.2.1\" class=\"pilcrow\">¶</a></p>\n</li>\n        </ul>\n<p id=\"section-6.9-4\">\n DBMS vendors are encouraged to provide functionality to generate and store UUID formats defined by this specification for use as identifiers or left parts of identifiers such as, but not limited to, primary keys, surrogate keys for temporal databases, foreign keys included in polymorphic relationships, and keys for key-value pairs in JSON columns and key-value databases.\n Applications using a monolithic database may find using database-generated UUIDs (as opposed to client-generate UUIDs) provides the best UUID monotonicity.\n In addition to UUIDs, additional identifiers MAY be used to ensure integrity and feedback.<a href=\"#section-6.9-4\" class=\"pilcrow\">¶</a></p>\n</section>\n</div>\n</section>\n</div>\n<div id=\"IANA\">\n<section id=\"section-7\">\n      <h2 id=\"name-iana-considerations-2\">\n<a href=\"#section-7\" class=\"section-number selfRef\">7. </a><a href=\"#name-iana-considerations-2\" class=\"section-name selfRef\">IANA Considerations</a>\n      </h2>\n<p id=\"section-7-1\">This document has no IANA actions.<a href=\"#section-7-1\" class=\"pilcrow\">¶</a></p>\n</section>\n</div>\n<div id=\"Security\">\n<section id=\"section-8\">\n      <h2 id=\"name-security-considerations-2\">\n<a href=\"#section-8\" class=\"section-number selfRef\">8. </a><a href=\"#name-security-considerations-2\" class=\"section-name selfRef\">Security Considerations</a>\n      </h2>\n<p id=\"section-8-1\"> \n MAC addresses pose inherent security risks and SHOULD not be used within a UUID. \n Instead CSPRNG data SHOULD be selected from a source with sufficient entropy to ensure guaranteed\n uniqueness among UUID generation. See <a href=\"#unguessability\" class=\"xref\">Section 6.6</a> for more information.<a href=\"#section-8-1\" class=\"pilcrow\">¶</a></p>\n<p id=\"section-8-2\">\n Timestamps embedded in the UUID do pose a very small attack surface. The timestamp in conjunction with \n an embedded counter does signal the order of creation for a given UUID and it's corresponding data but \n does not define anything about the data itself or the application as a whole. If UUIDs are required for\n use with any security operation within an application context in any shape or form then <span>[<a href=\"#RFC4122\" class=\"xref\">RFC4122</a>]</span> UUIDv4 SHOULD be utilized.<a href=\"#section-8-2\" class=\"pilcrow\">¶</a></p>\n</section>\n</div>\n<div id=\"Acknowledgements\">\n<section id=\"section-9\">\n      <h2 id=\"name-acknowledgements-2\">\n<a href=\"#section-9\" class=\"section-number selfRef\">9. </a><a href=\"#name-acknowledgements-2\" class=\"section-name selfRef\">Acknowledgements</a>\n      </h2>\n<p id=\"section-9-1\">The authors gratefully acknowledge the contributions of \n Ben Campbell,\n Ben Ramsey,\n Fabio Lima,\n Gonzalo Salgueiro, \n Martin Thomson,\n Murray S. Kucherawy,\n Rick van Rein,\n Rob Wilton,\n Sean Leonard,\n Theodore Y. Ts'o.,\n Robert Kieffer,\n sergeyprokhorenko,\n LiosK\n As well as all of those in the IETF community and on GitHub to who contributed to the discussions which resulted in this document.<a href=\"#section-9-1\" class=\"pilcrow\">¶</a></p>\n</section>\n</div>\n<section id=\"section-10\">\n      <h2 id=\"name-normative-references-2\">\n<a href=\"#section-10\" class=\"section-number selfRef\">10. </a><a href=\"#name-normative-references-2\" class=\"section-name selfRef\">Normative References</a>\n      </h2>\n<dl class=\"references\">\n<dt id=\"RFC2119\">[RFC2119]</dt>\n      <dd>\n<span class=\"refAuthor\">Bradner, S.</span>, <span class=\"refTitle\">\"Key words for use in RFCs to Indicate Requirement Levels\"</span>, <span class=\"seriesInfo\">BCP 14</span>, <span class=\"seriesInfo\">RFC 2119</span>, <span class=\"seriesInfo\">DOI 10.17487/RFC2119</span>, <time datetime=\"1997-03\" class=\"refDate\">March 1997</time>, <span>&lt;<a href=\"https://www.rfc-editor.org/info/rfc2119\">https://www.rfc-editor.org/info/rfc2119</a>&gt;</span>. </dd>\n<dd class=\"break\"></dd>\n<dt id=\"RFC8174\">[RFC8174]</dt>\n      <dd>\n<span class=\"refAuthor\">Leiba, B.</span>, <span class=\"refTitle\">\"Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words\"</span>, <span class=\"seriesInfo\">BCP 14</span>, <span class=\"seriesInfo\">RFC 8174</span>, <span class=\"seriesInfo\">DOI 10.17487/RFC8174</span>, <time datetime=\"2017-05\" class=\"refDate\">May 2017</time>, <span>&lt;<a href=\"https://www.rfc-editor.org/info/rfc8174\">https://www.rfc-editor.org/info/rfc8174</a>&gt;</span>. </dd>\n<dd class=\"break\"></dd>\n<dt id=\"RFC4122\">[RFC4122]</dt>\n      <dd>\n<span class=\"refAuthor\">Leach, P.</span>, <span class=\"refAuthor\">Mealling, M.</span>, and <span class=\"refAuthor\">R. Salz</span>, <span class=\"refTitle\">\"A Universally Unique IDentifier (UUID) URN Namespace\"</span>, <span class=\"seriesInfo\">RFC 4122</span>, <span class=\"seriesInfo\">DOI 10.17487/RFC4122</span>, <time datetime=\"2005-07\" class=\"refDate\">July 2005</time>, <span>&lt;<a href=\"https://www.rfc-editor.org/info/rfc4122\">https://www.rfc-editor.org/info/rfc4122</a>&gt;</span>. </dd>\n<dd class=\"break\"></dd>\n<dt id=\"RFC4086\">[RFC4086]</dt>\n    <dd>\n<span class=\"refAuthor\">Eastlake 3rd, D.</span>, <span class=\"refAuthor\">Schiller, J.</span>, and <span class=\"refAuthor\">S. Crocker</span>, <span class=\"refTitle\">\"Randomness Requirements for Security\"</span>, <span class=\"seriesInfo\">RFC 4086</span>, <span class=\"seriesInfo\">DOI 10.17487/RFC4086</span>, <time datetime=\"2005-06\" class=\"refDate\">June 2005</time>, <span>&lt;<a href=\"https://www.rfc-editor.org/info/rfc4086\">https://www.rfc-editor.org/info/rfc4086</a>&gt;</span>. </dd>\n<dd class=\"break\"></dd>\n</dl>\n</section>\n<section id=\"section-11\">\n      <h2 id=\"name-informative-references-2\">\n<a href=\"#section-11\" class=\"section-number selfRef\">11. </a><a href=\"#name-informative-references-2\" class=\"section-name selfRef\">Informative References</a>\n      </h2>\n<dl class=\"references\">\n<dt id=\"LexicalUUID\">[LexicalUUID]</dt>\n      <dd>\n<span class=\"refAuthor\">Twitter</span>, <span class=\"refTitle\">\"A Scala client for Cassandra\"</span>, <span class=\"seriesInfo\">commit f6da4e0</span>, <time datetime=\"2012-11\" class=\"refDate\">November 2012</time>, <span>&lt;<a href=\"https://github.com/twitter-archive/cassie\">https://github.com/twitter-archive/cassie</a>&gt;</span>. </dd>\n<dd class=\"break\"></dd>\n<dt id=\"Snowflake\">[Snowflake]</dt>\n      <dd>\n<span class=\"refAuthor\">Twitter</span>, <span class=\"refTitle\">\"Snowflake is a network service for generating unique ID numbers at high scale with some simple guarantees.\"</span>, <span class=\"seriesInfo\">Commit b3f6a3c</span>, <time datetime=\"2014-05\" class=\"refDate\">May 2014</time>, <span>&lt;<a href=\"https://github.com/twitter-archive/snowflake/releases/tag/snowflake-2010\">https://github.com/twitter-archive/snowflake/releases/tag/snowflake-2010</a>&gt;</span>. </dd>\n<dd class=\"break\"></dd>\n<dt id=\"Flake\">[Flake]</dt>\n      <dd>\n<span class=\"refAuthor\">Boundary</span>, <span class=\"refTitle\">\"Flake: A decentralized, k-ordered id generation service in Erlang\"</span>, <span class=\"seriesInfo\">Commit 15c933a</span>, <time datetime=\"2017-02\" class=\"refDate\">February 2017</time>, <span>&lt;<a href=\"https://github.com/boundary/flake\">https://github.com/boundary/flake</a>&gt;</span>. </dd>\n<dd class=\"break\"></dd>\n<dt id=\"ShardingID\">[ShardingID]</dt>\n      <dd>\n<span class=\"refAuthor\">Instagram Engineering</span>, <span class=\"refTitle\">\"Sharding &amp; IDs at Instagram\"</span>, <time datetime=\"2012-12\" class=\"refDate\">December 2012</time>, <span>&lt;<a href=\"https://instagram-engineering.com/sharding-ids-at-instagram-1cf5a71e5a5c\">https://instagram-engineering.com/sharding-ids-at-instagram-1cf5a71e5a5c</a>&gt;</span>. </dd>\n<dd class=\"break\"></dd>\n<dt id=\"KSUID\">[KSUID]</dt>\n      <dd>\n<span class=\"refAuthor\">Segment</span>, <span class=\"refTitle\">\"K-Sortable Globally Unique IDs\"</span>, <span class=\"seriesInfo\">Commit bf376a7</span>, <time datetime=\"2020-07\" class=\"refDate\">July 2020</time>, <span>&lt;<a href=\"https://github.com/segmentio/ksuid\">https://github.com/segmentio/ksuid</a>&gt;</span>. </dd>\n<dd class=\"break\"></dd>\n<dt id=\"Elasticflake\">[Elasticflake]</dt>\n      <dd>\n<span class=\"refAuthor\">Pearcy, P.</span>, <span class=\"refTitle\">\"Sequential UUID / Flake ID generator pulled out of elasticsearch common\"</span>, <span class=\"seriesInfo\">Commit dd71c21</span>, <time datetime=\"2015-01\" class=\"refDate\">January 2015</time>, <span>&lt;<a href=\"https://github.com/ppearcy/elasticflake\">https://github.com/ppearcy/elasticflake</a>&gt;</span>. </dd>\n<dd class=\"break\"></dd>\n<dt id=\"FlakeID\">[FlakeID]</dt>\n      <dd>\n<span class=\"refAuthor\">Pawlak, T.</span>, <span class=\"refTitle\">\"Flake ID Generator\"</span>, <span class=\"seriesInfo\">Commit fcd6a2f</span>, <time datetime=\"2020-04\" class=\"refDate\">April 2020</time>, <span>&lt;<a href=\"https://github.com/T-PWK/flake-idgen\">https://github.com/T-PWK/flake-idgen</a>&gt;</span>. </dd>\n<dd class=\"break\"></dd>\n<dt id=\"Sonyflake\">[Sonyflake]</dt>\n      <dd>\n<span class=\"refAuthor\">Sony</span>, <span class=\"refTitle\">\"A distributed unique ID generator inspired by Twitter's Snowflake\"</span>, <span class=\"seriesInfo\">Commit 848d664</span>, <time datetime=\"2020-08\" class=\"refDate\">August 2020</time>, <span>&lt;<a href=\"https://github.com/sony/sonyflake\">https://github.com/sony/sonyflake</a>&gt;</span>. </dd>\n<dd class=\"break\"></dd>\n<dt id=\"orderedUuid\">[orderedUuid]</dt>\n      <dd>\n<span class=\"refAuthor\">Cabrera, IT.</span>, <span class=\"refTitle\">\"Laravel: The mysterious \"Ordered UUID\"\"</span>, <time datetime=\"2020-01\" class=\"refDate\">January 2020</time>, <span>&lt;<a href=\"https://itnext.io/laravel-the-mysterious-ordered-uuid-29e7500b4f8\">https://itnext.io/laravel-the-mysterious-ordered-uuid-29e7500b4f8</a>&gt;</span>. </dd>\n<dd class=\"break\"></dd>\n<dt id=\"COMBGUID\">[COMBGUID]</dt>\n      <dd>\n<span class=\"refAuthor\">Tallent, R.</span>, <span class=\"refTitle\">\"Creating sequential GUIDs in C# for MSSQL or PostgreSql\"</span>, <span class=\"seriesInfo\">Commit 2759820</span>, <time datetime=\"2020-12\" class=\"refDate\">December 2020</time>, <span>&lt;<a href=\"https://github.com/richardtallent/RT.Comb\">https://github.com/richardtallent/RT.Comb</a>&gt;</span>. </dd>\n<dd class=\"break\"></dd>\n<dt id=\"ULID\">[ULID]</dt>\n      <dd>\n<span class=\"refAuthor\">Feerasta, A.</span>, <span class=\"refTitle\">\"Universally Unique Lexicographically Sortable Identifier\"</span>, <span class=\"seriesInfo\">Commit d0c7170</span>, <time datetime=\"2019-05\" class=\"refDate\">May 2019</time>, <span>&lt;<a href=\"https://github.com/ulid/spec\">https://github.com/ulid/spec</a>&gt;</span>. </dd>\n<dd class=\"break\"></dd>\n<dt id=\"SID\">[SID]</dt>\n      <dd>\n<span class=\"refAuthor\">Chilton, A.</span>, <span class=\"refTitle\">\"sid : generate sortable identifiers\"</span>, <span class=\"seriesInfo\">Commit 660e947</span>, <time datetime=\"2019-06\" class=\"refDate\">June 2019</time>, <span>&lt;<a href=\"https://github.com/chilts/sid\">https://github.com/chilts/sid</a>&gt;</span>. </dd>\n<dd class=\"break\"></dd>\n<dt id=\"pushID\">[pushID]</dt>\n      <dd>\n<span class=\"refAuthor\">Google</span>, <span class=\"refTitle\">\"The 2^120 Ways to Ensure Unique Identifiers\"</span>, <time datetime=\"2015-02\" class=\"refDate\">February 2015</time>, <span>&lt;<a href=\"https://firebase.googleblog.com/2015/02/the-2120-ways-to-ensure-unique_68.html\">https://firebase.googleblog.com/2015/02/the-2120-ways-to-ensure-unique_68.html</a>&gt;</span>. </dd>\n<dd class=\"break\"></dd>\n<dt id=\"XID\">[XID]</dt>\n      <dd>\n<span class=\"refAuthor\">Poitrey, O.</span>, <span class=\"refTitle\">\"Globally Unique ID Generator\"</span>, <span class=\"seriesInfo\">Commit efa678f</span>, <time datetime=\"2020-10\" class=\"refDate\">October 2020</time>, <span>&lt;<a href=\"https://github.com/rs/xid\">https://github.com/rs/xid</a>&gt;</span>. </dd>\n<dd class=\"break\"></dd>\n<dt id=\"ObjectID\">[ObjectID]</dt>\n      <dd>\n<span class=\"refAuthor\">MongoDB</span>, <span class=\"refTitle\">\"ObjectId - MongoDB Manual\"</span>, <span>&lt;<a href=\"https://docs.mongodb.com/manual/reference/method/ObjectId/\">https://docs.mongodb.com/manual/reference/method/ObjectId/</a>&gt;</span>. </dd>\n<dd class=\"break\"></dd>\n<dt id=\"CUID\">[CUID]</dt>\n      <dd>\n<span class=\"refAuthor\">Elliott, E.</span>, <span class=\"refTitle\">\"Collision-resistant ids optimized for horizontal scaling and performance.\"</span>, <span class=\"seriesInfo\">Commit 215b27b</span>, <time datetime=\"2020-10\" class=\"refDate\">October 2020</time>, <span>&lt;<a href=\"https://github.com/ericelliott/cuid\">https://github.com/ericelliott/cuid</a>&gt;</span>. </dd>\n<dd class=\"break\"></dd>\n<dt id=\"IEEE754\">[IEEE754]</dt>\n    <dd>\n<span class=\"refAuthor\">IEEE</span>, <span class=\"refTitle\">\"IEEE Standard for Floating-Point Arithmetic.\"</span>, <span class=\"seriesInfo\">Series 754-2019</span>, <time datetime=\"2019-07\" class=\"refDate\">July 2019</time>, <span>&lt;<a href=\"https://standards.ieee.org/ieee/754/6210/\">https://standards.ieee.org/ieee/754/6210/</a>&gt;</span>. </dd>\n<dd class=\"break\"></dd>\n</dl>\n</section>\n<div id=\"example_code\">\n<section id=\"appendix-A\">\n      <h2 id=\"name-example-code\">\n<a href=\"#appendix-A\" class=\"section-number selfRef\">Appendix A. </a><a href=\"#name-example-code\" class=\"section-name selfRef\">Example Code</a>\n      </h2>\n<div id=\"creating_a_uuidv6_value\">\n<section id=\"appendix-A.1\">\n        <h3 id=\"name-creating-a-uuidv6-value\">\n<a href=\"#appendix-A.1\" class=\"section-number selfRef\">A.1. </a><a href=\"#name-creating-a-uuidv6-value\" class=\"section-name selfRef\">Creating a UUIDv6 Value</a>\n        </h3>\n<p id=\"appendix-A.1-1\">This section details a function in C which converts from a UUID version 1 to version 6:<a href=\"#appendix-A.1-1\" class=\"pilcrow\">¶</a></p>\n<span id=\"name-uuidv6-function-in-c\"></span><figure id=\"figure-6\">\n          <div class=\"alignLeft art-text artwork\" id=\"appendix-A.1-2.1\">\n<pre>\n#include &lt;stdio.h&gt;\n#include &lt;stdint.h&gt;\n#include &lt;inttypes.h&gt;\n#include &lt;arpa/inet.h&gt;\n#include &lt;uuid/uuid.h&gt;\n\n/* Converts UUID version 1 to version 6 in place. */\nvoid uuidv1tov6(uuid_t u) {\n\n  uint64_t ut;\n  unsigned char *up = (unsigned char *)u;\n\n  // load ut with the first 64 bits of the UUID\n  ut = ((uint64_t)ntohl(*((uint32_t*)up))) &lt;&lt; 32;\n  ut |= ((uint64_t)ntohl(*((uint32_t*)&amp;up[4])));\n\n  // dance the bit-shift...\n  ut =\n    ((ut &gt;&gt; 32) &amp; 0x0FFF) | // 12 least significant bits\n    (0x6000) | // version number\n    ((ut &gt;&gt; 28) &amp; 0x0000000FFFFF0000) | // next 20 bits\n    ((ut &lt;&lt; 20) &amp; 0x000FFFF000000000) | // next 16 bits\n    (ut &lt;&lt; 52); // 12 most significant bits\n\n  // store back in UUID\n  *((uint32_t*)up) = htonl((uint32_t)(ut &gt;&gt; 32));\n  *((uint32_t*)&amp;up[4]) = htonl((uint32_t)(ut));\n\n}\n</pre>\n</div>\n<figcaption><a href=\"#figure-6\" class=\"selfRef\">Figure 6</a>:\n<a href=\"#name-uuidv6-function-in-c\" class=\"selfRef\">UUIDv6 Function in C</a>\n          </figcaption></figure>\n</section>\n</div>\n<div id=\"creating_a_uuidv7_value\">\n<section id=\"appendix-A.2\">\n        <h3 id=\"name-creating-a-uuidv7-value\">\n<a href=\"#appendix-A.2\" class=\"section-number selfRef\">A.2. </a><a href=\"#name-creating-a-uuidv7-value\" class=\"section-name selfRef\">Creating a UUIDv7 Value</a>\n        </h3>\n<span id=\"name-uuidv7-function-in-c\"></span><figure id=\"figure-7\">\n          <div class=\"alignLeft art-text artwork\" id=\"appendix-A.2-1.1\">\n<pre>\n#include &lt;stdio.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;stdint.h&gt;\n#include &lt;string.h&gt;\n#include &lt;time.h&gt;\n\n// ...\n\n// csprng data source\nFILE *rndf;\nrndf = fopen(\"/dev/urandom\", \"r\");\nif (rndf == 0) {\n    printf(\"fopen /dev/urandom error\\n\");\n    return 1;\n}\n\n// ...\n\n// generate one UUIDv7E\nuint8_t u[16];\nstruct timespec ts;\nint ret;\n\nret = clock_gettime(CLOCK_REALTIME, &amp;ts);\nif (ret != 0) {\n    printf(\"clock_gettime error: %d\\n\", ret);\n    return 1;\n}\n\nuint64_t tms;\n\ntms = ((uint64_t)ts.tv_sec) * 1000;\ntms += ((uint64_t)ts.tv_nsec) / 1000000;\n\nmemset(u, 0, 16);\n\nfread(&amp;u[6], 10, 1, rndf); // fill everything after the timestamp with random bytes\n\n*((uint64_t*)(u)) |= htonll(tms &lt;&lt; 16); // shift time into first 48 bits and OR into place\n\nu[8] = 0x80 | (u[8] &amp; 0x3F); // set variant field, top two bits are 1, 0\nu[6] = 0x70 | (u[6] &amp; 0x0F); // set version field, top four bits are 0, 1, 1, 1\n</pre>\n</div>\n<figcaption><a href=\"#figure-7\" class=\"selfRef\">Figure 7</a>:\n<a href=\"#name-uuidv7-function-in-c\" class=\"selfRef\">UUIDv7 Function in C</a>\n          </figcaption></figure>\n</section>\n</div>\n<div id=\"creating_a_uuidv8_value\">\n<section id=\"appendix-A.3\">\n        <h3 id=\"name-creating-a-uuidv8-value\">\n<a href=\"#appendix-A.3\" class=\"section-number selfRef\">A.3. </a><a href=\"#name-creating-a-uuidv8-value\" class=\"section-name selfRef\">Creating a UUIDv8 Value</a>\n        </h3>\n<p id=\"appendix-A.3-1\">UUIDv8 will vary greatly from implementation to implementation.<a href=\"#appendix-A.3-1\" class=\"pilcrow\">¶</a></p>\n<p id=\"appendix-A.3-2\">The following example utilizes:<a href=\"#appendix-A.3-2\" class=\"pilcrow\">¶</a></p>\n<ul class=\"normal\">\n<li class=\"normal\" id=\"appendix-A.3-3.1\">\n            <p id=\"appendix-A.3-3.1.1\">32 bit custom-epoch timestamp (seconds elapsed since 2020-01-01 00:00:00 UTC)<a href=\"#appendix-A.3-3.1.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"normal\" id=\"appendix-A.3-3.2\">\n            <p id=\"appendix-A.3-3.2.1\">16 bit exotic resolution (~15 microsecond) subsecond timestamp encoded using the fractional representation<a href=\"#appendix-A.3-3.2.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"normal\" id=\"appendix-A.3-3.3\">\n            <p id=\"appendix-A.3-3.3.1\">58 bit random number<a href=\"#appendix-A.3-3.3.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"normal\" id=\"appendix-A.3-3.4\">\n            <p id=\"appendix-A.3-3.4.1\">8 bit application-specific unique node ID<a href=\"#appendix-A.3-3.4.1\" class=\"pilcrow\">¶</a></p>\n</li>\n          <li class=\"normal\" id=\"appendix-A.3-3.5\">\n            <p id=\"appendix-A.3-3.5.1\">8 bit rolling sequence number<a href=\"#appendix-A.3-3.5.1\" class=\"pilcrow\">¶</a></p>\n</li>\n        </ul>\n<span id=\"name-uuidv8-function-in-c\"></span><figure id=\"figure-8\">\n          <div class=\"alignLeft art-text artwork\" id=\"appendix-A.3-4.1\">\n<pre>\n#include &lt;stdint.h&gt;\n#include &lt;time.h&gt;\n\nint get_random_bytes(uint8_t *buffer, int count) {\n  // ...\n}\n\nint generate_uuidv8(uint8_t *uuid, uint8_t node_id) {\n  struct timespec tp;\n  if (clock_gettime(CLOCK_REALTIME, &amp;tp) != 0)\n    return -1; // real-time clock error\n\n  // 32 bit biased timestamp (seconds elapsed since 2020-01-01 00:00:00 UTC)\n  uint32_t timestamp_sec = tp.tv_sec - 1577836800;\n  uuid[0] = timestamp_sec &gt;&gt; 24;\n  uuid[1] = timestamp_sec &gt;&gt; 16;\n  uuid[2] = timestamp_sec &gt;&gt; 8;\n  uuid[3] = timestamp_sec;\n\n  // 16 bit subsecond fraction (~15 microsecond resolution)\n  uint16_t timestamp_subsec = ((uint64_t)tp.tv_nsec &lt;&lt; 16) / 1000000000;\n  uuid[4] = timestamp_subsec &gt;&gt; 8;\n  uuid[5] = timestamp_subsec;\n\n  // 58 bit random number and required ver and var fields\n  if (get_random_bytes(&amp;uuid[6], 8) != 0)\n    return -1; // random number generator error\n  uuid[6] = 0x80 | (uuid[6] &amp; 0x0f);\n  uuid[8] = 0x80 | (uuid[8] &amp; 0x3f);\n\n  // 8 bit application-specific node ID to guarantee application-wide uniqueness\n  uuid[14] = node_id;\n\n  // 8 bit rolling sequence number to help ensure process-wide uniqueness\n  static uint8_t sequence = 0;\n  uuid[15] = sequence++; // NOTE: unprotected from race conditions\n\n  return 0;\n}\n</pre>\n</div>\n<figcaption><a href=\"#figure-8\" class=\"selfRef\">Figure 8</a>:\n<a href=\"#name-uuidv8-function-in-c\" class=\"selfRef\">UUIDv8 Function in C</a>\n          </figcaption></figure>\n</section>\n</div>\n</section>\n</div>\n<div id=\"test_vectors\">\n<section id=\"appendix-B\">\n      <h2 id=\"name-test-vectors\">\n<a href=\"#appendix-B\" class=\"section-number selfRef\">Appendix B. </a><a href=\"#name-test-vectors\" class=\"section-name selfRef\">Test Vectors</a>\n      </h2>\n<p id=\"appendix-B-1\">Both UUIDv1 and UUIDv6 test vectors utilize the same 60 bit timestamp: 0x1EC9414C232AB00 (138648505420000000) Tuesday, February 22, 2022 2:22:22.000000 PM GMT-05:00<a href=\"#appendix-B-1\" class=\"pilcrow\">¶</a></p>\n<p id=\"appendix-B-2\">Both UUIDv1 and UUIDv6 utilize the same values in clk_seq_hi_res, clock_seq_low, and node. All of which have been generated with random data.<a href=\"#appendix-B-2\" class=\"pilcrow\">¶</a></p>\n<span id=\"name-test-vector-timestamp-pseud\"></span><figure id=\"figure-9\">\n        <div class=\"alignLeft art-text artwork\" id=\"appendix-B-3.1\">\n<pre>\n# Unix Nanosecond precision to Gregorian 100-nanosecond intervals\ngregorian_100_ns = (Unix_64_bit_nanoseconds / 100) + gregorian_Unix_offset\n\n# Gregorian to Unix Offset:\n# The number of 100-ns intervals between the\n# UUID epoch 1582-10-15 00:00:00 and the Unix epoch 1970-01-01 00:00:00.\n# gregorian_Unix_offset = 0x01b21dd213814000 or 122192928000000000\n\n# Unix 64 bit Nanosecond Timestamp:\n# Unix NS: Tuesday, February 22, 2022 2:22:22 PM GMT-05:00\n# Unix_64_bit_nanoseconds = 0x16D6320C3D4DCC00 or 1645557742000000000\n\n# Work:\n# gregorian_100_ns = (1645557742000000000 / 100) + 122192928000000000\n# (138648505420000000 - 122192928000000000) * 100 = Unix_64_bit_nanoseconds\n\n# Final:\n# gregorian_100_ns = 0x1EC9414C232AB00 or 138648505420000000\n\n# Original: 000111101100100101000001010011000010001100101010101100000000\n# UUIDv1:   11000010001100101010101100000000|1001010000010100|0001|000111101100\n# UUIDv6:   00011110110010010100000101001100|0010001100101010|0110|101100000000\n</pre>\n</div>\n<figcaption><a href=\"#figure-9\" class=\"selfRef\">Figure 9</a>:\n<a href=\"#name-test-vector-timestamp-pseud\" class=\"selfRef\">Test Vector Timestamp Pseudo-code</a>\n        </figcaption></figure>\n<div id=\"uuidv6_example\">\n<section id=\"appendix-B.1\">\n        <h3 id=\"name-example-of-a-uuidv6-value\">\n<a href=\"#appendix-B.1\" class=\"section-number selfRef\">B.1. </a><a href=\"#name-example-of-a-uuidv6-value\" class=\"section-name selfRef\">Example of a UUIDv6 Value</a>\n        </h3>\n<span id=\"name-uuidv1-example-test-vector\"></span><figure id=\"figure-10\">\n          <div class=\"alignLeft art-text artwork\" id=\"appendix-B.1-1.1\">\n<pre>\n----------------------------------------------\nfield                 bits    value_hex\n----------------------------------------------\ntime_low              32      0xC232AB00\ntime_mid              16      0x9414\ntime_hi_and_version   16      0x11EC\nclk_seq_hi_res         8      0xB3\nclock_seq_low          8      0xC8\nnode                  48      0x9E6BDECED846\n----------------------------------------------\ntotal                128\n----------------------------------------------\nfinal_hex: C232AB00-9414-11EC-B3C8-9E6BDECED846\n</pre>\n</div>\n<figcaption><a href=\"#figure-10\" class=\"selfRef\">Figure 10</a>:\n<a href=\"#name-uuidv1-example-test-vector\" class=\"selfRef\">UUIDv1 Example Test Vector</a>\n          </figcaption></figure>\n<span id=\"name-uuidv6-example-test-vector\"></span><figure id=\"figure-11\">\n          <div class=\"alignLeft art-text artwork\" id=\"appendix-B.1-2.1\">\n<pre>\n-----------------------------------------------\nfield                 bits    value_hex\n-----------------------------------------------\ntime_high              32      0x1EC9414C\ntime_mid               16      0x232A\ntime_low_and_version   16      0x6B00\nclk_seq_hi_res          8      0xB3\nclock_seq_low           8      0xC8\nnode                   48      0x9E6BDECED846\n-----------------------------------------------\ntotal                 128\n-----------------------------------------------\nfinal_hex: 1EC9414C-232A-6B00-B3C8-9E6BDECED846\n</pre>\n</div>\n<figcaption><a href=\"#figure-11\" class=\"selfRef\">Figure 11</a>:\n<a href=\"#name-uuidv6-example-test-vector\" class=\"selfRef\">UUIDv6 Example Test Vector</a>\n          </figcaption></figure>\n</section>\n</div>\n<div id=\"uuidv7_example\">\n<section id=\"appendix-B.2\">\n        <h3 id=\"name-example-of-a-uuidv7-value\">\n<a href=\"#appendix-B.2\" class=\"section-number selfRef\">B.2. </a><a href=\"#name-example-of-a-uuidv7-value\" class=\"section-name selfRef\">Example of a UUIDv7 Value</a>\n        </h3>\n<p id=\"appendix-B.2-1\">This example UUIDv7 test vector utilizes a well-known 32 bit Unix epoch with additional millisecond precision to fill the first 48 bits<a href=\"#appendix-B.2-1\" class=\"pilcrow\">¶</a></p>\n<p id=\"appendix-B.2-2\">rand_a and rand_b are filled with random data.<a href=\"#appendix-B.2-2\" class=\"pilcrow\">¶</a></p>\n<p id=\"appendix-B.2-3\">The timestamp is Tuesday, February 22, 2022 2:22:22.00 PM GMT-05:00 represented as 0x17F22E279B0 or 1645557742000<a href=\"#appendix-B.2-3\" class=\"pilcrow\">¶</a></p>\n<span id=\"name-uuidv7-example-test-vector\"></span><figure id=\"figure-12\">\n          <div class=\"alignLeft art-text artwork\" id=\"appendix-B.2-4.1\">\n<pre>\n-------------------------------\nfield      bits    value\n-------------------------------\nunix_ts_ms   48    0x17F22E279B0\nvar           4    0x7\nrand_a       12    0xCC3\nvar           2    b10\nrand_b       62    0x18C4DC0C0C07398F\n-------------------------------\ntotal       128\n-------------------------------\nfinal: 017F22E2-79B0-7CC3-98C4-DC0C0C07398F\n</pre>\n</div>\n<figcaption><a href=\"#figure-12\" class=\"selfRef\">Figure 12</a>:\n<a href=\"#name-uuidv7-example-test-vector\" class=\"selfRef\">UUIDv7 Example Test Vector</a>\n          </figcaption></figure>\n</section>\n</div>\n<div id=\"uuidv8_example\">\n<section id=\"appendix-B.3\">\n        <h3 id=\"name-example-of-a-uuidv8-value\">\n<a href=\"#appendix-B.3\" class=\"section-number selfRef\">B.3. </a><a href=\"#name-example-of-a-uuidv8-value\" class=\"section-name selfRef\">Example of a UUIDv8 Value</a>\n        </h3>\n<p id=\"appendix-B.3-1\">This example UUIDv8 test vector utilizes a well-known 64 bit Unix epoch with nanosecond precision, truncated to the least-significant, right-most, bits to fill the first 48 bits through version.<a href=\"#appendix-B.3-1\" class=\"pilcrow\">¶</a></p>\n<p id=\"appendix-B.3-2\">The next two segments of custom_b and custom_c are are filled with random data.<a href=\"#appendix-B.3-2\" class=\"pilcrow\">¶</a></p>\n<p id=\"appendix-B.3-3\">Timestamp is Tuesday, February 22, 2022 2:22:22.000000 PM GMT-05:00 represented as 0x16D6320C3D4DCC00 or 1645557742000000000<a href=\"#appendix-B.3-3\" class=\"pilcrow\">¶</a></p>\n<p id=\"appendix-B.3-4\">It should be noted that this example is just to illustrate one scenario for UUIDv8. Test vectors will likely be implementation specific and vary greatly from this simple example.<a href=\"#appendix-B.3-4\" class=\"pilcrow\">¶</a></p>\n<span id=\"name-uuidv8-example-test-vector\"></span><figure id=\"figure-13\">\n          <div class=\"alignLeft art-text artwork\" id=\"appendix-B.3-5.1\">\n<pre>\n-------------------------------\nfield      bits    value\n-------------------------------\ncustom_a     48    0x320C3D4DCC00\nver           4    0x8\ncustom_b     12    0x75B\nvar           2    b10\ncustom_c     62    0xEC932D5F69181C0\n-------------------------------\ntotal       128\n-------------------------------\nfinal: 320C3D4D-CC00-875B-8EC9-32D5F69181C0\n</pre>\n</div>\n<figcaption><a href=\"#figure-13\" class=\"selfRef\">Figure 13</a>:\n<a href=\"#name-uuidv8-example-test-vector\" class=\"selfRef\">UUIDv8 Example Test Vector</a>\n          </figcaption></figure>\n</section>\n</div>\n</section>\n</div>\n<div id=\"var_tables\">\n<section id=\"appendix-C\">\n      <h2 id=\"name-version-and-variant-tables\">\n<a href=\"#appendix-C\" class=\"section-number selfRef\">Appendix C. </a><a href=\"#name-version-and-variant-tables\" class=\"section-name selfRef\">Version and Variant Tables</a>\n      </h2>\n<div id=\"old_var_table\">\n<section id=\"appendix-C.1\">\n        <h3 id=\"name-variant-10xx-versions\">\n<a href=\"#appendix-C.1\" class=\"section-number selfRef\">C.1. </a><a href=\"#name-variant-10xx-versions\" class=\"section-name selfRef\">Variant 10xx Versions</a>\n        </h3>\n<span id=\"name-all-uuid-variant-10xx-8-9-a\"></span><table class=\"center\" id=\"table-2\">\n          <caption>\n<a href=\"#table-2\" class=\"selfRef\">Table 2</a>:\n<a href=\"#name-all-uuid-variant-10xx-8-9-a\" class=\"selfRef\">All UUID variant 10xx (8/9/A/B) version definitions.</a>\n          </caption>\n<thead>\n            <tr>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">Msb0</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">Msb1</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">Msb2</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">Msb3</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">Version</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">Description</td>\n            </tr>\n          </thead>\n          <tbody>\n            <tr>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">0</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">0</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">0</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">0</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">0</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">Unused</td>\n            </tr>\n            <tr>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">0</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">0</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">0</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">1</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">1</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">The Gregorian time-based UUID from in <span>[<a href=\"#RFC4122\" class=\"xref\">RFC4122</a>], <a href=\"https://rfc-editor.org/rfc/rfc4122#section-4.1.3\" class=\"relref\">Section 4.1.3</a></span>\n</td>\n            </tr>\n            <tr>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">0</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">0</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">1</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">0</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">2</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">DCE Security version, with embedded POSIX UIDs from <span>[<a href=\"#RFC4122\" class=\"xref\">RFC4122</a>], <a href=\"https://rfc-editor.org/rfc/rfc4122#section-4.1.3\" class=\"relref\">Section 4.1.3</a></span>\n</td>\n            </tr>\n            <tr>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">0</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">0</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">1</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">1</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">3</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">The name-based version specified in <span>[<a href=\"#RFC4122\" class=\"xref\">RFC4122</a>], <a href=\"https://rfc-editor.org/rfc/rfc4122#section-4.1.3\" class=\"relref\">Section 4.1.3</a></span> that uses MD5 hashing.</td>\n            </tr>\n            <tr>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">0</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">1</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">0</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">0</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">4</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">The randomly or pseudo-randomly generated version specified in <span>[<a href=\"#RFC4122\" class=\"xref\">RFC4122</a>], <a href=\"https://rfc-editor.org/rfc/rfc4122#section-4.1.3\" class=\"relref\">Section 4.1.3</a></span>.</td>\n            </tr>\n            <tr>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">0</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">1</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">0</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">1</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">5</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">The name-based version specified in <span>[<a href=\"#RFC4122\" class=\"xref\">RFC4122</a>], <a href=\"https://rfc-editor.org/rfc/rfc4122#section-4.1.3\" class=\"relref\">Section 4.1.3</a></span> that uses SHA-1 hashing.</td>\n            </tr>\n            <tr>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">0</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">1</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">1</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">0</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">6</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">Reordered Gregorian time-based UUID specified in this document.</td>\n            </tr>\n            <tr>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">0</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">1</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">1</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">1</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">7</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">Unix Epoch time-based UUID specified in this document.</td>\n            </tr>\n            <tr>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">1</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">0</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">0</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">0</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">8</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">Reserved for custom UUID formats specified in this document.</td>\n            </tr>\n            <tr>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">1</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">0</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">0</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">1</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">9</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">Reserved for future definition.</td>\n            </tr>\n            <tr>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">1</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">0</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">1</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">0</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">10</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">Reserved for future definition.</td>\n            </tr>\n            <tr>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">1</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">0</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">1</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">1</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">11</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">Reserved for future definition.</td>\n            </tr>\n            <tr>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">1</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">1</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">0</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">0</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">12</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">Reserved for future definition.</td>\n            </tr>\n            <tr>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">1</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">1</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">0</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">1</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">13</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">Reserved for future definition.</td>\n            </tr>\n            <tr>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">1</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">1</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">1</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">0</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">14</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">Reserved for future definition.</td>\n            </tr>\n            <tr>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">1</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">1</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">1</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">1</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">15</td>\n              <td class=\"text-left\" rowspan=\"1\" colspan=\"1\">Reserved for future definition.</td>\n            </tr>\n          </tbody>\n        </table>\n</section>\n</div>\n</section>\n</div>\n<div id=\"authors-addresses\">\n<section id=\"appendix-D\">\n      <h2 id=\"name-authors-addresses-2\">\n<a href=\"#name-authors-addresses-2\" class=\"section-name selfRef\">Authors' Addresses</a>\n      </h2>\n<address class=\"vcard\">\n        <div dir=\"auto\" class=\"left\"><span class=\"fn nameRole\">Brad G. Peabody</span></div>\n<div class=\"email\">\n<span>Email:</span>\n<a href=\"mailto:brad@peabody.io\" class=\"email\">brad@peabody.io</a>\n</div>\n</address>\n<address class=\"vcard\">\n        <div dir=\"auto\" class=\"left\"><span class=\"fn nameRole\">Kyzer R. Davis</span></div>\n<div class=\"email\">\n<span>Email:</span>\n<a href=\"mailto:kydavis@cisco.com\" class=\"email\">kydavis@cisco.com</a>\n</div>\n</address>\n</section>\n</div>\n<script>const toc = document.getElementById(\"toc\");\ntoc.querySelector(\"h2\").addEventListener(\"click\", e => {\n  toc.classList.toggle(\"active\");\n});\ntoc.querySelector(\"nav\").addEventListener(\"click\", e => {\n  toc.classList.remove(\"active\");\n});\n</script>\n<script>(function(){function c(){var b=a.contentDocument||a.contentWindow.document;if(b){var d=b.createElement('script');d.innerHTML=\"window.__CF$cv$params={r:'89c7ca42a88b0c84',t:'MTcxOTg1MTUyNS4wMDAwMDA='};var a=document.createElement('script');a.nonce='';a.src='/cdn-cgi/challenge-platform/scripts/jsd/main.js';document.getElementsByTagName('head')[0].appendChild(a);\";b.getElementsByTagName('head')[0].appendChild(d)}}if(document.body){var a=document.createElement('iframe');a.height=1;a.width=1;a.style.position='absolute';a.style.top=0;a.style.left=0;a.style.border='none';a.style.visibility='hidden';document.body.appendChild(a);if('loading'!==document.readyState)c();else if(window.addEventListener)document.addEventListener('DOMContentLoaded',c);else{var e=document.onreadystatechange||function(){};document.onreadystatechange=function(b){e(b);'loading'!==document.readyState&&(document.onreadystatechange=e,c())}}}})();</script></body>\n</html>\n"
  },
  {
    "path": "doc/java-and-unsigned-numbers.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n<html>\n  <head>\n    <title>Java and unsigned int, unsigned short, unsigned byte, unsigned long, etc. (Or rather, the lack thereof)</title>\n  </head>\n\n  <body>\n\n   <h1>Java and unsigned int, unsigned short, unsigned byte, unsigned long, etc. (Or rather, the lack thereof)</h1>\n\nWritten by Sean R. Owens, sean at guild dot net, released to the\npublic domain.  Share and enjoy.  Since some people argue that it is\nimpossible to release software to the public domain, you are also free\nto use this code under any version of the GPL, LPGL, or BSD licenses,\nor contact me for use of another license.\n<p>\n\nIf you are wondering if this means that you are allowed to use this in\na class about java and/or unsigned types, <b>you are allowed to use\nthis in a class</b>\n<p>\n\n<a href=http://darksleep.com/player>http://darksleep.com/player</a>\n<br>\n<p>\nFor other fine writings on Java and other subjects, check out <a href=http://darksleep.com/notablog>notablog at http://darksleep.com/notablog</a>\n<p>\n( Evangelos Haleplidis has been so kind as to write this up as a set\nof classes that may be easily used to read unsigned types.  You can\ndownload a <a\nhref=http://darksleep.com/player/ehalep/Unsigned.jar>pre-compiled\njar,</a> <a href=http://darksleep.com/player/ehalep/unsigned.zip>a zip\nof the source,</a> and <a\nhref=http://darksleep.com/player/ehalep/javadoc.zip>a zip of the API\ndocs</a> from this website. )\n\n<h2> Note: java.nio.ByteBuffer / java.nio.ByteOrder </h2>\n\nIf all you want to know is how to read a stream of bytes where you\n<strong>know</strong> the endianness, then take a close look at\njava.nio.ByteOrder and java.nio.ByteBuffer and it's order() methods,\nas well as it's get and put methods.  If you want to roll your own\nand/or want to know how it works, read on.\n\n<h2> So what's up with unsigned types in Java? </h2>\n\n    In languages like C and C++, there exist a variety of sizes of\n    integers, char, short, int, long.  (char isn't really an integer,\n    but you can use it like an integer and most people use it in C for\n    really small integers.)  On most 32 bit systems, these correspond\n    to 1 byte, 2 byte, 4 byte, and 8 byte numbers.  But note, do not\n    make the mistake of assuming this is true everywhere.  On the\n    other hand, Java, since it is designed to be a portable platform,\n    guarantees that no matter what platform you are running on, a\n    'byte' is 1 byte, a 'short' is 2 bytes, an 'int' is 4 bytes, and a\n    'long' is 8 bytes.  However, C also provides 'unsigned' types of\n    each of its integers, which <a href=#why_no_unsigned_types>Java\n    does not</a>.  I find it incredibly annoying that Java doesn't\n    deal with unsigned types, considering the huge number of hardware\n    interfaces, network protocols, and file formats that use them.\n\n\n<p>\n\n    (The only exception is that Java does provide the 'char' type,\n    which is a 2 byte representation of unicode, instead of the C\n    'char' type, which is 1 byte ASCII.  Java's 'char' also can be\n    used as an unsigned short, i.e. it represents numbers from 0 up to\n    2^16.  The only gotchas are, weird things will happen if you try\n    to assign it to a short, and if you try to print it, you'll get\n    the unicode character it represents, instead of the integer value.\n    If you need to print the value of a char, cast it to int first.)\n\n<h2> So how do we work around this lack of unsigned types? </h2>\n\n    Well, you're probably not going to like this... \n<p>\n\n    The answer is, you use the signed types that are larger than the\n    original unsigned type.  I.e. use a short to hold an unsigned\n    byte, use a long to hold an unsigned int.  (And use a char to hold\n    an unsigned short.)  Yeah, this kinda sucks because now you're\n    using twice as much memory, but there really is no other solution.\n    (Also bear in mind, access to longs is not guaranteed to be atomic\n    - although if you're using multiple threads, you really should be\n    using synchronization anyway.)\n\n<h2> So... </h2>\n<h3> Have you noticed that you seem to have this bad habit of starting your headings with \"So\"?</h3>\nHmm, good point.  So let's stop doing that.\n\n<h2> How do we get the values into and out of 'unsigned' form? </h2>\n<p>\n\n    If someone sends you a bunch of bytes over the network (or you\n    read them from a file on the disk, or whatever) that include some\n    unsigned numbers, you need to do a few gymnastics to convert them\n    into the larger java types. \n\n\n<p> \n      \n    One issue that I really need to go into here is <a\n    href=#whats_all_this_about_byte_order_or_endianness>byte order aka\n    endianness</a>, but for the moment we're going to assume (or hope)\n    that whatever you're trying to read is in what is referred to as\n    'network byte order' aka 'big endian' aka Java's standard\n    endianness.\n      \n\n<h3>Reading from network byte order</h3>\n\n    Let us assume we're starting with a byte array, just to keep\n    things simple, and we want to read an unsigned byte, then an\n    unsigned short, then an unsigned int.\n\n      <pre> \n\tshort anUnsignedByte = 0;\n\tchar anUnsignedShort = 0;\n\tlong anUnsignedInt = 0;\n\n        int firstByte = 0;\n        int secondByte = 0;\n        int thirdByte = 0;\n        int fourthByte = 0;\n\n\tbyte buf[] = getMeSomeData();\n\t// Check to make sure we have enough bytes\n\tif(buf.length < (1 + 2 + 4)) \n\t  doSomeErrorHandling();\n\tint index = 0;\n\t\n        firstByte = (0x000000FF & ((int)buf[index]));\n\tindex++;\n\tanUnsignedByte = (short)firstByte;\n\n        firstByte = (0x000000FF & ((int)buf[index]));\n        secondByte = (0x000000FF & ((int)buf[index+1]));\n\tindex = index+2;\n\tanUnsignedShort  = (char) (firstByte << 8 | secondByte);\n\n        firstByte = (0x000000FF & ((int)buf[index]));\n        secondByte = (0x000000FF & ((int)buf[index+1]));\n        thirdByte = (0x000000FF & ((int)buf[index+2]));\n        fourthByte = (0x000000FF & ((int)buf[index+3]));\n        index = index+4;\n\tanUnsignedInt  = ((long) (firstByte << 24\n\t                | secondByte << 16\n                        | thirdByte << 8\n                        | fourthByte))\n                       & 0xFFFFFFFFL;\n      </pre>\n\n<p>\n\n    OK, now that all looks a little complicated.  But really it is\n    straightforward.  First off, you see a lot of \n<p>\n<pre>\n\t0x000000FF & (int)buf[index]\n</pre>\n<p>\n    What is going on there is that we are promoting a (signed) byte to\n    int, and then doing a bitwise AND operation on it to wipe out\n    everything but the first 8 bits.  Because Java treats the byte as\n    signed, if its unsigned value is above > 127, the sign bit will be\n    set (strictly speaking it is not \"the sign bit\" since numbers are\n    encoded in <a\n    href=\"http://en.wikipedia.org/wiki/Two%27s_complement\">two's\n    complement</a>) and it will appear to java to be negative.  When\n    it gets promoted to int, bits 0 through 7 will be the same as the\n    byte, and bits 8 through 31 will be set to 1.  So the bitwise AND\n    with 0x000000FF clears out all of those bits.  Note that this\n    could have been written more compactly as;\n<p>\n<pre>\n\t0xFF & buf[index]\n</pre>\n    Java assumes the leading zeros for 0xFF, and the bitwise &\n    operator automatically promotes the byte to int.  But I wanted to\n    be a tad more explicit about it.\n<p>\n    The next thing you'll see a lot of is the <<, or bitwise shift\n    left operator.  It's shifting the bit patterns of the left int\n    operand left by as many bits as you specify in the right operand\n    So, if you have some int foo = 0x000000FF, then (foo << 8) ==\n    0x0000FF00, and (foo << 16) == 0x00FF0000.\n<p>\n    The last piece of the puzzle is |, the bitwise OR operator.\n    Assume you've loaded both bytes of an unsigned short into separate\n    integers, so you have 0x00000012 and 0x00000034.  Now you shift\n    one of the bytes by 8 bits to the left, so you have 0x00001200 and\n    0x00000034, but you still need to stick them together.  So you\n    bitwise OR them, and you have 0x00001200 | 0x00000034 =\n    0x00001234.  This is then stored into Java's 'char' type.  \n<p>\n    That's basically it, except that in the case of the unsigned int,\n    you have to now store it into the long, and you're back up against\n    that sign extension problem we started with.  No problem, just\n    cast your int to long, then do the bitwise AND with 0xFFFFFFFFL.\n    (Note the trailing L to tell Java this is a literal of type 'long'\n    integer.)\n\n\n<h3>Writing to network byte order</h3>\n\n    Lets assume now that we want to write the values we read above\n    back into the same buffer, but whereas we read an unsigned byte,\n    then an unsigned short, then an unsigned int, now we instead (for\n    some arcane reason) want to write it out as unsigned int, unsigned\n    short, unsigned byte.\n\n      <pre>\n\tbuf[0] = (anUnsignedInt & 0xFF000000L) >> 24;\n\tbuf[1] = (anUnsignedInt & 0x00FF0000L) >> 16;\n\tbuf[2] = (anUnsignedInt & 0x0000FF00L) >> 8;\n\tbuf[3] = (anUnsignedInt & 0x000000FFL);\n\n\tbuf[4] = (anUnsignedShort & 0xFF00) >> 8;\n\tbuf[5] = (anUnsignedShort & 0x00FF);\n\n\tbuf[6] = (anUnsignedByte & 0xFF);\n      </pre>\n\n    \n<h2><a name=whats_all_this_about_byte_order_or_endianness>Whats all this about Byte Order? (or Endianness?)</a></h2>\n<h3> What does it mean?  Why do I care? (And what about Network Order?)</h3>\n\nFor the record, Java is 'big endian' also known as 'network byte\norder'.  Intel x86 processors are 'little endian'.  (Unless it's a\nJava program running on an Intel chip.)  A data file created by an x86\nsystem is <b>likely</b> but <b>not required</b> to be little endian.\nA data file created by a Java program is <b>likely</b> but <b>not\nrequired</b> to be big endian.  Any system can output data in whatever\nformat it wants and it's entirely possible the one you are dealing\nwith is being careful to write data in 'network byte order' aka 'big\nendian'.\n\n<h3> What does Byte Order / Endianness mean? </h3>\n\n\"Byte order\" or \"Endianness\" refers to how a particular computer\narchitecture stores numbers in memory.  Typically a particular\ncomputer is either \"big endian\" or \"little endian\".  (By the way,\naccording to Wikipedia, <a\nhref=http://en.wikipedia.org/wiki/Endianness>these terms derive from a\nstory in Gullivers Travels.</a>)\n\n<p>\n\nYou care about this because if you assume data is written in say, 'big\nendian' format, and write your code accordingly, and it turns out the\ndata is in 'little endian' format, you're going to get garbage.  And\nvice versa for assuming 'little endian' for data written in 'big\nendian'.\n\n\n\n<p>\n\nEvery number, whether expressed as digits, i.e. the number\n500,000,007 or as bytes, i.e. the four byte integer (as hexadecimal)\n0x1DCD6507, can be thought of as a string of digits.\nAnd this string of digits can be thought of as having a starting, or\nleft, 'end', and a finishing, or 'right' end.  In English, the first\ndigit in a number is always the biggest (or most significant) digit -\ni.e. the 5 in 500,000,007 actually represents the value 500,000,000.\nThe last digit in a number is always the littlest (or least\nsignificant) digit - i.e. the 7 in 500,000,007 represents the value 7.\n\n<p>\n\nWhen we talk about Endianness, or byte order, we are talking about the\norder in which we write down the digits.  Do we write the biggest\n(most significant) digit first, and then the next biggest, etc etc,\nuntil we reach the littlest (least significant) digit?  Or do we start\nwith the littlest digit first?  In English we always write the biggest\none first, hence English could be described as \"big endian\".  (There\n<em>are</em> human languages where they do it the other way around.\nMy friend Raichle suggests Hebrew as an example of one such language,\nbut she's not really sure.)\n\n<p> \n\nIn the example above, the value 50,0000,007, in hexadecimal, is\n0x1DCD6507.  And if we break it up into four separate bytes, the byte\nvalues are 0x1D, 0xCD, 0x65, and 0x07.  In decimal those four bytes\nare (respectively) 29, 205, 101, and 7.  The biggest byte is the first\none, 29, which represents the value 29 * 256 * 256 * 256 = 486539264.\nThe second biggest is the second byte, 205, which represents the value\n205 * 256 * 256 = 13434880.  The third biggest byte is 101, which\nrepresents the value 101 * 256 = 25856, and the littlest byte is 7,\nwhich represents the value 7 * 1 = 7.  The values 486539264 + 13434880\n+ 25856 + 7 = 500,000,007.\n\n<p>\n\nWhen the computer stores those four bytes into four locations in\nmemory, let's say into memory addresses 2056, 2057, 2058, and 2059,\nthe question is, what order does it store them in?  It might put 29 in\n2056, 205 in 2057, 101 in 2058, and 7 in 2059, just like you'd write\ndown the number in English.  If it did, then we would say that\ncomputer is \"big endian\".  However, a different computer architecture\nmight just as easily store those bytes by putting 7 in 2056, 101 in\n2057, 205 in 2058, and 29 in 2059.  If the computer stored the bytes\nin that manner then we would say that it was \"little endian\".\n\n<p>\n\nNote that this also applies to how the computer stores 2 byte shorts\nand 8 byte longs.  Also note that the \"biggest\" byte is also referred\nto as the \"Most Significant Byte\" (MSB) and the \"littlest\" byte is\nalso referred to as the \"Least Significant Byte\" (LSB), so you will\noften times see those two phrases or acronyms popping up.\n\n<h3> Ok, fine, so why do I care about Byte Order? </h3>\n\nWell, it depends.  A lot of the time you don't have to.  In pure Java,\nbyte order is always the same no matter what platform you're on, so no\nbig deal, you can forget about it, as long as you're dealing with pure\nJava.  \n\n<p>\n\nBut what happens when you're dealing with data generated by other\nlanguages?  Well, now you have to pay attention to things a bit.  You\nhave to make sure that you decode the bytes in the same order as they\nwere originally encoded in, and likewise make sure that you encode the\nbytes in the same order as they will be decoded in.  If you're lucky\nthis will be specified somewhere in the spec or API for whatever\nprotocol or file format you're dealing with.  If you're\nunlucky... well.  Good luck.\n\n<p>\n\nThe biggest problem is simply remembering what your byte order is, and\nknowing what the byte order of the data you are reading in is.  If\nthey're not the same, you need to make sure you re-order them\ncorrectly, or in the case of dealing with unsigned numbers like above,\nyou need to make sure you put the correct bytes into the correct parts\nof the integer/short/long.\n\n\n<h3> What the heck is Network Order? </h3> \n\nWhen the Internet Protocol (IP) was designed, \"big endian\" byte order\nwas designated as \"network order\".  All numeric values in IP packet\nheaders are stored in \"network order\".  The byte order of the computer\ncreating the packets is referred to as \"host order\", although it may\nin fact be the same as \"network order\" if your host is a \"big endian\"\nmachine.  So that's why you'll some times see Java endianness/byte\norder referred to as \"network order\", since both Java byte order and\nnetwork byte order are \"big endian\"\n\n<p>\n\n\n\n<h2><a name=why_no_unsigned_types>Why no unsigned types?</a></h2>\n\n    Why doesn't Java provide unsigned types?  Good question.  I always\n    thought it was kind of strange, especially since there are lots of\n    network protocols out there that use unsigned types.  I first ran into\n    this back in 1999.  At the time I did a lot of digging on the web\n    (google wasn't as good then as it is now) because I had a hard\n    time believing this was true, but eventually I ran across an\n    interview with one of the inventers of Java (was it Gosling?  I\n    can't remember.  I wish I'd saved a copy of that web page). where\n    the designer came right out and said something like \"Hey, unsigned\n    types make everything more complicated and nobody really needs\n    them anyway, so we left them out.\"  Here's another web page with\n    an interview with James Gosling that might give you an idea of\n    where he's coming from:\n\n<p>\n\n<a href=\"http://www.gotw.ca/publications/c_family_interview.htm\">http://www.gotw.ca/publications/c_family_interview.htm</a>\n\n<p>\n<pre>\n> Q: Programmers often talk about the advantages and disadvantages of\n> programming in a \"simple language.\"  What does that phrase mean to\n> you, and is [C/C++/Java] a simple language in your view?\n> \n> Ritchie: [deleted for brevity]\n> \n> Stroustrup: [deleted for brevity]\n> \n> Gosling: For me as a language designer, which I don't really count\n> myself as these days, what \"simple\" really ended up meaning was could\n> I expect J. Random Developer to hold the spec in his head. That\n> definition says that, for instance, Java isn't -- and in fact a lot of\n> these languages end up with a lot of corner cases, things that nobody\n> really understands. Quiz any C developer about unsigned, and pretty\n> soon you discover that almost no C developers actually understand what\n> goes on with unsigned, what unsigned arithmetic is. Things like that\n> made C complex. The language part of Java is, I think, pretty\n> simple. The libraries you have to look up.\n</pre>\n\n<p>\nOn the other hand.... \n\nAccording to <a href=\"http://www.artima.com/weblogs/viewpost.jsp?thread=7555\">http://www.artima.com/weblogs/viewpost.jsp?thread=7555</a>\n\n<pre>\n> Once Upon an Oak ...\n> by Heinz Kabutz\n> July 15, 2003\n>\n...\n> Trying to fill my gaps of Java's history, I started digging around on\n> Sun's website, and eventually stumbled across the Oak Language\n> Specification for Oak version 0.2. Oak was the original name of what\n> is now commonly known as Java, and this manual is the oldest manual\n> available for Oak (i.e. Java).\n...\n> Unsigned integer values (Section 3.1)\n> \n> The specification says: \"The four integer types of widths of 8, 16, 32\n> and 64 bits, and are signed unless prefixed by the unsigned modifier.\n> \n> In the sidebar it says: \"unsigned isn't implemented yet; it might\n> never be.\" How right you were.\n</pre>\n\nThe Oak Language Specification for Oak version 0.2 can be downloaded in as \npostscript from <a href=https://duke.dev.java.net/green/OakSpec0.2.ps>https://duke.dev.java.net/green/OakSpec0.2.ps</a> or zipped PDF from <a href=http://www.me.umn.edu/~shivane/blogs/cafefeed/resources/14-jun-2007/OakSpec0.2.zip>http://www.me.umn.edu/~shivane/blogs/cafefeed/resources/14-jun-2007/OakSpec0.2.zip</a> (assuming these links haven't broken...)\n\n    <hr>\n    Thanks goes to Derrick Coetzee (dc at moonflare dot com) for his\n    advice and support.\n\n    <hr>\n\n<!-- Created: Fri Sep 17 19:13:27 EDT 2004 -->\n<!-- hhmts start -->\nLast modified: Sat Apr  7 01:48:45 UTC 2012\n<!-- hhmts end -->\n  </body>\n</html>\n"
  },
  {
    "path": "doc/perf-analysis.md",
    "content": "# Performance Comparison: clj-uuid-old vs clj-uuid\n\nThis document provides a thorough analysis of the performance characteristics\nof `clj-uuid-old` (based on `bitmop`) versus `clj-uuid` (based on `bitmop2`)\nfor every UUID type and supporting operation.\n\n## Architecture Overview\n\n| Layer        | clj-uuid-old              | clj-uuid                    |\n|--------------|---------------------------|------------------------------|\n| Primitives   | `clj-uuid.bitmop`         | `clj-uuid.bitmop2`           |\n| Top-level NS | `clj-uuid-old`            | `clj-uuid`                   |\n| Byte model   | Manual shift/mask loops   | `java.nio.ByteBuffer`        |\n| Digest cache | ThreadLocal MessageDigest | ThreadLocal MessageDigest    |\n| Shared deps  | `clock`, `node`, `random`, `constants` | same           |\n\nBoth namespaces produce identical `java.util.UUID` output values. The\ndifference lies entirely in how bitwise operations are performed internally.\n\n### Core Primitive Change\n\nThe fundamental performance change is replacing **manual 8-iteration\nshift/mask loops** with **single native ByteBuffer operations**:\n\n| Operation       | bitmop (clj-uuid-old)                   | bitmop2 (clj-uuid)                     |\n|-----------------|-----------------------------------------|-----------------------------------------|\n| `bytes->long`   | 8-iteration `dpb` loop                  | Single `ByteBuffer.getLong`             |\n| `long->bytes`   | 8-iteration `ldb` + `sb8` loop          | Single `ByteBuffer.putLong`             |\n| `assemble-bytes`| 8-iteration `dpb` loop over sequence    | Direct shift-accumulation loop          |\n| `hex`           | `map ub8` + `long->bytes` + `map octet-hex` + `apply str` | `long->bytes` + `StringBuilder` direct append |\n| `mask-offset`   | O(offset) loop scanning for lowest set bit | `Long/numberOfTrailingZeros` (single `TZCNT` instruction) |\n| `mask-width`    | O(width) loop counting contiguous set bits | `Long/bitCount` (single `POPCNT` instruction) |\n| `bit-count`     | O(64) loop counting all set bits        | `Long/bitCount` (single `POPCNT` instruction) |\n\nOperations that are **unchanged** between the two (they operate on longs\ndirectly and don't involve byte conversion):\n\n- `mask` -- identical implementation\n- `ldb`, `dpb` -- identical implementation (but faster in bitmop2 due to O(1) `mask-offset`)\n- `ub*`, `sb*` byte casts -- identical implementation\n- `octet-hex` -- identical implementation\n- `expt2`, `pphex` -- identical implementation\n\n\n---\n\n## Per-Operation Primitive Benchmarks\n\nThe following analysis is based on the `bitmop2_test.clj` benchmark\nframework (100K iterations with JIT warmup).\n\n### `long->bytes`\n\nConverts a 64-bit long to an 8-byte big-endian array.\n\n| Impl   | Approach                                     | Ops per call |\n|--------|----------------------------------------------|--------------|\n| bitmop | Loop 8 times: `ldb(mask(8, j*8), x)` + `sb8` + `aset-byte` | 8x ldb + 8x sb8 + 8x aset-byte = ~40 ops |\n| bitmop2| `ByteBuffer.putLong(offset, x)`              | 1 native call |\n\n**Measured speedup: 6-27x**\n\nThe bitmop version executes 8 loop iterations, each calling `mask-offset` (a\n`cond` + bit-shift loop), `ldb` (2 shifts + 1 AND), `sb8` (2 casts + 1 AND),\nand `aset-byte`. The bitmop2 version delegates to a single JVM intrinsic\n`putLong` that writes 8 bytes in one native operation.\n\n### `bytes->long`\n\nReads 8 bytes from a byte array into a 64-bit long.\n\n| Impl   | Approach                                     | Ops per call |\n|--------|----------------------------------------------|--------------|\n| bitmop | Loop 8 times: `aget` + `dpb(mask(8, j*8), tot, byte)` | 8x aget + 8x dpb + 8x mask = ~48 ops |\n| bitmop2| `ByteBuffer.getLong(offset)`                 | 1 native call |\n\n**Measured speedup: 5-10x**\n\nSame pattern as `long->bytes` in reverse. Each bitmop iteration calls `dpb`\n(which internally calls `mask-offset`, performs 2 shifts, 2 ANDs, and 1 OR).\nThe bitmop2 version is a single native read.\n\n### `assemble-bytes`\n\nAssembles a sequence of 8 bytes into a long.\n\n| Impl   | Approach                                     | Ops per call |\n|--------|----------------------------------------------|--------------|\n| bitmop | Loop 8 times: `dpb(mask(8, k*8), tot, byte)` from seq | 8x dpb + seq traversal |\n| bitmop2| Direct shift-accumulation: `(bit-or (bit-shift-left tot 8) byte)` | 8x shift+or + seq traversal |\n\n**Measured speedup: 2.2-2.6x**\n\nThe bitmop2 version uses a pure arithmetic accumulation loop\n(`bit-shift-left` + `bit-or`) instead of bitmop's `dpb`+`mask` per\niteration.  This avoids the function call overhead of `mask`,\n`mask-offset`, and `dpb` on each byte, with zero allocation.\n\n### `hex`\n\nConverts a long to a 16-character hexadecimal string.\n\n| Impl   | Approach                                     | Allocs per call |\n|--------|----------------------------------------------|-----------------|\n| bitmop | `long->bytes` (8-iter loop) + `map ub8` (lazy seq) + `map octet-hex` (lazy seq of 2-char strs) + `apply str` | byte array + 2 lazy seqs + 8 temp strings + final concat |\n| bitmop2| `long->bytes` (1 putLong) + `StringBuilder` direct byte-by-byte append | byte array + 1 StringBuilder |\n\n**Measured speedup: 11-35x**\n\nThe bitmop version creates multiple intermediate lazy sequences and 8\ntwo-character strings before concatenating them all. The bitmop2 version\nwrites directly to a pre-sized `StringBuilder`, eliminating all intermediate\nstring and sequence allocation.\n\n\n---\n\n## Per-UUID-Type Performance Analysis\n\nFor each UUID type, we trace the critical path through both implementations\nand identify where `bitmop2` provides measurable improvement.\n\n### v0 (Null UUID) / v15 (Max UUID)\n\n```clojure\n;; Both implementations:\n(defn null [] +null+)\n(defn max  [] +max+)\n```\n\n**Impact: None.** Returns a constant. No bitwise operations involved.\n\n---\n\n### v1 (Time-based, Gregorian)\n\n```clojure\n;; clj-uuid-old (bitmop):\n(let [ts        (clock/monotonic-time)          ;; atom + swap! + State alloc\n      time-low  (ldb #=(mask 32  0)  ts)\n      time-mid  (ldb #=(mask 16 32)  ts)\n      time-high (dpb #=(mask 4  12) (ldb #=(mask 12 48) ts) 0x1)\n      msb       (bit-or time-high\n                  (bit-shift-left time-low 32)\n                  (bit-shift-left time-mid 16))]\n  (UUID. msb (node/+v1-lsb+)))                 ;; memoized fn call\n\n;; clj-uuid (bitmop2) -- inlined CAS + direct bit ops:\n(loop []\n  (let [current  (.get packed)                  ;; AtomicLong, captured in closure\n        millis   (unsigned-bit-shift-right current 14)\n        time-now (System/currentTimeMillis)]\n    (cond\n      (< millis time-now)\n      (let [next (bit-shift-left time-now 14)]\n        (if (.compareAndSet packed current next)\n          (let [ts  (+ 100103040000000000\n                       (* (+ 2208988800000 time-now) 10000))\n                msb (bit-or\n                      (bit-shift-left (bit-and ts 0xFFFFFFFF) 32)\n                      (bit-shift-left (bit-and (unsigned-bit-shift-right ts 32) 0xFFFF) 16)\n                      0x1000\n                      (bit-and (unsigned-bit-shift-right ts 48) 0xFFF))]\n            (UUID. msb v1-lsb))               ;; pre-captured long, no fn call\n          (recur)))\n      ...)))\n```\n\n| Operation            | bitmop (clj-uuid-old)          | bitmop2 (clj-uuid)             | Difference |\n|----------------------|--------------------------------|--------------------------------|------------|\n| Clock                | `atom` + `swap!` + `State` alloc | `AtomicLong.compareAndSet` (inlined) | **no var lookup, no alloc** |\n| Bit-field packing    | 3x `ldb` + 1x `dpb` (4 var lookups) | Direct `bit-or`/`bit-and`/`bit-shift` | **no var lookups** |\n| Node LSB             | `(node/+v1-lsb+)` (memoize lookup) | `v1-lsb` (pre-captured long)  | **no fn call** |\n\n**Construction impact: ~1.5x speedup (120 ns -> 100 ns).**  Three sources\nof overhead are eliminated: (1) `atom`/`swap!`/`State` allocation is replaced\nby `AtomicLong.compareAndSet` on a packed long; (2) `ldb`/`dpb` var lookups\nare replaced by inlined bit operations; (3) the memoized `+v1-lsb+` function\ncall is replaced by a pre-captured long in the closure.\n\n**Post-construction impact:** Operations on the resulting UUID differ:\n\n| Post-construction op  | bitmop (clj-uuid-old)                    | bitmop2 (clj-uuid)                    | Speedup  |\n|-----------------------|------------------------------------------|---------------------------------------|----------|\n| `to-byte-array`       | 2x `long->bytes` (16 loop iterations)    | 2x `putLong` (2 native calls)         | **60x**  |\n| `to-hex-string`       | 2x `hex` (lazy seqs + `apply str`)       | `uuid->buf` + `buf-hex` (StringBuilder) | **38x** |\n| `to-string`           | `UUID.toString` (JVM)                    | `UUID.toString` (JVM)                  | same     |\n| Field extraction      | `ldb`/`dpb` on longs                     | `ldb`/`dpb` on longs                  | same     |\n\n---\n\n### v6 (Time-based, Lexically Sortable)\n\nSame inlined CAS + direct bit-op architecture as v1, with different\nbit-field ordering for lexical sorting.\n\n**Construction impact: ~1.4x speedup (106 ns -> 100 ns).**  Same\noptimizations as v1.  The smaller relative gain reflects v6's already\nlower baseline (fewer bit operations in the original layout).\n\n**Post-construction impact:** Same as v1 (see table above).\n\n---\n\n### v7 (Unix Time, Crypto-secure, Lexically Sortable)\n\n```clojure\n;; Both implementations (identical structure):\n(let [^State state (clock/monotonic-unix-time-and-random-counter)\n      time            (ldb #=(mask 48  0) (.millis state))\n      ver-and-counter (dpb #=(mask 4  12) (.seqid state) 0x7)\n      msb             (bit-or ver-and-counter (bit-shift-left time 16))\n      lsb             (dpb #=(mask 2 62) (random/long) 0x2)]\n  (UUID. msb lsb))\n```\n\n| Operation                  | bitmop  | bitmop2 | Difference |\n|----------------------------|---------|---------|------------|\n| `monotonic-unix-time-...`  | shared  | shared  | none       |\n| `ldb` x1, `dpb` x2        | O(offset) `mask-offset` | O(1) `Long/numberOfTrailingZeros` | **1.21x** |\n| `random/long` (SecureRandom) | shared | shared | none     |\n\n**Construction impact: 1.21x speedup.**  The `dpb #=(mask 2 62)` call in\nthe LSB line previously invoked `mask-offset` with an O(offset) loop — for\noffset=62, that was 62 iterations per call.  bitmop2's `mask-offset` uses\n`Long/numberOfTrailingZeros`, a JVM intrinsic that compiles to a single\n`TZCNT` instruction.  This eliminates the v7 regression seen in earlier\nbenchmarks.  `SecureRandom.nextLong()` still dominates total latency.\n\n**Post-construction impact:** Same as v1/v6 (see table above).\n\n---\n\n### v7nc (Non-cryptographic V7, ThreadLocalRandom)\n\n```clojure\n;; clj-uuid (bitmop2) -- per-thread counter + ThreadLocalRandom:\n(let [^longs state (.get v7nc-tl)       ;; ThreadLocal long[3]\n      ^ThreadLocalRandom tlr ...]\n  (loop []\n    (let [time-now (System/currentTimeMillis)\n          last-ms  (aget state 0)]\n      (cond\n        (> time-now last-ms)              ;; new millisecond: reseed\n        (let [lsb-ctr (bit-and (.nextLong tlr) 0x3FFFFFFFFFFFFFFF)\n              msb     (bit-or (bit-shift-left (bit-and time-now 0xFFFFFFFFFFFF) 16)\n                              (bit-or 0x7000 (bit-and (.nextLong tlr) 0xFFF)))]\n          (aset state 0 time-now)\n          (aset state 1 msb)\n          (aset state 2 lsb-ctr)\n          (UUID. msb (bit-or lsb-ctr variant-bits)))\n\n        true                              ;; same millisecond: increment\n        (let [lsb-ctr (bit-and (unchecked-inc (aget state 2)) 0x3FFFFFFFFFFFFFFF)]\n          (aset state 2 lsb-ctr)\n          (UUID. (aget state 1) (bit-or lsb-ctr variant-bits)))))))\n```\n\nNo clj-uuid-old equivalent exists.  `v7nc` is a new constructor in 0.2.5.\n\n| Operation                  | v7 (CSPRNG)                  | v7nc                          |\n|----------------------------|------------------------------|-------------------------------|\n| Clock                      | Global `AtomicLong` CAS      | Per-thread `long[]` (no CAS)  |\n| Counter reseed             | `SecureRandom` (~300 ns)     | `ThreadLocalRandom` (~5 ns)   |\n| rand_b                     | `SecureRandom.nextLong()`    | Monotonic counter (increment) |\n| Hot path (same ms)         | CAS + SecureRandom           | Array load + increment        |\n\n**Construction: ~39 ns.**  The hot path (same millisecond) is just:\n`ThreadLocal.get()` + `System.currentTimeMillis()` + array load +\ncomparison + `unchecked-inc` + `bit-and` + array store + `UUID.` constructor.\nNo random number generation, no atomics, no var lookups.\n\n**vs JUG 5.2:** `v7nc` at 39 ns is **1.26x faster** than JUG's\n`TimeBasedEpochGenerator` at ~50 ns.\n\n---\n\n### v4 (Random)\n\n```clojure\n;; 0-arity (both implementations):\n(UUID/randomUUID)\n\n;; 2-arity (both implementations):\n(UUID.\n  (dpb #=(mask 4 12) msb 0x4)\n  (dpb #=(mask 2 62) lsb 0x2))\n```\n\n**Construction impact: None (0-arity) / Negligible (2-arity).**\n\nThe 0-arity form delegates directly to `UUID/randomUUID` (JVM built-in,\ndominated by SecureRandom). The 2-arity form uses only 2 `dpb` calls, which\nare identical between bitmop and bitmop2.\n\n**Post-construction impact:** Same as other UUID types.\n\n---\n\n### v3 (Namespaced, MD5) / v5 (Namespaced, SHA-1)\n\n```clojure\n;; clj-uuid-old (bitmop):\n(build-digested-uuid version\n  (digest-bytes +md5+|+sha1+\n    (to-byte-array (as-uuid context))\n    (as-byte-array local-part)))\n\n;; clj-uuid (bitmop2) -- fused pipeline:\n(let [^MessageDigest md (.get md5-tl)           ;; ThreadLocal, captured in closure\n      ^ByteBuffer nsbuf (.get ns-buf-tl)        ;; ThreadLocal reusable buffer\n      _   (.reset md)\n      _   (.putLong nsbuf 0 (.getMostSignificantBits (as-uuid context)))\n      _   (.putLong nsbuf 8 (.getLeastSignificantBits (as-uuid context)))\n      _   (.update md (.array nsbuf))\n      digest (.digest md ^bytes (as-byte-array local-part))\n      ^ByteBuffer dbuf (ByteBuffer/wrap digest)  ;; wrap, no copy\n      msb (bit-or (bit-and (.getLong dbuf 0) version-clear-mask) 0x3000)\n      lsb (bit-or (bit-and (.getLong dbuf 8) variant-clear-mask) variant-bits)]\n  (UUID. msb lsb))\n```\n\nThe v3/v5 construction path is the most interesting for performance\ncomparison, as it touches multiple bitmop operations in sequence:\n\n#### clj-uuid-old pipeline (4 function calls, ~8 var lookups)\n\n| Step | Operation | Cost |\n|---|---|---|\n| 1 | `to-byte-array` (serialize context UUID) | ~800 ns (16-iter loop) |\n| 2 | `digest-bytes` (MD5 or SHA-1 hash) | ~150-300 ns |\n| 3 | `build-digested-uuid` → `bytes->long` x2 | ~800 ns (16-iter loop) |\n| 4 | `dpb` x2 (version + variant) | ~5 ns |\n| | **Total (v3):** | **~1400 ns** |\n| | **Total (v5):** | **~1670 ns** |\n\n#### clj-uuid pipeline (fused, 0 var lookups on hot path)\n\n| Step | Operation | Cost |\n|---|---|---|\n| 1 | Reuse ThreadLocal ByteBuffer + 2x `putLong` | ~3 ns |\n| 2 | `MessageDigest` (ThreadLocal, `.reset` + `.update` + `.digest`) | ~150-250 ns |\n| 3 | `ByteBuffer/wrap` digest + 2x `.getLong` | ~3 ns |\n| 4 | Inline `bit-and`/`bit-or` (compile-time constant masks) | ~2 ns |\n| | **Total (v3):** | **~175 ns** |\n| | **Total (v5):** | **~260 ns** |\n\n**Overall v3 speedup: ~8x.**  **Overall v5 speedup: ~6.4x.**\n\nThree optimizations compound: (1) ThreadLocal ByteBuffer reuse for\nnamespace serialization eliminates per-call allocation; (2)\n`ByteBuffer/wrap` on the digest output avoids copying 16 bytes;\n(3) inline bit-and/bit-or with compile-time constant masks\n(`#=(bit-not #=(bitmop/mask ...))`) eliminates all `dpb-buf`,\n`buf->uuid`, and `buffer-from-bytes` var lookups.\n\n**vs JUG 5.2:** v5 at ~260 ns is now at parity with JUG's ~254 ns.\n\n---\n\n### v8 (Custom)\n\n```clojure\n;; Both implementations:\n(UUID.\n  (dpb #=(mask 4 12) msb 0x8)\n  (dpb #=(mask 2 62) lsb 0x2))\n```\n\n**Construction impact: 4.21x speedup (46 ns -> 11 ns).**  The v8\nconstructor is just two `dpb` calls (`mask(4,12)` and `mask(2,62)`).\nWith bitmop's O(offset) `mask-offset` loop, the `mask(2,62)` call alone\nrequired 62 loop iterations.  bitmop2's O(1) `Long/numberOfTrailingZeros`\neliminates this overhead, making `dpb` nearly free.\n\n**Post-construction impact:** Same as other UUID types.\n\n---\n\n### squuid (Sequential UUID)\n\n```clojure\n;; Both implementations:\n(let [uuid (v4)\n      secs (clock/posix-time)\n      lsb  (get-word-low  uuid)\n      msb  (get-word-high uuid)\n      timed-msb (bit-or (bit-shift-left secs 32)\n                  (bit-and +ub32-mask+ msb))]\n  (UUID. timed-msb lsb))\n```\n\n**Construction impact: None.** The squuid constructor uses only\n`get-word-high`/`get-word-low` (direct `.getMostSignificantBits`/\n`.getLeastSignificantBits` calls) and `bit-or`/`bit-and`/`bit-shift-left`\nnative operations. Dominated by `v4` -> `UUID/randomUUID` internally.\n\n**Post-construction impact:** Same as other UUID types.\n\n\n---\n\n## Post-Construction Operations Summary\n\nThese operations are called on UUID values *after* construction and show\nthe largest measurable differences between clj-uuid-old and clj-uuid:\n\n### `to-byte-array`\n\n| Impl         | Code path                                                  | Cost     |\n|--------------|------------------------------------------------------------|----------|\n| clj-uuid-old | `bitmop/long->bytes` x2 (16 shift/mask iterations total)  | ~804 ns  |\n| clj-uuid     | `bitmop2/long->bytes` x2 (2 `putLong` calls)              | ~14 ns   |\n\n**Speedup: ~57x**\n\nThis operation is called internally during v3/v5 construction (to serialize\nthe namespace UUID) and is also part of the public API for any UUID.\n\n### `to-hex-string`\n\n| Impl         | Code path                                                  | Cost     |\n|--------------|------------------------------------------------------------|----------|\n| clj-uuid-old | `bitmop/hex(msb)` + `bitmop/hex(lsb)` + `str` concat. Each `hex` call: `long->bytes` (8-iter loop) + `map ub8` (lazy seq) + `map octet-hex` (lazy seq of 8 temp strings) + `apply str` | ~5840 ns |\n| clj-uuid     | `uuid->buf` (2 putLong) + `buf-hex` (single StringBuilder, 16-byte direct loop) | ~199 ns  |\n\n**Speedup: ~29x**\n\nThe bitmop version allocates: 2 byte arrays, 4 lazy sequences, 16\nintermediate 2-character strings, and performs 2 final string concatenations.\nThe bitmop2 version allocates: 1 ByteBuffer + 1 pre-sized StringBuilder and\nappends 32 characters directly.\n\n### `to-string`\n\nBoth call `UUID.toString()`. **No difference.**\n\n### `to-urn-string`\n\nBoth call `(str \"urn:uuid:\" (.toString uuid))`. **No difference.**\n\n### `to-uri`\n\nBoth call `URI/create` on the URN string. **No difference.**\n\n### Field extraction (`get-time-low`, `get-time-mid`, etc.)\n\nBoth use `ldb`/`dpb` on `.getMostSignificantBits`/`.getLeastSignificantBits`.\nThe `#=(mask ...)` reader macros are compile-time constants. **No difference.**\n\n### Comparison operations (`uuid=`, `uuid<`, `uuid>`)\n\nBoth directly compare `.getMostSignificantBits`/`.getLeastSignificantBits`.\n**No difference.** (bitmop2 additionally provides `buf-compare` with unsigned\nsemantics for buffer-level comparison, but `clj-uuid` uses the same\n`uuid=`/`uuid<`/`uuid>` implementation as `clj-uuid-old`.)\n\n### `as-uuid` (byte array to UUID)\n\n| Impl         | Code path                                                  |\n|--------------|------------------------------------------------------------|\n| clj-uuid-old | `ByteBuffer/wrap` + 2 relative `.getLong` calls            |\n| clj-uuid     | `ByteBuffer/wrap` + 2 absolute `.getLong(0)` / `.getLong(8)` |\n\n**Impact: Negligible.** Both use ByteBuffer; the difference is absolute vs\nrelative positioning. The absolute form is marginally more predictable (no\nposition state) but performance is equivalent.\n\n\n---\n\n## Complete Impact Matrix\n\nThis table summarizes the impact of bitmop2 on every UUID type, separating\nconstruction from post-construction operations:\n\n| UUID Type | Construction Speedup | Hot Path Bottleneck             | `to-byte-array` | `to-hex-string` |\n|-----------|---------------------|---------------------------------|------------------|------------------|\n| v0 (null) | --                  | constant                        | **57x**          | **29x**          |\n| v1        | **1.5x**            | `AtomicLong` CAS (inlined)      | **57x**          | **29x**          |\n| v3        | **~8x**             | MD5 digest (fused pipeline)     | **57x**          | **29x**          |\n| v4 (0)    | none                | `SecureRandom` (CSPRNG)         | **57x**          | **29x**          |\n| v4 (2)    | negligible          | caller-provided longs           | **57x**          | **29x**          |\n| v5        | **~6.4x**           | SHA-1 digest (fused pipeline)   | **57x**          | **29x**          |\n| v6        | **1.4x**            | `AtomicLong` CAS (inlined)      | **57x**          | **29x**          |\n| v7        | **1.2x**            | `SecureRandom` (CSPRNG)         | **57x**          | **29x**          |\n| v7nc      | *new*               | `ThreadLocalRandom` (per-thread)| **57x**          | **29x**          |\n| v8        | **4.2x**            | caller-provided longs           | **57x**          | **29x**          |\n| squuid    | none                | `SecureRandom` via v4           | **57x**          | **29x**          |\n| max       | --                  | constant                        | **57x**          | **29x**          |\n\n**Key takeaway:** The bitmop->bitmop2 change provides the largest speedup in\nbyte serialization and hex string rendering, which are post-construction\noperations common to *all* UUID types.  Additionally, `mask-offset`,\n`mask-width`, and `bit-count` now use JVM intrinsics (`Long/numberOfTrailingZeros`\nand `Long/bitCount`), replacing O(n) loops with single CPU instructions.\nThis particularly benefits v7 (1.2x, eliminating a previous regression) and\nv8 (4.2x, where `dpb` is the entire constructor cost).  v3/v5 continue to\nshow the largest gains from byte conversion optimization and ThreadLocal\ndigest caching.\n\n\n---\n\n## Where the Gains Matter Most\n\n### High-throughput serialization\n\nApplications that generate UUIDs and immediately serialize them (to byte\narrays for database storage, or to hex strings for logging/wire format)\nbenefit from the cumulative improvement:\n\n```\nclj-uuid-old (v1 + to-byte-array):  ~120 ns (v1) + ~804 ns (bytes) = ~926 ns\nclj-uuid     (v1 + to-byte-array):  ~100 ns (v1) + ~14 ns  (bytes) = ~114 ns\n                                                                        ~8.1x\n```\n\n```\nclj-uuid-old (v1 + to-hex-string):  ~120 ns (v1) + ~5840 ns (hex)  = ~5960 ns\nclj-uuid     (v1 + to-hex-string):  ~100 ns (v1) + ~126 ns  (hex)  = ~226 ns\n                                                                        ~26x\n```\n\n### Batch name-based UUID generation (v3/v5)\n\nWhen generating many v3/v5 UUIDs (e.g., deterministic ID generation from\na dataset), both the namespace serialization and digest-result extraction\nare improved:\n\n```\nclj-uuid-old (v3): ~800 ns (to-byte-array) + ~200 ns (MD5) + ~800 ns (bytes->long x2) + ~5 ns (dpb)\n                  = ~1400 ns\n\nclj-uuid     (v3): ~14 ns (to-byte-array) + ~140 ns (MD5) + ~14 ns (bytes->long x2) + ~3 ns (dpb)\n                  = ~160 ns\n                                                               ~9.0x\n```\n\n```\nclj-uuid-old (v5): ~800 ns (to-byte-array) + ~300 ns (SHA-1) + ~800 ns (bytes->long x2) + ~5 ns (dpb)\n                  = ~1670 ns\n\nclj-uuid     (v5): ~14 ns (to-byte-array) + ~250 ns (SHA-1) + ~14 ns (bytes->long x2) + ~3 ns (dpb)\n                  = ~280 ns\n                                                               ~6.0x\n```\n\n### UUID comparison and field extraction\n\nNo improvement -- these paths use `ldb`/`dpb` on longs, which are\nidentical. In practice these operations are already extremely fast\n(single-digit nanoseconds).\n\n\n---\n\n## Allocation Profile Comparison\n\nBeyond raw speed, bitmop2 reduces GC pressure through fewer intermediate\nallocations:\n\n| Operation     | bitmop allocations                          | bitmop2 allocations                   |\n|---------------|---------------------------------------------|---------------------------------------|\n| `long->bytes` | 1 byte array                                | 1 byte array + 1 ByteBuffer (wrap)    |\n| `bytes->long` | none (returns primitive)                    | 1 ByteBuffer (wrap)                   |\n| `hex (long)`  | 1 byte array + 2 lazy seqs + 8 temp strings + 1 final string | 1 byte array + 1 StringBuilder + 1 string |\n| `to-hex-string`| 2 byte arrays + 4 lazy seqs + 16 temp strings + 2 hex strings + 1 concat | 1 ByteBuffer + 1 StringBuilder + 1 string |\n| `assemble-bytes` | none (returns primitive, seq traversal only) | none (returns primitive, seq traversal only) |\n\nThe `ByteBuffer/wrap` call in bitmop2 does **not** copy the array (it\ncreates a view), so `long->bytes` and `bytes->long` have minimal allocation\noverhead beyond the existing array.\n\nThe biggest allocation win is in `to-hex-string`, where bitmop creates ~25\nintermediate objects (lazy seq chunks, 2-character strings, intermediate hex\nstrings) versus bitmop2's 3 objects (ByteBuffer, StringBuilder, result\nstring).\n\nThe `assemble-bytes` optimization in bitmop2 now uses a zero-allocation\nshift-accumulation loop (no byte-array, no ByteBuffer), matching bitmop's\nallocation-free approach while being 2.4x faster due to avoiding per-byte\n`dpb`/`mask`/`mask-offset` function calls.\n\n\n---\n\n## Future: cljc/ClojureScript Performance\n\nThe ByteBuffer abstraction in bitmop2 was designed to map to JavaScript's\n`DataView` over `ArrayBuffer`:\n\n| bitmop2 (JVM)              | Future cljc (JS)                    |\n|----------------------------|-------------------------------------|\n| `ByteBuffer/allocate 16`   | `new DataView(new ArrayBuffer(16))` |\n| `.getLong buf offset`       | `.getBigInt64(offset)`              |\n| `.putLong buf offset val`   | `.setBigInt64(offset, val)`        |\n| `.getInt buf offset`        | `.getInt32(offset)`                |\n| `.get buf offset`           | `.getUint8(offset)`                |\n\nThis means the performance characteristics of bitmop2 will carry over to\nClojureScript, where manual shift/mask loops in JavaScript would be\nsignificantly more expensive than native DataView operations (which are\nimplemented in C++ by the JS engine).\n\n\n---\n\n## Summary\n\n| Category                | clj-uuid-old (bitmop)  | clj-uuid (bitmop2)   | Improvement    |\n|-------------------------|------------------------|----------------------|----------------|\n| UUID construction       | baseline               | **1.2-9x faster**    | see below*     |\n| `to-byte-array`         | baseline               | **57x faster**       | ByteBuffer     |\n| `to-hex-string`         | baseline               | **29x faster**       | StringBuilder  |\n| `bytes->long`           | baseline               | **5-10x faster**     | ByteBuffer     |\n| `long->bytes`           | baseline               | **6-27x faster**     | ByteBuffer     |\n| `hex`                   | baseline               | **11-35x faster**    | StringBuilder  |\n| `assemble-bytes`        | baseline               | **2.4x faster**      | shift-accum    |\n| `mask-offset`           | baseline               | **O(1)**             | `TZCNT` intrinsic |\n| `mask-width`/`bit-count`| baseline               | **O(1)**             | `POPCNT` intrinsic |\n| Field extraction        | baseline               | same                 | n/a            |\n| Comparison              | baseline               | same                 | n/a            |\n| GC pressure             | higher                 | **lower**            | fewer allocs   |\n| cljc readiness          | no                     | **yes** (DataView)   | architecture   |\n\n*Construction speedup varies by UUID type: v3 sees **~8x** and v5 sees\n**~6.4x** from the fused digest pipeline with ThreadLocal ByteBuffer\nreuse (v5 is now at parity with JUG 5.2).  v8 sees **4.2x** from O(1)\n`mask-offset`.  v1 sees **~1.5x** and v6 sees **~1.4x** from inlined\n`AtomicLong` CAS, direct bit operations, and pre-captured node LSBs.\nv7nc is a new constructor at ~39 ns -- **1.26x faster** than JUG 5.2's\nv7 generator, using per-thread `ThreadLocalRandom` instead of\n`SecureRandom`.  v4 (0-arity) delegates to `UUID/randomUUID` and is\nunchanged.\n\nThe largest gains are in **serialization-heavy workloads** where UUIDs are\nfrequently converted to byte arrays or hex strings -- common in database\ndrivers, logging frameworks, and wire protocols.  Additional gains come from\n**O(1) mask-offset/mask-width/bit-count** using JVM intrinsics\n(`Long/numberOfTrailingZeros` and `Long/bitCount`), which particularly\nbenefits v8 (4.2x) where `dpb` calls with high-offset masks were\npreviously bottlenecked by an O(offset) loop.\n"
  },
  {
    "path": "doc/rfc4122.txt",
    "content": "\n\n\n\n\n\nNetwork Working Group                                           P. Leach\nRequest for Comments: 4122                                     Microsoft\nCategory: Standards Track                                    M. Mealling\n                                                Refactored Networks, LLC\n                                                                 R. Salz\n                                              DataPower Technology, Inc.\n                                                               July 2005\n\n\n          A Universally Unique IDentifier (UUID) URN Namespace\n\nStatus of This Memo\n\n   This document specifies an Internet standards track protocol for the\n   Internet community, and requests discussion and suggestions for\n   improvements.  Please refer to the current edition of the \"Internet\n   Official Protocol Standards\" (STD 1) for the standardization state\n   and status of this protocol.  Distribution of this memo is unlimited.\n\nCopyright Notice\n\n   Copyright (C) The Internet Society (2005).\n\nAbstract\n\n   This specification defines a Uniform Resource Name namespace for\n   UUIDs (Universally Unique IDentifier), also known as GUIDs (Globally\n   Unique IDentifier).  A UUID is 128 bits long, and can guarantee\n   uniqueness across space and time.  UUIDs were originally used in the\n   Apollo Network Computing System and later in the Open Software\n   Foundation's (OSF) Distributed Computing Environment (DCE), and then\n   in Microsoft Windows platforms.\n\n   This specification is derived from the DCE specification with the\n   kind permission of the OSF (now known as The Open Group).\n   Information from earlier versions of the DCE specification have been\n   incorporated into this document.\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nLeach, et al.               Standards Track                     [Page 1]\n\f\nRFC 4122                  A UUID URN Namespace                 July 2005\n\n\nTable of Contents\n\n   1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  2\n   2. Motivation . . . . . . . . . . . . . . . . . . . . . . . . . .  3\n   3. Namespace Registration Template  . . . . . . . . . . . . . . .  3\n   4. Specification  . . . . . . . . . . . . . . . . . . . . . . . .  5\n      4.1. Format. . . . . . . . . . . . . . . . . . . . . . . . . .  5\n           4.1.1. Variant. . . . . . . . . . . . . . . . . . . . . .  6\n           4.1.2. Layout and Byte Order. . . . . . . . . . . . . . .  6\n           4.1.3. Version. . . . . . . . . . . . . . . . . . . . . .  7\n           4.1.4. Timestamp. . . . . . . . . . . . . . . . . . . . .  8\n           4.1.5. Clock Sequence . . . . . . . . . . . . . . . . . .  8\n           4.1.6. Node . . . . . . . . . . . . . . . . . . . . . . .  9\n           4.1.7. Nil UUID . . . . . . . . . . . . . . . . . . . . .  9\n      4.2. Algorithms for Creating a Time-Based UUID . . . . . . . .  9\n           4.2.1. Basic Algorithm. . . . . . . . . . . . . . . . . . 10\n           4.2.2. Generation Details . . . . . . . . . . . . . . . . 12\n      4.3. Algorithm for Creating a Name-Based UUID. . . . . . . . . 13\n      4.4. Algorithms for Creating a UUID from Truly Random or\n           Pseudo-Random Numbers . . . . . . . . . . . . . . . . . . 14\n      4.5. Node IDs that Do Not Identify the Host. . . . . . . . . . 15\n   5. Community Considerations . . . . . . . . . . . . . . . . . . . 15\n   6. Security Considerations  . . . . . . . . . . . . . . . . . . . 16\n   7. Acknowledgments  . . . . . . . . . . . . . . . . . . . . . . . 16\n   8. Normative References . . . . . . . . . . . . . . . . . . . . . 16\n   A. Appendix A - Sample Implementation . . . . . . . . . . . . . . 18\n   B. Appendix B - Sample Output of utest  . . . . . . . . . . . . . 29\n   C. Appendix C - Some Name Space IDs . . . . . . . . . . . . . . . 30\n\n1.  Introduction\n\n   This specification defines a Uniform Resource Name namespace for\n   UUIDs (Universally Unique IDentifier), also known as GUIDs (Globally\n   Unique IDentifier).  A UUID is 128 bits long, and requires no central\n   registration process.\n\n   The information here is meant to be a concise guide for those wishing\n   to implement services using UUIDs as URNs.  Nothing in this document\n   should be construed to override the DCE standards that defined UUIDs.\n\n   There is an ITU-T Recommendation and ISO/IEC Standard [3] that are\n   derived from earlier versions of this document.  Both sets of\n   specifications have been aligned, and are fully technically\n   compatible.  In addition, a global registration function is being\n   provided by the Telecommunications Standardisation Bureau of ITU-T;\n   for details see <http://www.itu.int/ITU-T/asn1/uuid.html>.\n\n\n\n\n\nLeach, et al.               Standards Track                     [Page 2]\n\f\nRFC 4122                  A UUID URN Namespace                 July 2005\n\n\n2.  Motivation\n\n   One of the main reasons for using UUIDs is that no centralized\n   authority is required to administer them (although one format uses\n   IEEE 802 node identifiers, others do not).  As a result, generation\n   on demand can be completely automated, and used for a variety of\n   purposes.  The UUID generation algorithm described here supports very\n   high allocation rates of up to 10 million per second per machine if\n   necessary, so that they could even be used as transaction IDs.\n\n   UUIDs are of a fixed size (128 bits) which is reasonably small\n   compared to other alternatives.  This lends itself well to sorting,\n   ordering, and hashing of all sorts, storing in databases, simple\n   allocation, and ease of programming in general.\n\n   Since UUIDs are unique and persistent, they make excellent Uniform\n   Resource Names.  The unique ability to generate a new UUID without a\n   registration process allows for UUIDs to be one of the URNs with the\n   lowest minting cost.\n\n3.  Namespace Registration Template\n\n   Namespace ID:  UUID\n   Registration Information:\n      Registration date: 2003-10-01\n\n   Declared registrant of the namespace:\n      JTC 1/SC6 (ASN.1 Rapporteur Group)\n\n   Declaration of syntactic structure:\n      A UUID is an identifier that is unique across both space and time,\n      with respect to the space of all UUIDs.  Since a UUID is a fixed\n      size and contains a time field, it is possible for values to\n      rollover (around A.D. 3400, depending on the specific algorithm\n      used).  A UUID can be used for multiple purposes, from tagging\n      objects with an extremely short lifetime, to reliably identifying\n      very persistent objects across a network.\n\n      The internal representation of a UUID is a specific sequence of\n      bits in memory, as described in Section 4.  To accurately\n      represent a UUID as a URN, it is necessary to convert the bit\n      sequence to a string representation.\n\n      Each field is treated as an integer and has its value printed as a\n      zero-filled hexadecimal digit string with the most significant\n      digit first.  The hexadecimal values \"a\" through \"f\" are output as\n      lower case characters and are case insensitive on input.\n\n\n\n\nLeach, et al.               Standards Track                     [Page 3]\n\f\nRFC 4122                  A UUID URN Namespace                 July 2005\n\n\n      The formal definition of the UUID string representation is\n      provided by the following ABNF [7]:\n\n      UUID                   = time-low \"-\" time-mid \"-\"\n                               time-high-and-version \"-\"\n                               clock-seq-and-reserved\n                               clock-seq-low \"-\" node\n      time-low               = 4hexOctet\n      time-mid               = 2hexOctet\n      time-high-and-version  = 2hexOctet\n      clock-seq-and-reserved = hexOctet\n      clock-seq-low          = hexOctet\n      node                   = 6hexOctet\n      hexOctet               = hexDigit hexDigit\n      hexDigit =\n            \"0\" / \"1\" / \"2\" / \"3\" / \"4\" / \"5\" / \"6\" / \"7\" / \"8\" / \"9\" /\n            \"a\" / \"b\" / \"c\" / \"d\" / \"e\" / \"f\" /\n            \"A\" / \"B\" / \"C\" / \"D\" / \"E\" / \"F\"\n\n   The following is an example of the string representation of a UUID as\n   a URN:\n\n   urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6\n\n   Relevant ancillary documentation:\n      [1][2]\n   Identifier uniqueness considerations:\n      This document specifies three algorithms to generate UUIDs: the\n      first leverages the unique values of 802 MAC addresses to\n      guarantee uniqueness, the second uses pseudo-random number\n      generators, and the third uses cryptographic hashing and\n      application-provided text strings.  As a result, the UUIDs\n      generated according to the mechanisms here will be unique from all\n      other UUIDs that have been or will be assigned.\n\n   Identifier persistence considerations:\n      UUIDs are inherently very difficult to resolve in a global sense.\n      This, coupled with the fact that UUIDs are temporally unique\n      within their spatial context, ensures that UUIDs will remain as\n      persistent as possible.\n\n   Process of identifier assignment:\n      Generating a UUID does not require that a registration authority\n      be contacted.  One algorithm requires a unique value over space\n      for each generator.  This value is typically an IEEE 802 MAC\n      address, usually already available on network-connected hosts.\n      The address can be assigned from an address block obtained from\n      the IEEE registration authority.  If no such address is available,\n\n\n\nLeach, et al.               Standards Track                     [Page 4]\n\f\nRFC 4122                  A UUID URN Namespace                 July 2005\n\n\n      or privacy concerns make its use undesirable, Section 4.5\n      specifies two alternatives.  Another approach is to use version 3\n      or version 4 UUIDs as defined below.\n\n   Process for identifier resolution:\n      Since UUIDs are not globally resolvable, this is not applicable.\n\n   Rules for Lexical Equivalence:\n      Consider each field of the UUID to be an unsigned integer as shown\n      in the table in section Section 4.1.2.  Then, to compare a pair of\n      UUIDs, arithmetically compare the corresponding fields from each\n      UUID in order of significance and according to their data type.\n      Two UUIDs are equal if and only if all the corresponding fields\n      are equal.\n\n      As an implementation note, equality comparison can be performed on\n      many systems by doing the appropriate byte-order canonicalization,\n      and then treating the two UUIDs as 128-bit unsigned integers.\n\n      UUIDs, as defined in this document, can also be ordered\n      lexicographically.  For a pair of UUIDs, the first one follows the\n      second if the most significant field in which the UUIDs differ is\n      greater for the first UUID.  The second precedes the first if the\n      most significant field in which the UUIDs differ is greater for\n      the second UUID.\n\n   Conformance with URN Syntax:\n      The string representation of a UUID is fully compatible with the\n      URN syntax.  When converting from a bit-oriented, in-memory\n      representation of a UUID into a URN, care must be taken to\n      strictly adhere to the byte order issues mentioned in the string\n      representation section.\n\n   Validation mechanism:\n      Apart from determining whether the timestamp portion of the UUID\n      is in the future and therefore not yet assignable, there is no\n      mechanism for determining whether a UUID is 'valid'.\n\n   Scope:\n      UUIDs are global in scope.\n\n4.  Specification\n\n4.1.  Format\n\n   The UUID format is 16 octets; some bits of the eight octet variant\n   field specified below determine finer structure.\n\n\n\n\nLeach, et al.               Standards Track                     [Page 5]\n\f\nRFC 4122                  A UUID URN Namespace                 July 2005\n\n\n4.1.1.  Variant\n\n   The variant field determines the layout of the UUID.  That is, the\n   interpretation of all other bits in the UUID depends on the setting\n   of the bits in the variant field.  As such, it could more accurately\n   be called a type field; we retain the original term for\n   compatibility.  The variant field consists of a variable number of\n   the most significant bits of octet 8 of the UUID.\n\n   The following table lists the contents of the variant field, where\n   the letter \"x\" indicates a \"don't-care\" value.\n\n   Msb0  Msb1  Msb2  Description\n\n    0     x     x    Reserved, NCS backward compatibility.\n\n    1     0     x    The variant specified in this document.\n\n    1     1     0    Reserved, Microsoft Corporation backward\n                     compatibility\n\n    1     1     1    Reserved for future definition.\n\n   Interoperability, in any form, with variants other than the one\n   defined here is not guaranteed, and is not likely to be an issue in\n   practice.\n\n4.1.2.  Layout and Byte Order\n\n   To minimize confusion about bit assignments within octets, the UUID\n   record definition is defined only in terms of fields that are\n   integral numbers of octets.  The fields are presented with the most\n   significant one first.\n\n   Field                  Data Type     Octet  Note\n                                        #\n\n   time_low               unsigned 32   0-3    The low field of the\n                          bit integer          timestamp\n\n   time_mid               unsigned 16   4-5    The middle field of the\n                          bit integer          timestamp\n\n   time_hi_and_version    unsigned 16   6-7    The high field of the\n                          bit integer          timestamp multiplexed\n                                               with the version number\n\n\n\n\n\nLeach, et al.               Standards Track                     [Page 6]\n\f\nRFC 4122                  A UUID URN Namespace                 July 2005\n\n\n   clock_seq_hi_and_rese  unsigned 8    8      The high field of the\n   rved                   bit integer          clock sequence\n                                               multiplexed with the\n                                               variant\n\n   clock_seq_low          unsigned 8    9      The low field of the\n                          bit integer          clock sequence\n\n   node                   unsigned 48   10-15  The spatially unique\n                          bit integer          node identifier\n\n   In the absence of explicit application or presentation protocol\n   specification to the contrary, a UUID is encoded as a 128-bit object,\n   as follows:\n\n   The fields are encoded as 16 octets, with the sizes and order of the\n   fields defined above, and with each field encoded with the Most\n   Significant Byte first (known as network byte order).  Note that the\n   field names, particularly for multiplexed fields, follow historical\n   practice.\n\n   0                   1                   2                   3\n    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |                          time_low                             |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |       time_mid                |         time_hi_and_version   |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |clk_seq_hi_res |  clk_seq_low  |         node (0-1)            |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |                         node (2-5)                            |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\n4.1.3.  Version\n\n   The version number is in the most significant 4 bits of the time\n   stamp (bits 4 through 7 of the time_hi_and_version field).\n\n   The following table lists the currently-defined versions for this\n   UUID variant.\n\n   Msb0  Msb1  Msb2  Msb3   Version  Description\n\n    0     0     0     1        1     The time-based version\n                                     specified in this document.\n\n    0     0     1     0        2     DCE Security version, with\n                                     embedded POSIX UIDs.\n\n\n\nLeach, et al.               Standards Track                     [Page 7]\n\f\nRFC 4122                  A UUID URN Namespace                 July 2005\n\n\n    0     0     1     1        3     The name-based version\n                                     specified in this document\n                                     that uses MD5 hashing.\n\n    0     1     0     0        4     The randomly or pseudo-\n                                     randomly generated version\n                                     specified in this document.\n\n    0     1     0     1        5     The name-based version\n                                     specified in this document\n                                     that uses SHA-1 hashing.\n\n   The version is more accurately a sub-type; again, we retain the term\n   for compatibility.\n\n4.1.4.  Timestamp\n\n   The timestamp is a 60-bit value.  For UUID version 1, this is\n   represented by Coordinated Universal Time (UTC) as a count of 100-\n   nanosecond intervals since 00:00:00.00, 15 October 1582 (the date of\n   Gregorian reform to the Christian calendar).\n\n   For systems that do not have UTC available, but do have the local\n   time, they may use that instead of UTC, as long as they do so\n   consistently throughout the system.  However, this is not recommended\n   since generating the UTC from local time only needs a time zone\n   offset.\n\n   For UUID version 3 or 5, the timestamp is a 60-bit value constructed\n   from a name as described in Section 4.3.\n\n   For UUID version 4, the timestamp is a randomly or pseudo-randomly\n   generated 60-bit value, as described in Section 4.4.\n\n4.1.5.  Clock Sequence\n\n   For UUID version 1, the clock sequence is used to help avoid\n   duplicates that could arise when the clock is set backwards in time\n   or if the node ID changes.\n\n   If the clock is set backwards, or might have been set backwards\n   (e.g., while the system was powered off), and the UUID generator can\n   not be sure that no UUIDs were generated with timestamps larger than\n   the value to which the clock was set, then the clock sequence has to\n   be changed.  If the previous value of the clock sequence is known, it\n   can just be incremented; otherwise it should be set to a random or\n   high-quality pseudo-random value.\n\n\n\n\nLeach, et al.               Standards Track                     [Page 8]\n\f\nRFC 4122                  A UUID URN Namespace                 July 2005\n\n\n   Similarly, if the node ID changes (e.g., because a network card has\n   been moved between machines), setting the clock sequence to a random\n   number minimizes the probability of a duplicate due to slight\n   differences in the clock settings of the machines.  If the value of\n   clock sequence associated with the changed node ID were known, then\n   the clock sequence could just be incremented, but that is unlikely.\n\n   The clock sequence MUST be originally (i.e., once in the lifetime of\n   a system) initialized to a random number to minimize the correlation\n   across systems.  This provides maximum protection against node\n   identifiers that may move or switch from system to system rapidly.\n   The initial value MUST NOT be correlated to the node identifier.\n\n   For UUID version 3 or 5, the clock sequence is a 14-bit value\n   constructed from a name as described in Section 4.3.\n\n   For UUID version 4, clock sequence is a randomly or pseudo-randomly\n   generated 14-bit value as described in Section 4.4.\n\n4.1.6.  Node\n\n   For UUID version 1, the node field consists of an IEEE 802 MAC\n   address, usually the host address.  For systems with multiple IEEE\n   802 addresses, any available one can be used.  The lowest addressed\n   octet (octet number 10) contains the global/local bit and the\n   unicast/multicast bit, and is the first octet of the address\n   transmitted on an 802.3 LAN.\n\n   For systems with no IEEE address, a randomly or pseudo-randomly\n   generated value may be used; see Section 4.5.  The multicast bit must\n   be set in such addresses, in order that they will never conflict with\n   addresses obtained from network cards.\n\n   For UUID version 3 or 5, the node field is a 48-bit value constructed\n   from a name as described in Section 4.3.\n\n   For UUID version 4, the node field is a randomly or pseudo-randomly\n   generated 48-bit value as described in Section 4.4.\n\n4.1.7.  Nil UUID\n\n   The nil UUID is special form of UUID that is specified to have all\n   128 bits set to zero.\n\n4.2.  Algorithms for Creating a Time-Based UUID\n\n   Various aspects of the algorithm for creating a version 1 UUID are\n   discussed in the following sections.\n\n\n\nLeach, et al.               Standards Track                     [Page 9]\n\f\nRFC 4122                  A UUID URN Namespace                 July 2005\n\n\n4.2.1.  Basic Algorithm\n\n   The following algorithm is simple, correct, and inefficient:\n\n   o  Obtain a system-wide global lock\n\n   o  From a system-wide shared stable store (e.g., a file), read the\n      UUID generator state: the values of the timestamp, clock sequence,\n      and node ID used to generate the last UUID.\n\n   o  Get the current time as a 60-bit count of 100-nanosecond intervals\n      since 00:00:00.00, 15 October 1582.\n\n   o  Get the current node ID.\n\n   o  If the state was unavailable (e.g., non-existent or corrupted), or\n      the saved node ID is different than the current node ID, generate\n      a random clock sequence value.\n\n   o  If the state was available, but the saved timestamp is later than\n      the current timestamp, increment the clock sequence value.\n\n   o  Save the state (current timestamp, clock sequence, and node ID)\n      back to the stable store.\n\n   o  Release the global lock.\n\n   o  Format a UUID from the current timestamp, clock sequence, and node\n      ID values according to the steps in Section 4.2.2.\n\n   If UUIDs do not need to be frequently generated, the above algorithm\n   may be perfectly adequate.  For higher performance requirements,\n   however, issues with the basic algorithm include:\n\n   o  Reading the state from stable storage each time is inefficient.\n\n   o  The resolution of the system clock may not be 100-nanoseconds.\n\n   o  Writing the state to stable storage each time is inefficient.\n\n   o  Sharing the state across process boundaries may be inefficient.\n\n   Each of these issues can be addressed in a modular fashion by local\n   improvements in the functions that read and write the state and read\n   the clock.  We address each of them in turn in the following\n   sections.\n\n\n\n\n\nLeach, et al.               Standards Track                    [Page 10]\n\f\nRFC 4122                  A UUID URN Namespace                 July 2005\n\n\n4.2.1.1.  Reading Stable Storage\n\n   The state only needs to be read from stable storage once at boot\n   time, if it is read into a system-wide shared volatile store (and\n   updated whenever the stable store is updated).\n\n   If an implementation does not have any stable store available, then\n   it can always say that the values were unavailable.  This is the\n   least desirable implementation because it will increase the frequency\n   of creation of new clock sequence numbers, which increases the\n   probability of duplicates.\n\n   If the node ID can never change (e.g., the net card is inseparable\n   from the system), or if any change also reinitializes the clock\n   sequence to a random value, then instead of keeping it in stable\n   store, the current node ID may be returned.\n\n4.2.1.2.  System Clock Resolution\n\n   The timestamp is generated from the system time, whose resolution may\n   be less than the resolution of the UUID timestamp.\n\n   If UUIDs do not need to be frequently generated, the timestamp can\n   simply be the system time multiplied by the number of 100-nanosecond\n   intervals per system time interval.\n\n   If a system overruns the generator by requesting too many UUIDs\n   within a single system time interval, the UUID service MUST either\n   return an error, or stall the UUID generator until the system clock\n   catches up.\n\n   A high resolution timestamp can be simulated by keeping a count of\n   the number of UUIDs that have been generated with the same value of\n   the system time, and using it to construct the low order bits of the\n   timestamp.  The count will range between zero and the number of\n   100-nanosecond intervals per system time interval.\n\n   Note: If the processors overrun the UUID generation frequently,\n   additional node identifiers can be allocated to the system, which\n   will permit higher speed allocation by making multiple UUIDs\n   potentially available for each time stamp value.\n\n4.2.1.3.  Writing Stable Storage\n\n   The state does not always need to be written to stable store every\n   time a UUID is generated.  The timestamp in the stable store can be\n   periodically set to a value larger than any yet used in a UUID.  As\n   long as the generated UUIDs have timestamps less than that value, and\n\n\n\nLeach, et al.               Standards Track                    [Page 11]\n\f\nRFC 4122                  A UUID URN Namespace                 July 2005\n\n\n   the clock sequence and node ID remain unchanged, only the shared\n   volatile copy of the state needs to be updated.  Furthermore, if the\n   timestamp value in stable store is in the future by less than the\n   typical time it takes the system to reboot, a crash will not cause a\n   reinitialization of the clock sequence.\n\n4.2.1.4.  Sharing State Across Processes\n\n   If it is too expensive to access shared state each time a UUID is\n   generated, then the system-wide generator can be implemented to\n   allocate a block of time stamps each time it is called; a per-\n   process generator can allocate from that block until it is exhausted.\n\n4.2.2.  Generation Details\n\n   Version 1 UUIDs are generated according to the following algorithm:\n\n   o  Determine the values for the UTC-based timestamp and clock\n      sequence to be used in the UUID, as described in Section 4.2.1.\n\n   o  For the purposes of this algorithm, consider the timestamp to be a\n      60-bit unsigned integer and the clock sequence to be a 14-bit\n      unsigned integer.  Sequentially number the bits in a field,\n      starting with zero for the least significant bit.\n\n   o  Set the time_low field equal to the least significant 32 bits\n      (bits zero through 31) of the timestamp in the same order of\n      significance.\n\n   o  Set the time_mid field equal to bits 32 through 47 from the\n      timestamp in the same order of significance.\n\n   o  Set the 12 least significant bits (bits zero through 11) of the\n      time_hi_and_version field equal to bits 48 through 59 from the\n      timestamp in the same order of significance.\n\n   o  Set the four most significant bits (bits 12 through 15) of the\n      time_hi_and_version field to the 4-bit version number\n      corresponding to the UUID version being created, as shown in the\n      table above.\n\n   o  Set the clock_seq_low field to the eight least significant bits\n      (bits zero through 7) of the clock sequence in the same order of\n      significance.\n\n\n\n\n\n\n\nLeach, et al.               Standards Track                    [Page 12]\n\f\nRFC 4122                  A UUID URN Namespace                 July 2005\n\n\n   o  Set the 6 least significant bits (bits zero through 5) of the\n      clock_seq_hi_and_reserved field to the 6 most significant bits\n      (bits 8 through 13) of the clock sequence in the same order of\n      significance.\n\n   o  Set the two most significant bits (bits 6 and 7) of the\n      clock_seq_hi_and_reserved to zero and one, respectively.\n\n   o  Set the node field to the 48-bit IEEE address in the same order of\n      significance as the address.\n\n4.3.  Algorithm for Creating a Name-Based UUID\n\n   The version 3 or 5 UUID is meant for generating UUIDs from \"names\"\n   that are drawn from, and unique within, some \"name space\".  The\n   concept of name and name space should be broadly construed, and not\n   limited to textual names.  For example, some name spaces are the\n   domain name system, URLs, ISO Object IDs (OIDs), X.500 Distinguished\n   Names (DNs), and reserved words in a programming language.  The\n   mechanisms or conventions used for allocating names and ensuring\n   their uniqueness within their name spaces are beyond the scope of\n   this specification.\n\n   The requirements for these types of UUIDs are as follows:\n\n   o  The UUIDs generated at different times from the same name in the\n      same namespace MUST be equal.\n\n   o  The UUIDs generated from two different names in the same namespace\n      should be different (with very high probability).\n\n   o  The UUIDs generated from the same name in two different namespaces\n      should be different with (very high probability).\n\n   o  If two UUIDs that were generated from names are equal, then they\n      were generated from the same name in the same namespace (with very\n      high probability).\n\n   The algorithm for generating a UUID from a name and a name space are\n   as follows:\n\n   o  Allocate a UUID to use as a \"name space ID\" for all UUIDs\n      generated from names in that name space; see Appendix C for some\n      pre-defined values.\n\n   o  Choose either MD5 [4] or SHA-1 [8] as the hash algorithm; If\n      backward compatibility is not an issue, SHA-1 is preferred.\n\n\n\n\nLeach, et al.               Standards Track                    [Page 13]\n\f\nRFC 4122                  A UUID URN Namespace                 July 2005\n\n\n   o  Convert the name to a canonical sequence of octets (as defined by\n      the standards or conventions of its name space); put the name\n      space ID in network byte order.\n\n   o  Compute the hash of the name space ID concatenated with the name.\n\n   o  Set octets zero through 3 of the time_low field to octets zero\n      through 3 of the hash.\n\n   o  Set octets zero and one of the time_mid field to octets 4 and 5 of\n      the hash.\n\n   o  Set octets zero and one of the time_hi_and_version field to octets\n      6 and 7 of the hash.\n\n   o  Set the four most significant bits (bits 12 through 15) of the\n      time_hi_and_version field to the appropriate 4-bit version number\n      from Section 4.1.3.\n\n   o  Set the clock_seq_hi_and_reserved field to octet 8 of the hash.\n\n   o  Set the two most significant bits (bits 6 and 7) of the\n      clock_seq_hi_and_reserved to zero and one, respectively.\n\n   o  Set the clock_seq_low field to octet 9 of the hash.\n\n   o  Set octets zero through five of the node field to octets 10\n      through 15 of the hash.\n\n   o  Convert the resulting UUID to local byte order.\n\n4.4.  Algorithms for Creating a UUID from Truly Random or\n      Pseudo-Random Numbers\n\n   The version 4 UUID is meant for generating UUIDs from truly-random or\n   pseudo-random numbers.\n\n   The algorithm is as follows:\n\n   o  Set the two most significant bits (bits 6 and 7) of the\n      clock_seq_hi_and_reserved to zero and one, respectively.\n\n   o  Set the four most significant bits (bits 12 through 15) of the\n      time_hi_and_version field to the 4-bit version number from\n      Section 4.1.3.\n\n   o  Set all the other bits to randomly (or pseudo-randomly) chosen\n      values.\n\n\n\nLeach, et al.               Standards Track                    [Page 14]\n\f\nRFC 4122                  A UUID URN Namespace                 July 2005\n\n\n   See Section 4.5 for a discussion on random numbers.\n\n4.5.  Node IDs that Do Not Identify the Host\n\n   This section describes how to generate a version 1 UUID if an IEEE\n   802 address is not available, or its use is not desired.\n\n   One approach is to contact the IEEE and get a separate block of\n   addresses.  At the time of writing, the application could be found at\n   <http://standards.ieee.org/regauth/oui/pilot-ind.html>, and the cost\n   was US$550.\n\n   A better solution is to obtain a 47-bit cryptographic quality random\n   number and use it as the low 47 bits of the node ID, with the least\n   significant bit of the first octet of the node ID set to one.  This\n   bit is the unicast/multicast bit, which will never be set in IEEE 802\n   addresses obtained from network cards.  Hence, there can never be a\n   conflict between UUIDs generated by machines with and without network\n   cards.  (Recall that the IEEE 802 spec talks about transmission\n   order, which is the opposite of the in-memory representation that is\n   discussed in this document.)\n\n   For compatibility with earlier specifications, note that this\n   document uses the unicast/multicast bit, instead of the arguably more\n   correct local/global bit.\n\n   Advice on generating cryptographic-quality random numbers can be\n   found in RFC1750 [5].\n\n   In addition, items such as the computer's name and the name of the\n   operating system, while not strictly speaking random, will help\n   differentiate the results from those obtained by other systems.\n\n   The exact algorithm to generate a node ID using these data is system\n   specific, because both the data available and the functions to obtain\n   them are often very system specific.  A generic approach, however, is\n   to accumulate as many sources as possible into a buffer, use a\n   message digest such as MD5 [4] or SHA-1 [8], take an arbitrary 6\n   bytes from the hash value, and set the multicast bit as described\n   above.\n\n5.  Community Considerations\n\n   The use of UUIDs is extremely pervasive in computing.  They comprise\n   the core identifier infrastructure for many operating systems\n   (Microsoft Windows) and applications (the Mozilla browser) and in\n   many cases, become exposed to the Web in many non-standard ways.\n\n\n\n\nLeach, et al.               Standards Track                    [Page 15]\n\f\nRFC 4122                  A UUID URN Namespace                 July 2005\n\n\n   This specification attempts to standardize that practice as openly as\n   possible and in a way that attempts to benefit the entire Internet.\n\n6.  Security Considerations\n\n   Do not assume that UUIDs are hard to guess; they should not be used\n   as security capabilities (identifiers whose mere possession grants\n   access), for example.  A predictable random number source will\n   exacerbate the situation.\n\n   Do not assume that it is easy to determine if a UUID has been\n   slightly transposed in order to redirect a reference to another\n   object.  Humans do not have the ability to easily check the integrity\n   of a UUID by simply glancing at it.\n\n   Distributed applications generating UUIDs at a variety of hosts must\n   be willing to rely on the random number source at all hosts.  If this\n   is not feasible, the namespace variant should be used.\n\n7.  Acknowledgments\n\n   This document draws heavily on the OSF DCE specification for UUIDs.\n   Ted Ts'o provided helpful comments, especially on the byte ordering\n   section which we mostly plagiarized from a proposed wording he\n   supplied (all errors in that section are our responsibility,\n   however).\n\n   We are also grateful to the careful reading and bit-twiddling of Ralf\n   S. Engelschall, John Larmouth, and Paul Thorpe.  Professor Larmouth\n   was also invaluable in achieving coordination with ISO/IEC.\n\n8.  Normative References\n\n   [1]  Zahn, L., Dineen, T., and P. Leach, \"Network Computing\n        Architecture\", ISBN 0-13-611674-4, January 1990.\n\n   [2]  \"DCE: Remote Procedure Call\", Open Group CAE Specification C309,\n        ISBN 1-85912-041-5, August 1994.\n\n   [3]  ISO/IEC 9834-8:2004 Information Technology, \"Procedures for the\n        operation of OSI Registration Authorities: Generation and\n        registration of Universally Unique Identifiers (UUIDs) and their\n        use as ASN.1 Object Identifier components\" ITU-T Rec. X.667,\n        2004.\n\n   [4]  Rivest, R., \"The MD5 Message-Digest Algorithm \", RFC 1321, April\n        1992.\n\n\n\n\nLeach, et al.               Standards Track                    [Page 16]\n\f\nRFC 4122                  A UUID URN Namespace                 July 2005\n\n\n   [5]  Eastlake, D., 3rd, Schiller, J., and S. Crocker, \"Randomness\n        Requirements for Security\", BCP 106, RFC 4086, June 2005.\n\n   [6]  Moats, R., \"URN Syntax\", RFC 2141, May 1997.\n\n   [7]  Crocker, D. and P. Overell, \"Augmented BNF for Syntax\n        Specifications: ABNF\", RFC 2234, November 1997.\n\n   [8]  National Institute of Standards and Technology, \"Secure Hash\n        Standard\", FIPS PUB 180-1, April 1995,\n        <http://www.itl.nist.gov/fipspubs/fip180-1.htm>.\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nLeach, et al.               Standards Track                    [Page 17]\n\f\nRFC 4122                  A UUID URN Namespace                 July 2005\n\n\nAppendix A.  Appendix A - Sample Implementation\n\n   This implementation consists of 5 files: uuid.h, uuid.c, sysdep.h,\n   sysdep.c and utest.c.  The uuid.* files are the system independent\n   implementation of the UUID generation algorithms described above,\n   with all the optimizations described above except efficient state\n   sharing across processes included.  The code has been tested on Linux\n   (Red Hat 4.0) with GCC (2.7.2), and Windows NT 4.0 with VC++ 5.0.\n   The code assumes 64-bit integer support, which makes it much clearer.\n\n   All the following source files should have the following copyright\n   notice included:\n\ncopyrt.h\n\n/*\n** Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\n** Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. &\n** Digital Equipment Corporation, Maynard, Mass.\n** Copyright (c) 1998 Microsoft.\n** To anyone who acknowledges that this file is provided \"AS IS\"\n** without any express or implied warranty: permission to use, copy,\n** modify, and distribute this file for any purpose is hereby\n** granted without fee, provided that the above copyright notices and\n** this notice appears in all source code copies, and that none of\n** the names of Open Software Foundation, Inc., Hewlett-Packard\n** Company, Microsoft, or Digital Equipment Corporation be used in\n** advertising or publicity pertaining to distribution of the software\n** without specific, written prior permission. Neither Open Software\n** Foundation, Inc., Hewlett-Packard Company, Microsoft, nor Digital\n** Equipment Corporation makes any representations about the\n** suitability of this software for any purpose.\n*/\n\n\nuuid.h\n\n#include \"copyrt.h\"\n#undef uuid_t\ntypedef struct {\n    unsigned32  time_low;\n    unsigned16  time_mid;\n    unsigned16  time_hi_and_version;\n    unsigned8   clock_seq_hi_and_reserved;\n    unsigned8   clock_seq_low;\n    byte        node[6];\n} uuid_t;\n\n\n\n\nLeach, et al.               Standards Track                    [Page 18]\n\f\nRFC 4122                  A UUID URN Namespace                 July 2005\n\n\n/* uuid_create -- generate a UUID */\nint uuid_create(uuid_t * uuid);\n\n/* uuid_create_md5_from_name -- create a version 3 (MD5) UUID using a\n   \"name\" from a \"name space\" */\nvoid uuid_create_md5_from_name(\n    uuid_t *uuid,         /* resulting UUID */\n    uuid_t nsid,          /* UUID of the namespace */\n    void *name,           /* the name from which to generate a UUID */\n    int namelen           /* the length of the name */\n);\n\n/* uuid_create_sha1_from_name -- create a version 5 (SHA-1) UUID\n   using a \"name\" from a \"name space\" */\nvoid uuid_create_sha1_from_name(\n\n    uuid_t *uuid,         /* resulting UUID */\n    uuid_t nsid,          /* UUID of the namespace */\n    void *name,           /* the name from which to generate a UUID */\n    int namelen           /* the length of the name */\n);\n\n/* uuid_compare --  Compare two UUID's \"lexically\" and return\n        -1   u1 is lexically before u2\n         0   u1 is equal to u2\n         1   u1 is lexically after u2\n   Note that lexical ordering is not temporal ordering!\n*/\nint uuid_compare(uuid_t *u1, uuid_t *u2);\n\n\nuuid.c\n\n#include \"copyrt.h\"\n#include <string.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <time.h>\n#include \"sysdep.h\"\n#include \"uuid.h\"\n\n/* various forward declarations */\nstatic int read_state(unsigned16 *clockseq, uuid_time_t *timestamp,\n    uuid_node_t *node);\nstatic void write_state(unsigned16 clockseq, uuid_time_t timestamp,\n    uuid_node_t node);\nstatic void format_uuid_v1(uuid_t *uuid, unsigned16 clockseq,\n    uuid_time_t timestamp, uuid_node_t node);\n\n\n\nLeach, et al.               Standards Track                    [Page 19]\n\f\nRFC 4122                  A UUID URN Namespace                 July 2005\n\n\nstatic void format_uuid_v3or5(uuid_t *uuid, unsigned char hash[16],\n    int v);\nstatic void get_current_time(uuid_time_t *timestamp);\nstatic unsigned16 true_random(void);\n\n/* uuid_create -- generator a UUID */\nint uuid_create(uuid_t *uuid)\n{\n     uuid_time_t timestamp, last_time;\n     unsigned16 clockseq;\n     uuid_node_t node;\n     uuid_node_t last_node;\n     int f;\n\n     /* acquire system-wide lock so we're alone */\n     LOCK;\n     /* get time, node ID, saved state from non-volatile storage */\n     get_current_time(&timestamp);\n     get_ieee_node_identifier(&node);\n     f = read_state(&clockseq, &last_time, &last_node);\n\n     /* if no NV state, or if clock went backwards, or node ID\n        changed (e.g., new network card) change clockseq */\n     if (!f || memcmp(&node, &last_node, sizeof node))\n         clockseq = true_random();\n     else if (timestamp < last_time)\n         clockseq++;\n\n     /* save the state for next time */\n     write_state(clockseq, timestamp, node);\n\n     UNLOCK;\n\n     /* stuff fields into the UUID */\n     format_uuid_v1(uuid, clockseq, timestamp, node);\n     return 1;\n}\n\n/* format_uuid_v1 -- make a UUID from the timestamp, clockseq,\n                     and node ID */\nvoid format_uuid_v1(uuid_t* uuid, unsigned16 clock_seq,\n                    uuid_time_t timestamp, uuid_node_t node)\n{\n    /* Construct a version 1 uuid with the information we've gathered\n       plus a few constants. */\n    uuid->time_low = (unsigned long)(timestamp & 0xFFFFFFFF);\n    uuid->time_mid = (unsigned short)((timestamp >> 32) & 0xFFFF);\n    uuid->time_hi_and_version =\n\n\n\nLeach, et al.               Standards Track                    [Page 20]\n\f\nRFC 4122                  A UUID URN Namespace                 July 2005\n\n\n        (unsigned short)((timestamp >> 48) & 0x0FFF);\n    uuid->time_hi_and_version |= (1 << 12);\n    uuid->clock_seq_low = clock_seq & 0xFF;\n    uuid->clock_seq_hi_and_reserved = (clock_seq & 0x3F00) >> 8;\n    uuid->clock_seq_hi_and_reserved |= 0x80;\n    memcpy(&uuid->node, &node, sizeof uuid->node);\n}\n\n/* data type for UUID generator persistent state */\ntypedef struct {\n    uuid_time_t  ts;       /* saved timestamp */\n    uuid_node_t  node;     /* saved node ID */\n    unsigned16   cs;       /* saved clock sequence */\n} uuid_state;\n\nstatic uuid_state st;\n\n/* read_state -- read UUID generator state from non-volatile store */\nint read_state(unsigned16 *clockseq, uuid_time_t *timestamp,\n               uuid_node_t *node)\n{\n    static int inited = 0;\n    FILE *fp;\n\n    /* only need to read state once per boot */\n    if (!inited) {\n        fp = fopen(\"state\", \"rb\");\n        if (fp == NULL)\n            return 0;\n        fread(&st, sizeof st, 1, fp);\n        fclose(fp);\n        inited = 1;\n    }\n    *clockseq = st.cs;\n    *timestamp = st.ts;\n    *node = st.node;\n    return 1;\n}\n\n/* write_state -- save UUID generator state back to non-volatile\n   storage */\nvoid write_state(unsigned16 clockseq, uuid_time_t timestamp,\n                 uuid_node_t node)\n{\n    static int inited = 0;\n    static uuid_time_t next_save;\n    FILE* fp;\n\n\n\n\nLeach, et al.               Standards Track                    [Page 21]\n\f\nRFC 4122                  A UUID URN Namespace                 July 2005\n\n\n    if (!inited) {\n        next_save = timestamp;\n        inited = 1;\n    }\n\n    /* always save state to volatile shared state */\n    st.cs = clockseq;\n    st.ts = timestamp;\n    st.node = node;\n    if (timestamp >= next_save) {\n        fp = fopen(\"state\", \"wb\");\n        fwrite(&st, sizeof st, 1, fp);\n        fclose(fp);\n        /* schedule next save for 10 seconds from now */\n        next_save = timestamp + (10 * 10 * 1000 * 1000);\n    }\n}\n\n/* get-current_time -- get time as 60-bit 100ns ticks since UUID epoch.\n   Compensate for the fact that real clock resolution is\n   less than 100ns. */\nvoid get_current_time(uuid_time_t *timestamp)\n{\n    static int inited = 0;\n    static uuid_time_t time_last;\n    static unsigned16 uuids_this_tick;\n    uuid_time_t time_now;\n\n    if (!inited) {\n        get_system_time(&time_now);\n        uuids_this_tick = UUIDS_PER_TICK;\n        inited = 1;\n    }\n\n    for ( ; ; ) {\n        get_system_time(&time_now);\n\n        /* if clock reading changed since last UUID generated, */\n        if (time_last != time_now) {\n            /* reset count of uuids gen'd with this clock reading */\n            uuids_this_tick = 0;\n            time_last = time_now;\n            break;\n        }\n        if (uuids_this_tick < UUIDS_PER_TICK) {\n            uuids_this_tick++;\n            break;\n        }\n\n\n\nLeach, et al.               Standards Track                    [Page 22]\n\f\nRFC 4122                  A UUID URN Namespace                 July 2005\n\n\n        /* going too fast for our clock; spin */\n    }\n    /* add the count of uuids to low order bits of the clock reading */\n    *timestamp = time_now + uuids_this_tick;\n}\n\n/* true_random -- generate a crypto-quality random number.\n   **This sample doesn't do that.** */\nstatic unsigned16 true_random(void)\n{\n    static int inited = 0;\n    uuid_time_t time_now;\n\n    if (!inited) {\n        get_system_time(&time_now);\n        time_now = time_now / UUIDS_PER_TICK;\n        srand((unsigned int)\n               (((time_now >> 32) ^ time_now) & 0xffffffff));\n        inited = 1;\n    }\n\n    return rand();\n}\n\n/* uuid_create_md5_from_name -- create a version 3 (MD5) UUID using a\n   \"name\" from a \"name space\" */\nvoid uuid_create_md5_from_name(uuid_t *uuid, uuid_t nsid, void *name,\n                               int namelen)\n{\n    MD5_CTX c;\n    unsigned char hash[16];\n    uuid_t net_nsid;\n\n    /* put name space ID in network byte order so it hashes the same\n       no matter what endian machine we're on */\n    net_nsid = nsid;\n    net_nsid.time_low = htonl(net_nsid.time_low);\n    net_nsid.time_mid = htons(net_nsid.time_mid);\n    net_nsid.time_hi_and_version = htons(net_nsid.time_hi_and_version);\n\n    MD5Init(&c);\n    MD5Update(&c, &net_nsid, sizeof net_nsid);\n    MD5Update(&c, name, namelen);\n    MD5Final(hash, &c);\n\n    /* the hash is in network byte order at this point */\n    format_uuid_v3or5(uuid, hash, 3);\n}\n\n\n\nLeach, et al.               Standards Track                    [Page 23]\n\f\nRFC 4122                  A UUID URN Namespace                 July 2005\n\n\nvoid uuid_create_sha1_from_name(uuid_t *uuid, uuid_t nsid, void *name,\n                                int namelen)\n{\n    SHA_CTX c;\n    unsigned char hash[20];\n    uuid_t net_nsid;\n\n    /* put name space ID in network byte order so it hashes the same\n       no matter what endian machine we're on */\n    net_nsid = nsid;\n    net_nsid.time_low = htonl(net_nsid.time_low);\n    net_nsid.time_mid = htons(net_nsid.time_mid);\n    net_nsid.time_hi_and_version = htons(net_nsid.time_hi_and_version);\n\n    SHA1_Init(&c);\n    SHA1_Update(&c, &net_nsid, sizeof net_nsid);\n    SHA1_Update(&c, name, namelen);\n    SHA1_Final(hash, &c);\n\n    /* the hash is in network byte order at this point */\n    format_uuid_v3or5(uuid, hash, 5);\n}\n\n/* format_uuid_v3or5 -- make a UUID from a (pseudo)random 128-bit\n   number */\nvoid format_uuid_v3or5(uuid_t *uuid, unsigned char hash[16], int v)\n{\n    /* convert UUID to local byte order */\n    memcpy(uuid, hash, sizeof *uuid);\n    uuid->time_low = ntohl(uuid->time_low);\n    uuid->time_mid = ntohs(uuid->time_mid);\n    uuid->time_hi_and_version = ntohs(uuid->time_hi_and_version);\n\n    /* put in the variant and version bits */\n    uuid->time_hi_and_version &= 0x0FFF;\n    uuid->time_hi_and_version |= (v << 12);\n    uuid->clock_seq_hi_and_reserved &= 0x3F;\n    uuid->clock_seq_hi_and_reserved |= 0x80;\n}\n\n/* uuid_compare --  Compare two UUID's \"lexically\" and return */\n#define CHECK(f1, f2) if (f1 != f2) return f1 < f2 ? -1 : 1;\nint uuid_compare(uuid_t *u1, uuid_t *u2)\n{\n    int i;\n\n    CHECK(u1->time_low, u2->time_low);\n    CHECK(u1->time_mid, u2->time_mid);\n\n\n\nLeach, et al.               Standards Track                    [Page 24]\n\f\nRFC 4122                  A UUID URN Namespace                 July 2005\n\n\n    CHECK(u1->time_hi_and_version, u2->time_hi_and_version);\n    CHECK(u1->clock_seq_hi_and_reserved, u2->clock_seq_hi_and_reserved);\n    CHECK(u1->clock_seq_low, u2->clock_seq_low)\n    for (i = 0; i < 6; i++) {\n        if (u1->node[i] < u2->node[i])\n            return -1;\n        if (u1->node[i] > u2->node[i])\n            return 1;\n    }\n    return 0;\n}\n#undef CHECK\n\n\nsysdep.h\n\n#include \"copyrt.h\"\n/* remove the following define if you aren't running WIN32 */\n#define WININC 0\n\n#ifdef WININC\n#include <windows.h>\n#else\n#include <sys/types.h>\n#include <sys/time.h>\n#include <sys/sysinfo.h>\n#endif\n\n#include \"global.h\"\n/* change to point to where MD5 .h's live; RFC 1321 has sample\n   implementation */\n#include \"md5.h\"\n\n/* set the following to the number of 100ns ticks of the actual\n   resolution of your system's clock */\n#define UUIDS_PER_TICK 1024\n\n/* Set the following to a calls to get and release a global lock */\n#define LOCK\n#define UNLOCK\n\ntypedef unsigned long   unsigned32;\ntypedef unsigned short  unsigned16;\ntypedef unsigned char   unsigned8;\ntypedef unsigned char   byte;\n\n/* Set this to what your compiler uses for 64-bit data type */\n#ifdef WININC\n\n\n\nLeach, et al.               Standards Track                    [Page 25]\n\f\nRFC 4122                  A UUID URN Namespace                 July 2005\n\n\n#define unsigned64_t unsigned __int64\n#define I64(C) C\n#else\n#define unsigned64_t unsigned long long\n#define I64(C) C##LL\n#endif\n\ntypedef unsigned64_t uuid_time_t;\ntypedef struct {\n    char nodeID[6];\n} uuid_node_t;\n\nvoid get_ieee_node_identifier(uuid_node_t *node);\nvoid get_system_time(uuid_time_t *uuid_time);\nvoid get_random_info(char seed[16]);\n\n\nsysdep.c\n\n#include \"copyrt.h\"\n#include <stdio.h>\n#include \"sysdep.h\"\n\n/* system dependent call to get IEEE node ID.\n   This sample implementation generates a random node ID. */\nvoid get_ieee_node_identifier(uuid_node_t *node)\n{\n    static inited = 0;\n    static uuid_node_t saved_node;\n    char seed[16];\n    FILE *fp;\n\n    if (!inited) {\n        fp = fopen(\"nodeid\", \"rb\");\n        if (fp) {\n            fread(&saved_node, sizeof saved_node, 1, fp);\n            fclose(fp);\n        }\n        else {\n            get_random_info(seed);\n            seed[0] |= 0x01;\n            memcpy(&saved_node, seed, sizeof saved_node);\n            fp = fopen(\"nodeid\", \"wb\");\n            if (fp) {\n                fwrite(&saved_node, sizeof saved_node, 1, fp);\n                fclose(fp);\n            }\n        }\n\n\n\nLeach, et al.               Standards Track                    [Page 26]\n\f\nRFC 4122                  A UUID URN Namespace                 July 2005\n\n\n        inited = 1;\n    }\n\n    *node = saved_node;\n}\n\n/* system dependent call to get the current system time. Returned as\n   100ns ticks since UUID epoch, but resolution may be less than\n   100ns. */\n#ifdef _WINDOWS_\n\nvoid get_system_time(uuid_time_t *uuid_time)\n{\n    ULARGE_INTEGER time;\n\n    /* NT keeps time in FILETIME format which is 100ns ticks since\n       Jan 1, 1601. UUIDs use time in 100ns ticks since Oct 15, 1582.\n       The difference is 17 Days in Oct + 30 (Nov) + 31 (Dec)\n       + 18 years and 5 leap days. */\n    GetSystemTimeAsFileTime((FILETIME *)&time);\n    time.QuadPart +=\n\n          (unsigned __int64) (1000*1000*10)       // seconds\n        * (unsigned __int64) (60 * 60 * 24)       // days\n        * (unsigned __int64) (17+30+31+365*18+5); // # of days\n    *uuid_time = time.QuadPart;\n}\n\n/* Sample code, not for use in production; see RFC 1750 */\nvoid get_random_info(char seed[16])\n{\n    MD5_CTX c;\n    struct {\n        MEMORYSTATUS m;\n        SYSTEM_INFO s;\n        FILETIME t;\n        LARGE_INTEGER pc;\n        DWORD tc;\n        DWORD l;\n        char hostname[MAX_COMPUTERNAME_LENGTH + 1];\n    } r;\n\n    MD5Init(&c);\n    GlobalMemoryStatus(&r.m);\n    GetSystemInfo(&r.s);\n    GetSystemTimeAsFileTime(&r.t);\n    QueryPerformanceCounter(&r.pc);\n    r.tc = GetTickCount();\n\n\n\nLeach, et al.               Standards Track                    [Page 27]\n\f\nRFC 4122                  A UUID URN Namespace                 July 2005\n\n\n    r.l = MAX_COMPUTERNAME_LENGTH + 1;\n    GetComputerName(r.hostname, &r.l);\n    MD5Update(&c, &r, sizeof r);\n    MD5Final(seed, &c);\n}\n\n#else\n\nvoid get_system_time(uuid_time_t *uuid_time)\n{\n    struct timeval tp;\n\n    gettimeofday(&tp, (struct timezone *)0);\n\n    /* Offset between UUID formatted times and Unix formatted times.\n       UUID UTC base time is October 15, 1582.\n       Unix base time is January 1, 1970.*/\n    *uuid_time = ((unsigned64)tp.tv_sec * 10000000)\n        + ((unsigned64)tp.tv_usec * 10)\n        + I64(0x01B21DD213814000);\n}\n\n/* Sample code, not for use in production; see RFC 1750 */\nvoid get_random_info(char seed[16])\n{\n    MD5_CTX c;\n    struct {\n        struct sysinfo s;\n        struct timeval t;\n        char hostname[257];\n    } r;\n\n    MD5Init(&c);\n    sysinfo(&r.s);\n    gettimeofday(&r.t, (struct timezone *)0);\n    gethostname(r.hostname, 256);\n    MD5Update(&c, &r, sizeof r);\n    MD5Final(seed, &c);\n}\n\n#endif\n\nutest.c\n\n#include \"copyrt.h\"\n#include \"sysdep.h\"\n#include <stdio.h>\n#include \"uuid.h\"\n\n\n\nLeach, et al.               Standards Track                    [Page 28]\n\f\nRFC 4122                  A UUID URN Namespace                 July 2005\n\n\nuuid_t NameSpace_DNS = { /* 6ba7b810-9dad-11d1-80b4-00c04fd430c8 */\n    0x6ba7b810,\n    0x9dad,\n    0x11d1,\n    0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8\n};\n\n/* puid -- print a UUID */\nvoid puid(uuid_t u)\n{\n    int i;\n\n    printf(\"%8.8x-%4.4x-%4.4x-%2.2x%2.2x-\", u.time_low, u.time_mid,\n    u.time_hi_and_version, u.clock_seq_hi_and_reserved,\n    u.clock_seq_low);\n    for (i = 0; i < 6; i++)\n        printf(\"%2.2x\", u.node[i]);\n    printf(\"\\n\");\n}\n\n/* Simple driver for UUID generator */\nvoid main(int argc, char **argv)\n{\n    uuid_t u;\n    int f;\n\n    uuid_create(&u);\n    printf(\"uuid_create(): \"); puid(u);\n\n    f = uuid_compare(&u, &u);\n    printf(\"uuid_compare(u,u): %d\\n\", f);     /* should be 0 */\n    f = uuid_compare(&u, &NameSpace_DNS);\n    printf(\"uuid_compare(u, NameSpace_DNS): %d\\n\", f); /* s.b. 1 */\n    f = uuid_compare(&NameSpace_DNS, &u);\n    printf(\"uuid_compare(NameSpace_DNS, u): %d\\n\", f); /* s.b. -1 */\n    uuid_create_md5_from_name(&u, NameSpace_DNS, \"www.widgets.com\", 15);\n    printf(\"uuid_create_md5_from_name(): \"); puid(u);\n}\n\nAppendix B.  Appendix B - Sample Output of utest\n\n     uuid_create(): 7d444840-9dc0-11d1-b245-5ffdce74fad2\n     uuid_compare(u,u): 0\n     uuid_compare(u, NameSpace_DNS): 1\n     uuid_compare(NameSpace_DNS, u): -1\n     uuid_create_md5_from_name(): e902893a-9d22-3c7e-a7b8-d6e313b71d9f\n\n\n\n\n\nLeach, et al.               Standards Track                    [Page 29]\n\f\nRFC 4122                  A UUID URN Namespace                 July 2005\n\n\nAppendix C.  Appendix C - Some Name Space IDs\n\n   This appendix lists the name space IDs for some potentially\n   interesting name spaces, as initialized C structures and in the\n   string representation defined above.\n\n   /* Name string is a fully-qualified domain name */\n   uuid_t NameSpace_DNS = { /* 6ba7b810-9dad-11d1-80b4-00c04fd430c8 */\n       0x6ba7b810,\n       0x9dad,\n       0x11d1,\n       0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8\n   };\n\n   /* Name string is a URL */\n   uuid_t NameSpace_URL = { /* 6ba7b811-9dad-11d1-80b4-00c04fd430c8 */\n       0x6ba7b811,\n       0x9dad,\n       0x11d1,\n       0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8\n   };\n\n   /* Name string is an ISO OID */\n   uuid_t NameSpace_OID = { /* 6ba7b812-9dad-11d1-80b4-00c04fd430c8 */\n       0x6ba7b812,\n       0x9dad,\n       0x11d1,\n       0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8\n   };\n\n   /* Name string is an X.500 DN (in DER or a text output format) */\n   uuid_t NameSpace_X500 = { /* 6ba7b814-9dad-11d1-80b4-00c04fd430c8 */\n       0x6ba7b814,\n       0x9dad,\n       0x11d1,\n       0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8\n   };\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nLeach, et al.               Standards Track                    [Page 30]\n\f\nRFC 4122                  A UUID URN Namespace                 July 2005\n\n\nAuthors' Addresses\n\n   Paul J. Leach\n   Microsoft\n   1 Microsoft Way\n   Redmond, WA  98052\n   US\n\n   Phone: +1 425-882-8080\n   EMail: paulle@microsoft.com\n\n\n   Michael Mealling\n   Refactored Networks, LLC\n   1635 Old Hwy 41\n   Suite 112, Box 138\n   Kennesaw, GA 30152\n   US\n\n   Phone: +1-678-581-9656\n   EMail: michael@refactored-networks.com\n   URI: http://www.refactored-networks.com\n\n\n   Rich Salz\n   DataPower Technology, Inc.\n   1 Alewife Center\n   Cambridge, MA  02142\n   US\n\n   Phone: +1 617-864-0455\n   EMail: rsalz@datapower.com\n   URI:   http://www.datapower.com\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nLeach, et al.               Standards Track                    [Page 31]\n\f\nRFC 4122                  A UUID URN Namespace                 July 2005\n\n\nFull Copyright Statement\n\n   Copyright (C) The Internet Society (2005).\n\n   This document is subject to the rights, licenses and restrictions\n   contained in BCP 78, and except as set forth therein, the authors\n   retain all their rights.\n\n   This document and the information contained herein are provided on an\n   \"AS IS\" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS\n   OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET\n   ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED,\n   INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE\n   INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED\n   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.\n\nIntellectual Property\n\n   The IETF takes no position regarding the validity or scope of any\n   Intellectual Property Rights or other rights that might be claimed to\n   pertain to the implementation or use of the technology described in\n   this document or the extent to which any license under such rights\n   might or might not be available; nor does it represent that it has\n   made any independent effort to identify any such rights.  Information\n   on the procedures with respect to rights in RFC documents can be\n   found in BCP 78 and BCP 79.\n\n   Copies of IPR disclosures made to the IETF Secretariat and any\n   assurances of licenses to be made available, or the result of an\n   attempt made to obtain a general license or permission for the use of\n   such proprietary rights by implementers or users of this\n   specification can be obtained from the IETF on-line IPR repository at\n   http://www.ietf.org/ipr.\n\n   The IETF invites any interested party to bring to its attention any\n   copyrights, patents or patent applications, or other proprietary\n   rights that may cover technology that may be required to implement\n   this standard.  Please address the information to the IETF at ietf-\n   ipr@ietf.org.\n\nAcknowledgement\n\n   Funding for the RFC Editor function is currently provided by the\n   Internet Society.\n\n\n\n\n\n\n\nLeach, et al.               Standards Track                    [Page 32]\n\f\n"
  },
  {
    "path": "doc/rfc9562.txt",
    "content": "﻿\n\n\n\nInternet Engineering Task Force (IETF)                          K. Davis\nRequest for Comments: 9562                                 Cisco Systems\nObsoletes: 4122                                               B. Peabody\nCategory: Standards Track                                        Uncloud\nISSN: 2070-1721                                                 P. Leach\n                                                University of Washington\n                                                                May 2024\n\n\n                 Universally Unique IDentifiers (UUIDs)\n\nAbstract\n\n   This specification defines UUIDs (Universally Unique IDentifiers) --\n   also known as GUIDs (Globally Unique IDentifiers) -- and a Uniform\n   Resource Name namespace for UUIDs.  A UUID is 128 bits long and is\n   intended to guarantee uniqueness across space and time.  UUIDs were\n   originally used in the Apollo Network Computing System (NCS), later\n   in the Open Software Foundation's (OSF's) Distributed Computing\n   Environment (DCE), and then in Microsoft Windows platforms.\n\n   This specification is derived from the OSF DCE specification with the\n   kind permission of the OSF (now known as \"The Open Group\").\n   Information from earlier versions of the OSF DCE specification have\n   been incorporated into this document.  This document obsoletes RFC\n   4122.\n\nStatus of This Memo\n\n   This is an Internet Standards Track document.\n\n   This document is a product of the Internet Engineering Task Force\n   (IETF).  It represents the consensus of the IETF community.  It has\n   received public review and has been approved for publication by the\n   Internet Engineering Steering Group (IESG).  Further information on\n   Internet Standards is available in Section 2 of RFC 7841.\n\n   Information about the current status of this document, any errata,\n   and how to provide feedback on it may be obtained at\n   https://www.rfc-editor.org/info/rfc9562.\n\nCopyright Notice\n\n   Copyright (c) 2024 IETF Trust and the persons identified as the\n   document authors.  All rights reserved.\n\n   This document is subject to BCP 78 and the IETF Trust's Legal\n   Provisions Relating to IETF Documents\n   (https://trustee.ietf.org/license-info) in effect on the date of\n   publication of this document.  Please review these documents\n   carefully, as they describe your rights and restrictions with respect\n   to this document.  Code Components extracted from this document must\n   include Revised BSD License text as described in Section 4.e of the\n   Trust Legal Provisions and are provided without warranty as described\n   in the Revised BSD License.\n\nTable of Contents\n\n   1.  Introduction\n   2.  Motivation\n     2.1.  Update Motivation\n   3.  Terminology\n     3.1.  Requirements Language\n     3.2.  Abbreviations\n   4.  UUID Format\n     4.1.  Variant Field\n     4.2.  Version Field\n   5.  UUID Layouts\n     5.1.  UUID Version 1\n     5.2.  UUID Version 2\n     5.3.  UUID Version 3\n     5.4.  UUID Version 4\n     5.5.  UUID Version 5\n     5.6.  UUID Version 6\n     5.7.  UUID Version 7\n     5.8.  UUID Version 8\n     5.9.  Nil UUID\n     5.10. Max UUID\n   6.  UUID Best Practices\n     6.1.  Timestamp Considerations\n     6.2.  Monotonicity and Counters\n     6.3.  UUID Generator States\n     6.4.  Distributed UUID Generation\n     6.5.  Name-Based UUID Generation\n     6.6.  Namespace ID Usage and Allocation\n     6.7.  Collision Resistance\n     6.8.  Global and Local Uniqueness\n     6.9.  Unguessability\n     6.10. UUIDs That Do Not Identify the Host\n     6.11. Sorting\n     6.12. Opacity\n     6.13. DBMS and Database Considerations\n   7.  IANA Considerations\n     7.1.  IANA UUID Subtype Registry and Registration\n     7.2.  IANA UUID Namespace ID Registry and Registration\n   8.  Security Considerations\n   9.  References\n     9.1.  Normative References\n     9.2.  Informative References\n   Appendix A.  Test Vectors\n     A.1.  Example of a UUIDv1 Value\n     A.2.  Example of a UUIDv3 Value\n     A.3.  Example of a UUIDv4 Value\n     A.4.  Example of a UUIDv5 Value\n     A.5.  Example of a UUIDv6 Value\n     A.6.  Example of a UUIDv7 Value\n   Appendix B.  Illustrative Examples\n     B.1.  Example of a UUIDv8 Value (Time-Based)\n     B.2.  Example of a UUIDv8 Value (Name-Based)\n   Acknowledgements\n   Authors' Addresses\n\n1.  Introduction\n\n   This specification defines a Uniform Resource Name namespace for\n   Universally Unique IDentifiers (UUIDs), also known as Globally Unique\n   IDentifiers (GUIDs).  A UUID is 128 bits long and requires no central\n   registration process.\n\n   The use of UUIDs is extremely pervasive in computing.  They comprise\n   the core identifier infrastructure for many operating systems such as\n   Microsoft Windows and applications such as the Mozilla Web browser;\n   in many cases, they can become exposed in many non-standard ways.\n\n   This specification attempts to standardize that practice as openly as\n   possible and in a way that attempts to benefit the entire Internet.\n   The information here is meant to be a concise guide for those wishing\n   to implement services using UUIDs either in combination with URNs\n   [RFC8141] or otherwise.\n\n   There is an ITU-T Recommendation and an ISO/IEC Standard [X667] that\n   are derived from [RFC4122].  Both sets of specifications have been\n   aligned and are fully technically compatible.  Nothing in this\n   document should be construed to override the DCE standards that\n   defined UUIDs.\n\n2.  Motivation\n\n   One of the main reasons for using UUIDs is that no centralized\n   authority is required to administer them (although two formats may\n   leverage optional IEEE 802 Node IDs, others do not).  As a result,\n   generation on demand can be completely automated and used for a\n   variety of purposes.  The UUID generation algorithm described here\n   supports very high allocation rates of 10 million per second per\n   machine or more, if necessary, so that they could even be used as\n   transaction IDs.\n\n   UUIDs are of a fixed size (128 bits), which is reasonably small\n   compared to other alternatives.  This lends itself well to sorting,\n   ordering, and hashing of all sorts; storing in databases; simple\n   allocation; and ease of programming in general.\n\n   Since UUIDs are unique and persistent, they make excellent URNs.  The\n   unique ability to generate a new UUID without a registration process\n   allows for UUIDs to be one of the URNs with the lowest minting cost.\n\n2.1.  Update Motivation\n\n   Many things have changed in the time since UUIDs were originally\n   created.  Modern applications have a need to create and utilize UUIDs\n   as the primary identifier for a variety of different items in complex\n   computational systems, including but not limited to database keys,\n   file names, machine or system names, and identifiers for event-driven\n   transactions.\n\n   One area in which UUIDs have gained popularity is database keys.\n   This stems from the increasingly distributed nature of modern\n   applications.  In such cases, \"auto-increment\" schemes that are often\n   used by databases do not work well: the effort required to coordinate\n   sequential numeric identifiers across a network can easily become a\n   burden.  The fact that UUIDs can be used to create unique, reasonably\n   short values in distributed systems without requiring coordination\n   makes them a good alternative, but UUID versions 1-5, which were\n   originally defined by [RFC4122], lack certain other desirable\n   characteristics, such as:\n\n   1.  UUID versions that are not time ordered, such as UUIDv4\n       (described in Section 5.4), have poor database-index locality.\n       This means that new values created in succession are not close to\n       each other in the index; thus, they require inserts to be\n       performed at random locations.  The resulting negative\n       performance effects on the common structures used for this\n       (B-tree and its variants) can be dramatic.\n\n   2.  The 100-nanosecond Gregorian Epoch used in UUIDv1 timestamps\n       (described in Section 5.1) is uncommon and difficult to represent\n       accurately using a standard number format such as that described\n       in [IEEE754].\n\n   3.  Introspection/parsing is required to order by time sequence, as\n       opposed to being able to perform a simple byte-by-byte\n       comparison.\n\n   4.  Privacy and network security issues arise from using a Media\n       Access Control (MAC) address in the node field of UUIDv1.\n       Exposed MAC addresses can be used as an attack surface to locate\n       network interfaces and reveal various other information about\n       such machines (minimally, the manufacturer and, potentially,\n       other details).  Additionally, with the advent of virtual\n       machines and containers, uniqueness of the MAC address is no\n       longer guaranteed.\n\n   5.  Many of the implementation details specified in [RFC4122]\n       involved trade-offs that are neither possible to specify for all\n       applications nor necessary to produce interoperable\n       implementations.\n\n   6.  [RFC4122] did not distinguish between the requirements for\n       generating a UUID and those for simply storing one, although they\n       are often different.\n\n   Due to the aforementioned issues, many widely distributed database\n   applications and large application vendors have sought to solve the\n   problem of creating a better time-based, sortable unique identifier\n   for use as a database key.  This has led to numerous implementations\n   over the past 10+ years solving the same problem in slightly\n   different ways.\n\n   While preparing this specification, the following 16 different\n   implementations were analyzed for trends in total ID length, bit\n   layout, lexical formatting and encoding, timestamp type, timestamp\n   format, timestamp accuracy, node format and components, collision\n   handling, and multi-timestamp tick generation sequencing:\n\n   1.   [ULID]\n   2.   [LexicalUUID]\n   3.   [Snowflake]\n   4.   [Flake]\n   5.   [ShardingID]\n   6.   [KSUID]\n   7.   [Elasticflake]\n   8.   [FlakeID]\n   9.   [Sonyflake]\n   10.  [orderedUuid]\n   11.  [COMBGUID]\n   12.  [SID]\n   13.  [pushID]\n   14.  [XID]\n   15.  [ObjectID]\n   16.  [CUID]\n\n   An inspection of these implementations and the issues described above\n   has led to this document, in which new UUIDs are adapted to address\n   these issues.\n\n   Further, [RFC4122] itself was in need of an overhaul to address a\n   number of topics such as, but not limited to, the following:\n\n   1.  Implementation of miscellaneous errata reports.  Mostly around\n       bit-layout clarifications, which lead to inconsistent\n       implementations [Err1957], [Err3546], [Err4975], [Err4976],\n       [Err5560], etc.\n\n   2.  Decoupling other UUID versions from the UUIDv1 bit layout so that\n       fields like \"time_hi_and_version\" do not need to be referenced\n       within a UUID that is not time based while also providing\n       definition sections similar to that for UUIDv1 for UUIDv3,\n       UUIDv4, and UUIDv5.\n\n   3.  Providing implementation best practices around many real-world\n       scenarios and corner cases observed by existing and prototype\n       implementations.\n\n   4.  Addressing security best practices and considerations for the\n       modern age as it pertains to MAC addresses, hashing algorithms,\n       secure randomness, and other topics.\n\n   5.  Providing implementations a standard-based option for\n       implementation-specific and/or experimental UUID designs.\n\n   6.  Providing more test vectors that illustrate real UUIDs created as\n       per the specification.\n\n3.  Terminology\n\n3.1.  Requirements Language\n\n   The key words \"MUST\", \"MUST NOT\", \"REQUIRED\", \"SHALL\", \"SHALL NOT\",\n   \"SHOULD\", \"SHOULD NOT\", \"RECOMMENDED\", \"NOT RECOMMENDED\", \"MAY\", and\n   \"OPTIONAL\" in this document are to be interpreted as described in\n   BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all\n   capitals, as shown here.\n\n3.2.  Abbreviations\n\n   The following abbreviations are used in this document:\n\n   ABNF          Augmented Backus-Naur Form\n\n   CSPRNG        Cryptographically Secure Pseudorandom Number Generator\n\n   DBMS          Database Management System\n\n   IEEE          Institute of Electrical and Electronics Engineers\n\n   ITU           International Telecommunication Union\n\n   MAC           Media Access Control\n\n   MD5           Message Digest 5\n\n   MSB           Most Significant Bit\n\n   OID           Object Identifier\n\n   SHA           Secure Hash Algorithm\n\n   SHA-1         Secure Hash Algorithm 1 (with message digest of 160\n                 bits)\n\n   SHA-3         Secure Hash Algorithm 3 (arbitrary size)\n\n   SHA-224       Secure Hash Algorithm 2 with message digest size of 224\n                 bits\n\n   SHA-256       Secure Hash Algorithm 2 with message digest size of 256\n                 bits\n\n   SHA-512       Secure Hash Algorithm 2 with message digest size of 512\n                 bits\n\n   SHAKE         Secure Hash Algorithm 3 based on the KECCAK algorithm\n\n   URN           Uniform Resource Names\n\n   UTC           Coordinated Universal Time\n\n   UUID          Universally Unique Identifier\n\n   UUIDv1        Universally Unique Identifier version 1\n\n   UUIDv2        Universally Unique Identifier version 2\n\n   UUIDv3        Universally Unique Identifier version 3\n\n   UUIDv4        Universally Unique Identifier version 4\n\n   UUIDv5        Universally Unique Identifier version 5\n\n   UUIDv6        Universally Unique Identifier version 6\n\n   UUIDv7        Universally Unique Identifier version 7\n\n   UUIDv8        Universally Unique Identifier version 8\n\n4.  UUID Format\n\n   The UUID format is 16 octets (128 bits) in size; the variant bits in\n   conjunction with the version bits described in the next sections\n   determine finer structure.  In terms of these UUID formats and\n   layout, bit definitions start at 0 and end at 127, while octet\n   definitions start at 0 and end at 15.\n\n   In the absence of explicit application or presentation protocol\n   specification to the contrary, each field is encoded with the most\n   significant byte first (known as \"network byte order\").\n\n   Saving UUIDs to binary format is done by sequencing all fields in\n   big-endian format.  However, there is a known caveat that Microsoft's\n   Component Object Model (COM) GUIDs leverage little-endian when saving\n   GUIDs.  The discussion of this (see [MS_COM_GUID]) is outside the\n   scope of this specification.\n\n   UUIDs MAY be represented as binary data or integers.  When in use\n   with URNs or as text in applications, any given UUID should be\n   represented by the \"hex-and-dash\" string format consisting of\n   multiple groups of uppercase or lowercase alphanumeric hexadecimal\n   characters separated by single dashes/hyphens.  When used with\n   databases, please refer to Section 6.13.\n\n   The formal definition of the UUID string representation is provided\n   by the following ABNF [RFC5234]:\n\n   UUID     = 4hexOctet \"-\"\n              2hexOctet \"-\"\n              2hexOctet \"-\"\n              2hexOctet \"-\"\n              6hexOctet\n   hexOctet = HEXDIG HEXDIG\n   DIGIT    = %x30-39\n   HEXDIG   = DIGIT / \"A\" / \"B\" / \"C\" / \"D\" / \"E\" / \"F\"\n\n   Note that the alphabetic characters may be all uppercase, all\n   lowercase, or mixed case, as per Section 2.3 of [RFC5234].  An\n   example UUID using this textual representation from the above ABNF is\n   shown in Figure 1.\n\n   f81d4fae-7dec-11d0-a765-00a0c91e6bf6\n\n                    Figure 1: Example String UUID Format\n\n   The same UUID from Figure 1 is represented in binary (Figure 2), as\n   an unsigned integer (Figure 3), and as a URN (Figure 4) defined by\n   [RFC8141].\n\n   111110000001110101001111101011100111110111101100000100011101000\\\n   01010011101100101000000001010000011001001000111100110101111110110\n\n                       Figure 2: Example Binary UUID\n\n   329800735698586629295641978511506172918\n\n    Figure 3: Example Unsigned Integer UUID (Shown as a Decimal Number)\n\n   urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6\n\n                  Figure 4: Example URN Namespace for UUID\n\n   There are many other ways to define a UUID format; some examples are\n   detailed below.  Please note that this is not an exhaustive list and\n   is only provided for informational purposes.\n\n   *  Some UUID implementations, such as those found in [Python] and\n      [Microsoft], will output UUID with the string format, including\n      dashes, enclosed in curly braces.\n\n   *  [X667] provides UUID format definitions for use of UUID with an\n      OID.\n\n   *  [IBM_NCS] is a legacy implementation that produces a unique UUID\n      format compatible with Variant 0xx of Table 1.\n\n4.1.  Variant Field\n\n   The variant field determines the layout of the UUID.  That is, the\n   interpretation of all other bits in the UUID depends on the setting\n   of the bits in the variant field.  As such, it could more accurately\n   be called a \"type\" field; we retain the original term for\n   compatibility.  The variant field consists of a variable number of\n   the most significant bits of octet 8 of the UUID.\n\n   Table 1 lists the contents of the variant field, where the letter \"x\"\n   indicates a \"don't-care\" value.\n\n     +======+======+======+======+=========+=========================+\n     | MSB0 | MSB1 | MSB2 | MSB3 | Variant | Description             |\n     +======+======+======+======+=========+=========================+\n     | 0    | x    | x    | x    | 1-7     | Reserved.  Network      |\n     |      |      |      |      |         | Computing System (NCS)  |\n     |      |      |      |      |         | backward compatibility, |\n     |      |      |      |      |         | and includes Nil UUID   |\n     |      |      |      |      |         | as per Section 5.9.     |\n     +------+------+------+------+---------+-------------------------+\n     | 1    | 0    | x    | x    | 8-9,A-B | The variant specified   |\n     |      |      |      |      |         | in this document.       |\n     +------+------+------+------+---------+-------------------------+\n     | 1    | 1    | 0    | x    | C-D     | Reserved.  Microsoft    |\n     |      |      |      |      |         | Corporation backward    |\n     |      |      |      |      |         | compatibility.          |\n     +------+------+------+------+---------+-------------------------+\n     | 1    | 1    | 1    | x    | E-F     | Reserved for future     |\n     |      |      |      |      |         | definition and includes |\n     |      |      |      |      |         | Max UUID as per         |\n     |      |      |      |      |         | Section 5.10.           |\n     +------+------+------+------+---------+-------------------------+\n\n                           Table 1: UUID Variants\n\n   Interoperability, in any form, with variants other than the one\n   defined here is not guaranteed but is not likely to be an issue in\n   practice.\n\n   Specifically for UUIDs in this document, bits 64 and 65 of the UUID\n   (bits 0 and 1 of octet 8) MUST be set to 1 and 0 as specified in row\n   2 of Table 1.  Accordingly, all bit and field layouts avoid the use\n   of these bits.\n\n4.2.  Version Field\n\n   The version number is in the most significant 4 bits of octet 6 (bits\n   48 through 51 of the UUID).\n\n   Table 2 lists all of the versions for this UUID variant 10xx\n   specified in this document.\n\n   +======+======+======+======+=========+============================+\n   | MSB0 | MSB1 | MSB2 | MSB3 | Version | Description                |\n   +======+======+======+======+=========+============================+\n   | 0    | 0    | 0    | 0    | 0       | Unused.                    |\n   +------+------+------+------+---------+----------------------------+\n   | 0    | 0    | 0    | 1    | 1       | The Gregorian time-based   |\n   |      |      |      |      |         | UUID specified in this     |\n   |      |      |      |      |         | document.                  |\n   +------+------+------+------+---------+----------------------------+\n   | 0    | 0    | 1    | 0    | 2       | Reserved for DCE Security  |\n   |      |      |      |      |         | version, with embedded     |\n   |      |      |      |      |         | POSIX UUIDs.               |\n   +------+------+------+------+---------+----------------------------+\n   | 0    | 0    | 1    | 1    | 3       | The name-based version     |\n   |      |      |      |      |         | specified in this document |\n   |      |      |      |      |         | that uses MD5 hashing.     |\n   +------+------+------+------+---------+----------------------------+\n   | 0    | 1    | 0    | 0    | 4       | The randomly or            |\n   |      |      |      |      |         | pseudorandomly generated   |\n   |      |      |      |      |         | version specified in this  |\n   |      |      |      |      |         | document.                  |\n   +------+------+------+------+---------+----------------------------+\n   | 0    | 1    | 0    | 1    | 5       | The name-based version     |\n   |      |      |      |      |         | specified in this document |\n   |      |      |      |      |         | that uses SHA-1 hashing.   |\n   +------+------+------+------+---------+----------------------------+\n   | 0    | 1    | 1    | 0    | 6       | Reordered Gregorian time-  |\n   |      |      |      |      |         | based UUID specified in    |\n   |      |      |      |      |         | this document.             |\n   +------+------+------+------+---------+----------------------------+\n   | 0    | 1    | 1    | 1    | 7       | Unix Epoch time-based UUID |\n   |      |      |      |      |         | specified in this          |\n   |      |      |      |      |         | document.                  |\n   +------+------+------+------+---------+----------------------------+\n   | 1    | 0    | 0    | 0    | 8       | Reserved for custom UUID   |\n   |      |      |      |      |         | formats specified in this  |\n   |      |      |      |      |         | document.                  |\n   +------+------+------+------+---------+----------------------------+\n   | 1    | 0    | 0    | 1    | 9       | Reserved for future        |\n   |      |      |      |      |         | definition.                |\n   +------+------+------+------+---------+----------------------------+\n   | 1    | 0    | 1    | 0    | 10      | Reserved for future        |\n   |      |      |      |      |         | definition.                |\n   +------+------+------+------+---------+----------------------------+\n   | 1    | 0    | 1    | 1    | 11      | Reserved for future        |\n   |      |      |      |      |         | definition.                |\n   +------+------+------+------+---------+----------------------------+\n   | 1    | 1    | 0    | 0    | 12      | Reserved for future        |\n   |      |      |      |      |         | definition.                |\n   +------+------+------+------+---------+----------------------------+\n   | 1    | 1    | 0    | 1    | 13      | Reserved for future        |\n   |      |      |      |      |         | definition.                |\n   +------+------+------+------+---------+----------------------------+\n   | 1    | 1    | 1    | 0    | 14      | Reserved for future        |\n   |      |      |      |      |         | definition.                |\n   +------+------+------+------+---------+----------------------------+\n   | 1    | 1    | 1    | 1    | 15      | Reserved for future        |\n   |      |      |      |      |         | definition.                |\n   +------+------+------+------+---------+----------------------------+\n\n    Table 2: UUID Variant 10xx Versions Defined by This Specification\n\n   An example version/variant layout for UUIDv4 follows the table where\n   \"M\" represents the version placement for the hexadecimal\n   representation of 0x4 (0b0100) and the \"N\" represents the variant\n   placement for one of the four possible hexadecimal representation of\n   variant 10xx: 0x8 (0b1000), 0x9 (0b1001), 0xA (0b1010), 0xB (0b1011).\n\n   00000000-0000-4000-8000-000000000000\n   00000000-0000-4000-9000-000000000000\n   00000000-0000-4000-A000-000000000000\n   00000000-0000-4000-B000-000000000000\n   xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx\n\n                     Figure 5: UUIDv4 Variant Examples\n\n   It should be noted that the other remaining UUID variants found in\n   Table 1 leverage different sub-typing or versioning mechanisms.  The\n   recording and definition of the remaining UUID variant and sub-typing\n   combinations are outside of the scope of this document.\n\n5.  UUID Layouts\n\n   To minimize confusion about bit assignments within octets and among\n   differing versions, the UUID record definition is provided as a\n   grouping of fields within a bit layout consisting of four octets per\n   row.  The fields are presented with the most significant one first.\n\n5.1.  UUID Version 1\n\n   UUIDv1 is a time-based UUID featuring a 60-bit timestamp represented\n   by Coordinated Universal Time (UTC) as a count of 100-nanosecond\n   intervals since 00:00:00.00, 15 October 1582 (the date of Gregorian\n   reform to the Christian calendar).\n\n   UUIDv1 also features a clock sequence field that is used to help\n   avoid duplicates that could arise when the clock is set backwards in\n   time or if the Node ID changes.\n\n   The node field consists of an IEEE 802 MAC address, usually the host\n   address or a randomly derived value per Sections 6.9 and 6.10.\n\n    0                   1                   2                   3\n    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |                           time_low                            |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |           time_mid            |  ver  |       time_high       |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |var|         clock_seq         |             node              |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |                              node                             |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\n                   Figure 6: UUIDv1 Field and Bit Layout\n\n   time_low:\n      The least significant 32 bits of the 60-bit starting timestamp.\n      Occupies bits 0 through 31 (octets 0-3).\n\n   time_mid:\n      The middle 16 bits of the 60-bit starting timestamp.  Occupies\n      bits 32 through 47 (octets 4-5).\n\n   ver:\n      The 4-bit version field as defined by Section 4.2, set to 0b0001\n      (1).  Occupies bits 48 through 51 of octet 6.\n\n   time_high:\n      The least significant 12 bits from the 60-bit starting timestamp.\n      Occupies bits 52 through 63 (octets 6-7).\n\n   var:\n      The 2-bit variant field as defined by Section 4.1, set to 0b10.\n      Occupies bits 64 and 65 of octet 8.\n\n   clock_seq:\n      The 14 bits containing the clock sequence.  Occupies bits 66\n      through 79 (octets 8-9).\n\n   node:\n      48-bit spatially unique identifier.  Occupies bits 80 through 127\n      (octets 10-15).\n\n   For systems that do not have UTC available but do have the local\n   time, they may use that instead of UTC as long as they do so\n   consistently throughout the system.  However, this is not recommended\n   since generating the UTC from local time only needs a time-zone\n   offset.\n\n   If the clock is set backwards, or if it might have been set backwards\n   (e.g., while the system was powered off), and the UUID generator\n   cannot be sure that no UUIDs were generated with timestamps larger\n   than the value to which the clock was set, then the clock sequence\n   MUST be changed.  If the previous value of the clock sequence is\n   known, it MAY be incremented; otherwise it SHOULD be set to a random\n   or high-quality pseudorandom value.\n\n   Similarly, if the Node ID changes (e.g., because a network card has\n   been moved between machines), setting the clock sequence to a random\n   number minimizes the probability of a duplicate due to slight\n   differences in the clock settings of the machines.  If the value of\n   the clock sequence associated with the changed Node ID were known,\n   then the clock sequence MAY be incremented, but that is unlikely.\n\n   The clock sequence MUST be originally (i.e., once in the lifetime of\n   a system) initialized to a random number to minimize the correlation\n   across systems.  This provides maximum protection against Node IDs\n   that may move or switch from system to system rapidly.  The initial\n   value MUST NOT be correlated to the Node ID.\n\n   Notes about nodes derived from IEEE 802:\n\n   *  On systems with multiple IEEE 802 addresses, any available one MAY\n      be used.\n\n   *  On systems with no IEEE address, a randomly or pseudorandomly\n      generated value MUST be used; see Sections 6.9 and 6.10.\n\n   *  On systems utilizing a 64-bit MAC address, the least significant,\n      rightmost 48 bits MAY be used.\n\n   *  Systems utilizing an IEEE 802.15.4 16-bit address SHOULD instead\n      utilize their 64-bit MAC address where the least significant,\n      rightmost 48 bits MAY be used.  An alternative is to generate 32\n      bits of random data and postfix at the end of the 16-bit MAC\n      address to create a 48-bit value.\n\n5.2.  UUID Version 2\n\n   UUIDv2 is for DCE Security UUIDs (see [C309] and [C311]).  As such,\n   the definition of these UUIDs is outside the scope of this\n   specification.\n\n5.3.  UUID Version 3\n\n   UUIDv3 is meant for generating UUIDs from names that are drawn from,\n   and unique within, some namespace as per Section 6.5.\n\n   UUIDv3 values are created by computing an MD5 hash [RFC1321] over a\n   given Namespace ID value (Section 6.6) concatenated with the desired\n   name value after both have been converted to a canonical sequence of\n   octets, as defined by the standards or conventions of its namespace,\n   in network byte order.  This MD5 value is then used to populate all\n   128 bits of the UUID layout.  The UUID version and variant then\n   replace the respective bits as defined by Sections 4.2 and 4.1.  An\n   example of this bit substitution can be found in Appendix A.2.\n\n   Information around selecting a desired name's canonical format within\n   a given namespace can be found in Section 6.5 under the heading \"A\n   note on names\".\n\n   Where possible, UUIDv5 SHOULD be used in lieu of UUIDv3.  For more\n   information on MD5 security considerations, see [RFC6151].\n\n    0                   1                   2                   3\n    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |                            md5_high                           |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |          md5_high             |  ver  |       md5_mid         |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |var|                        md5_low                            |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |                            md5_low                            |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\n                   Figure 7: UUIDv3 Field and Bit Layout\n\n   md5_high:\n      The first 48 bits of the layout are filled with the most\n      significant, leftmost 48 bits from the computed MD5 value.\n      Occupies bits 0 through 47 (octets 0-5).\n\n   ver:\n      The 4-bit version field as defined by Section 4.2, set to 0b0011\n      (3).  Occupies bits 48 through 51 of octet 6.\n\n   md5_mid:\n      12 more bits of the layout consisting of the least significant,\n      rightmost 12 bits of 16 bits immediately following md5_high from\n      the computed MD5 value.  Occupies bits 52 through 63 (octets 6-7).\n\n   var:\n      The 2-bit variant field as defined by Section 4.1, set to 0b10.\n      Occupies bits 64 and 65 of octet 8.\n\n   md5_low:\n      The final 62 bits of the layout immediately following the var\n      field to be filled with the least significant, rightmost bits of\n      the final 64 bits from the computed MD5 value.  Occupies bits 66\n      through 127 (octets 8-15)\n\n5.4.  UUID Version 4\n\n   UUIDv4 is meant for generating UUIDs from truly random or\n   pseudorandom numbers.\n\n   An implementation may generate 128 bits of random data that is used\n   to fill out the UUID fields in Figure 8.  The UUID version and\n   variant then replace the respective bits as defined by Sections 4.1\n   and 4.2.\n\n   Alternatively, an implementation MAY choose to randomly generate the\n   exact required number of bits for random_a, random_b, and random_c\n   (122 bits total) and then concatenate the version and variant in the\n   required position.\n\n   For guidelines on random data generation, see Section 6.9.\n\n    0                   1                   2                   3\n    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |                           random_a                            |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |          random_a             |  ver  |       random_b        |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |var|                       random_c                            |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |                           random_c                            |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\n                   Figure 8: UUIDv4 Field and Bit Layout\n\n   random_a:\n      The first 48 bits of the layout that can be filled with random\n      data as specified in Section 6.9.  Occupies bits 0 through 47\n      (octets 0-5).\n\n   ver:\n      The 4-bit version field as defined by Section 4.2, set to 0b0100\n      (4).  Occupies bits 48 through 51 of octet 6.\n\n   random_b:\n      12 more bits of the layout that can be filled random data as per\n      Section 6.9.  Occupies bits 52 through 63 (octets 6-7).\n\n   var:\n      The 2-bit variant field as defined by Section 4.1, set to 0b10.\n      Occupies bits 64 and 65 of octet 8.\n\n   random_c:\n      The final 62 bits of the layout immediately following the var\n      field to be filled with random data as per Section 6.9.  Occupies\n      bits 66 through 127 (octets 8-15).\n\n5.5.  UUID Version 5\n\n   UUIDv5 is meant for generating UUIDs from \"names\" that are drawn\n   from, and unique within, some \"namespace\" as per Section 6.5.\n\n   UUIDv5 values are created by computing an SHA-1 hash [FIPS180-4] over\n   a given Namespace ID value (Section 6.6) concatenated with the\n   desired name value after both have been converted to a canonical\n   sequence of octets, as defined by the standards or conventions of its\n   namespace, in network byte order.  The most significant, leftmost 128\n   bits of the SHA-1 value are then used to populate all 128 bits of the\n   UUID layout, and the remaining 32 least significant, rightmost bits\n   of SHA-1 output are discarded.  The UUID version and variant then\n   replace the respective bits as defined by Sections 4.2 and 4.1.  An\n   example of this bit substitution and discarding excess bits can be\n   found in Appendix A.4.\n\n   Information around selecting a desired name's canonical format within\n   a given namespace can be found in Section 6.5 under the heading \"A\n   note on names\".\n\n   There may be scenarios, usually depending on organizational security\n   policies, where SHA-1 libraries may not be available or may be deemed\n   unsafe for use.  As such, it may be desirable to generate name-based\n   UUIDs derived from SHA-256 or newer SHA methods.  These name-based\n   UUIDs MUST NOT utilize UUIDv5 and MUST be within the UUIDv8 space\n   defined by Section 5.8.  An illustrative example of UUIDv8 for\n   SHA-256 name-based UUIDs is provided in Appendix B.2.\n\n   For more information on SHA-1 security considerations, see [RFC6194].\n\n    0                   1                   2                   3\n    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |                           sha1_high                           |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |         sha1_high             |  ver  |      sha1_mid         |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |var|                       sha1_low                            |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |                           sha1_low                            |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\n                   Figure 9: UUIDv5 Field and Bit Layout\n\n   sha1_high:\n      The first 48 bits of the layout are filled with the most\n      significant, leftmost 48 bits from the computed SHA-1 value.\n      Occupies bits 0 through 47 (octets 0-5).\n\n   ver:\n      The 4-bit version field as defined by Section 4.2, set to 0b0101\n      (5).  Occupies bits 48 through 51 of octet 6.\n\n   sha1_mid:\n      12 more bits of the layout consisting of the least significant,\n      rightmost 12 bits of 16 bits immediately following sha1_high from\n      the computed SHA-1 value.  Occupies bits 52 through 63 (octets\n      6-7).\n\n   var:\n      The 2-bit variant field as defined by Section 4.1, set to 0b10.\n      Occupies bits 64 and 65 of octet 8.\n\n   sha1_low:\n      The final 62 bits of the layout immediately following the var\n      field to be filled by skipping the two most significant, leftmost\n      bits of the remaining SHA-1 hash and then using the next 62 most\n      significant, leftmost bits.  Any leftover SHA-1 bits are discarded\n      and unused.  Occupies bits 66 through 127 (octets 8-15).\n\n5.6.  UUID Version 6\n\n   UUIDv6 is a field-compatible version of UUIDv1 (Section 5.1),\n   reordered for improved DB locality.  It is expected that UUIDv6 will\n   primarily be implemented in contexts where UUIDv1 is used.  Systems\n   that do not involve legacy UUIDv1 SHOULD use UUIDv7 (Section 5.7)\n   instead.\n\n   Instead of splitting the timestamp into the low, mid, and high\n   sections from UUIDv1, UUIDv6 changes this sequence so timestamp bytes\n   are stored from most to least significant.  That is, given a 60-bit\n   timestamp value as specified for UUIDv1 in Section 5.1, for UUIDv6\n   the first 48 most significant bits are stored first, followed by the\n   4-bit version (same position), followed by the remaining 12 bits of\n   the original 60-bit timestamp.\n\n   The clock sequence and node bits remain unchanged from their position\n   in Section 5.1.\n\n   The clock sequence and node bits SHOULD be reset to a pseudorandom\n   value for each new UUIDv6 generated; however, implementations MAY\n   choose to retain the old clock sequence and MAC address behavior from\n   Section 5.1.  For more information on MAC address usage within UUIDs,\n   see the Section 8.\n\n   The format for the 16-byte, 128-bit UUIDv6 is shown in Figure 10.\n\n    0                   1                   2                   3\n    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |                           time_high                           |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |           time_mid            |  ver  |       time_low        |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |var|         clock_seq         |             node              |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |                              node                             |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\n                   Figure 10: UUIDv6 Field and Bit Layout\n\n   time_high:\n      The most significant 32 bits of the 60-bit starting timestamp.\n      Occupies bits 0 through 31 (octets 0-3).\n\n   time_mid:\n      The middle 16 bits of the 60-bit starting timestamp.  Occupies\n      bits 32 through 47 (octets 4-5).\n\n   ver:\n      The 4-bit version field as defined by Section 4.2, set to 0b0110\n      (6).  Occupies bits 48 through 51 of octet 6.\n\n   time_low:\n      12 bits that will contain the least significant 12 bits from the\n      60-bit starting timestamp.  Occupies bits 52 through 63 (octets\n      6-7).\n\n   var:\n      The 2-bit variant field as defined by Section 4.1, set to 0b10.\n      Occupies bits 64 and 65 of octet 8.\n\n   clock_seq:\n      The 14 bits containing the clock sequence.  Occupies bits 66\n      through 79 (octets 8-9).\n\n   node:\n      48-bit spatially unique identifier.  Occupies bits 80 through 127\n      (octets 10-15).\n\n   With UUIDv6, the steps for splitting the timestamp into time_high and\n   time_mid are OPTIONAL since the 48 bits of time_high and time_mid\n   will remain in the same order.  An extra step of splitting the first\n   48 bits of the timestamp into the most significant 32 bits and least\n   significant 16 bits proves useful when reusing an existing UUIDv1\n   implementation.\n\n5.7.  UUID Version 7\n\n   UUIDv7 features a time-ordered value field derived from the widely\n   implemented and well-known Unix Epoch timestamp source, the number of\n   milliseconds since midnight 1 Jan 1970 UTC, leap seconds excluded.\n   Generally, UUIDv7 has improved entropy characteristics over UUIDv1\n   (Section 5.1) or UUIDv6 (Section 5.6).\n\n   UUIDv7 values are created by allocating a Unix timestamp in\n   milliseconds in the most significant 48 bits and filling the\n   remaining 74 bits, excluding the required version and variant bits,\n   with random bits for each new UUIDv7 generated to provide uniqueness\n   as per Section 6.9.  Alternatively, implementations MAY fill the 74\n   bits, jointly, with a combination of the following subfields, in this\n   order from the most significant bits to the least, to guarantee\n   additional monotonicity within a millisecond:\n\n   1.  An OPTIONAL sub-millisecond timestamp fraction (12 bits at\n       maximum) as per Section 6.2 (Method 3).\n\n   2.  An OPTIONAL carefully seeded counter as per Section 6.2 (Method 1\n       or 2).\n\n   3.  Random data for each new UUIDv7 generated for any remaining\n       space.\n\n   Implementations SHOULD utilize UUIDv7 instead of UUIDv1 and UUIDv6 if\n   possible.\n\n    0                   1                   2                   3\n    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |                           unix_ts_ms                          |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |          unix_ts_ms           |  ver  |       rand_a          |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |var|                        rand_b                             |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |                            rand_b                             |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\n                   Figure 11: UUIDv7 Field and Bit Layout\n\n   unix_ts_ms:\n      48-bit big-endian unsigned number of the Unix Epoch timestamp in\n      milliseconds as per Section 6.1.  Occupies bits 0 through 47\n      (octets 0-5).\n\n   ver:\n      The 4-bit version field as defined by Section 4.2, set to 0b0111\n      (7).  Occupies bits 48 through 51 of octet 6.\n\n   rand_a:\n      12 bits of pseudorandom data to provide uniqueness as per\n      Section 6.9 and/or optional constructs to guarantee additional\n      monotonicity as per Section 6.2.  Occupies bits 52 through 63\n      (octets 6-7).\n\n   var:\n      The 2-bit variant field as defined by Section 4.1, set to 0b10.\n      Occupies bits 64 and 65 of octet 8.\n\n   rand_b:\n      The final 62 bits of pseudorandom data to provide uniqueness as\n      per Section 6.9 and/or an optional counter to guarantee additional\n      monotonicity as per Section 6.2.  Occupies bits 66 through 127\n      (octets 8-15).\n\n5.8.  UUID Version 8\n\n   UUIDv8 provides a format for experimental or vendor-specific use\n   cases.  The only requirement is that the variant and version bits\n   MUST be set as defined in Sections 4.1 and 4.2.  UUIDv8's uniqueness\n   will be implementation specific and MUST NOT be assumed.\n\n   The only explicitly defined bits are those of the version and variant\n   fields, leaving 122 bits for implementation-specific UUIDs.  To be\n   clear, UUIDv8 is not a replacement for UUIDv4 (Section 5.4) where all\n   122 extra bits are filled with random data.\n\n   Some example situations in which UUIDv8 usage could occur:\n\n   *  An implementation would like to embed extra information within the\n      UUID other than what is defined in this document.\n\n   *  An implementation has other application and/or language\n      restrictions that inhibit the use of one of the current UUIDs.\n\n   Appendix B provides two illustrative examples of custom UUIDv8\n   algorithms to address two example scenarios.\n\n    0                   1                   2                   3\n    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |                           custom_a                            |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |          custom_a             |  ver  |       custom_b        |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |var|                       custom_c                            |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |                           custom_c                            |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\n                   Figure 12: UUIDv8 Field and Bit Layout\n\n   custom_a:\n      The first 48 bits of the layout that can be filled as an\n      implementation sees fit.  Occupies bits 0 through 47 (octets 0-5).\n\n   ver:\n      The 4-bit version field as defined by Section 4.2, set to 0b1000\n      (8).  Occupies bits 48 through 51 of octet 6.\n\n   custom_b:\n      12 more bits of the layout that can be filled as an implementation\n      sees fit.  Occupies bits 52 through 63 (octets 6-7).\n\n   var:\n      The 2-bit variant field as defined by Section 4.1, set to 0b10.\n      Occupies bits 64 and 65 of octet 8.\n\n   custom_c:\n      The final 62 bits of the layout immediately following the var\n      field to be filled as an implementation sees fit.  Occupies bits\n      66 through 127 (octets 8-15).\n\n5.9.  Nil UUID\n\n   The Nil UUID is special form of UUID that is specified to have all\n   128 bits set to zero.\n\n   00000000-0000-0000-0000-000000000000\n\n                         Figure 13: Nil UUID Format\n\n   A Nil UUID value can be useful to communicate the absence of any\n   other UUID value in situations that otherwise require or use a\n   128-bit UUID.  A Nil UUID can express the concept \"no such value\n   here\".  Thus, it is reserved for such use as needed for\n   implementation-specific situations.\n\n   Note that the Nil UUID value falls within the range of the Apollo NCS\n   variant as per the first row of Table 1 rather than the variant\n   defined by this document.\n\n5.10.  Max UUID\n\n   The Max UUID is a special form of UUID that is specified to have all\n   128 bits set to 1.  This UUID can be thought of as the inverse of the\n   Nil UUID defined in Section 5.9.\n\n   FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF\n\n                         Figure 14: Max UUID Format\n\n   A Max UUID value can be used as a sentinel value in situations where\n   a 128-bit UUID is required, but a concept such as \"end of UUID list\"\n   needs to be expressed and is reserved for such use as needed for\n   implementation-specific situations.\n\n   Note that the Max UUID value falls within the range of the \"yet-to-be\n   defined\" future UUID variant as per the last row of Table 1 rather\n   than the variant defined by this document.\n\n6.  UUID Best Practices\n\n   The minimum requirements for generating UUIDs of each version are\n   described in this document.  Everything else is an implementation\n   detail, and it is up to the implementer to decide what is appropriate\n   for a given implementation.  Various relevant factors are covered\n   below to help guide an implementer through the different trade-offs\n   among differing UUID implementations.\n\n6.1.  Timestamp Considerations\n\n   UUID timestamp source, precision, and length were topics of great\n   debate while creating UUIDv7 for this specification.  Choosing the\n   right timestamp for your application is very important.  This section\n   will detail some of the most common points on this issue.\n\n   Reliability:\n      Implementations acquire the current timestamp from a reliable\n      source to provide values that are time ordered and continually\n      increasing.  Care must be taken to ensure that timestamp changes\n      from the environment or operating system are handled in a way that\n      is consistent with implementation requirements.  For example, if\n      it is possible for the system clock to move backward due to either\n      manual adjustment or corrections from a time synchronization\n      protocol, implementations need to determine how to handle such\n      cases.  (See \"Altering, Fuzzing, or Smearing\" below.)\n\n   Source:\n      UUIDv1 and UUIDv6 both utilize a Gregorian Epoch timestamp, while\n      UUIDv7 utilizes a Unix Epoch timestamp.  If other timestamp\n      sources or a custom timestamp Epoch are required, UUIDv8 MUST be\n      used.\n\n   Sub-second Precision and Accuracy:\n      Many levels of precision exist for timestamps: milliseconds,\n      microseconds, nanoseconds, and beyond.  Additionally, fractional\n      representations of sub-second precision may be desired to mix\n      various levels of precision in a time-ordered manner.\n      Furthermore, system clocks themselves have an underlying\n      granularity, which is frequently less than the precision offered\n      by the operating system.  With UUIDv1 and UUIDv6, 100 nanoseconds\n      of precision are present, while UUIDv7 features a millisecond\n      level of precision by default within the Unix Epoch that does not\n      exceed the granularity capable in most modern systems.  For other\n      levels of precision, UUIDv8 is available.  Similar to Section 6.2,\n      with UUIDv1 or UUIDv6, a high-resolution timestamp can be\n      simulated by keeping a count of the number of UUIDs that have been\n      generated with the same value of the system time and using that\n      count to construct the low order bits of the timestamp.  The count\n      of the high-resolution timestamp will range between zero and the\n      number of 100-nanosecond intervals per system-time interval.\n\n   Length:\n      The length of a given timestamp directly impacts how many\n      timestamp ticks can be contained in a UUID before the maximum\n      value for the timestamp field is reached.  Take care to ensure\n      that the proper length is selected for a given timestamp.  UUIDv1\n      and UUIDv6 utilize a 60-bit timestamp valid until 5623 AD; UUIDv7\n      features a 48-bit timestamp valid until the year 10889 AD.\n\n   Altering, Fuzzing, or Smearing:\n      Implementations MAY alter the actual timestamp.  Some examples\n      include security considerations around providing a real-clock\n      value within a UUID to 1) correct inaccurate clocks, 2) handle\n      leap seconds, or 3) obtain a millisecond value by dividing by 1024\n      (or some other value) for performance reasons (instead of dividing\n      a number of microseconds by 1000).  This specification makes no\n      requirement or guarantee about how close the clock value needs to\n      be to the actual time.  If UUIDs do not need to be frequently\n      generated, the UUIDv1 or UUIDv6 timestamp can simply be the system\n      time multiplied by the number of 100-nanosecond intervals per\n      system-time interval.\n\n   Padding:\n      When timestamp padding is required, implementations MUST pad the\n      most significant bits (leftmost) with data.  An example for this\n      padding data is to fill the most significant, leftmost bits of a\n      Unix timestamp with zeroes to complete the 48-bit timestamp in\n      UUIDv7.  An alternative approach for padding data is to fill the\n      most significant, leftmost bits with the number of 32-bit Unix\n      timestamp rollovers after 2038-01-19.\n\n   Truncating:\n      When timestamps need to be truncated, the lower, least significant\n      bits MUST be used.  An example would be truncating a 64-bit Unix\n      timestamp to the least significant, rightmost 48 bits for UUIDv7.\n\n   Error Handling:\n      If a system overruns the generator by requesting too many UUIDs\n      within a single system-time interval, the UUID service can return\n      an error or stall the UUID generator until the system clock\n      catches up and MUST NOT knowingly return duplicate values due to a\n      counter rollover.  Note that if the processors overrun the UUID\n      generation frequently, additional Node IDs can be allocated to the\n      system, which will permit higher speed allocation by making\n      multiple UUIDs potentially available for each timestamp value.\n      Similar techniques are discussed in Section 6.4.\n\n6.2.  Monotonicity and Counters\n\n   Monotonicity (each subsequent value being greater than the last) is\n   the backbone of time-based sortable UUIDs.  Normally, time-based\n   UUIDs from this document will be monotonic due to an embedded\n   timestamp; however, implementations can guarantee additional\n   monotonicity via the concepts covered in this section.\n\n   Take care to ensure UUIDs generated in batches are also monotonic.\n   That is, if one thousand UUIDs are generated for the same timestamp,\n   there should be sufficient logic for organizing the creation order of\n   those one thousand UUIDs.  Batch UUID creation implementations MAY\n   utilize a monotonic counter that increments for each UUID created\n   during a given timestamp.\n\n   For single-node UUID implementations that do not need to create\n   batches of UUIDs, the embedded timestamp within UUIDv6 and UUIDv7 can\n   provide sufficient monotonicity guarantees by simply ensuring that\n   timestamp increments before creating a new UUID.  Distributed nodes\n   are discussed in Section 6.4.\n\n   Implementations SHOULD employ the following methods for single-node\n   UUID implementations that require batch UUID creation or are\n   otherwise concerned about monotonicity with high-frequency UUID\n   generation.\n\n   Fixed Bit-Length Dedicated Counter (Method 1):\n      Some implementations allocate a specific number of bits in the\n      UUID layout to the sole purpose of tallying the total number of\n      UUIDs created during a given UUID timestamp tick.  If present, a\n      fixed bit-length counter MUST be positioned immediately after the\n      embedded timestamp.  This promotes sortability and allows random\n      data generation for each counter increment.  With this method, the\n      rand_a section (or a subset of its leftmost bits) of UUIDv7 is\n      used as a fixed bit-length dedicated counter that is incremented\n      for every UUID generation.  The trailing random bits generated for\n      each new UUID in rand_b can help produce unguessable UUIDs.  In\n      the event that more counter bits are required, the most\n      significant (leftmost) bits of rand_b MAY be used as additional\n      counter bits.\n\n   Monotonic Random (Method 2):\n      With this method, the random data is extended to also function as\n      a counter.  This monotonic value can be thought of as a \"randomly\n      seeded counter\" that MUST be incremented in the least significant\n      position for each UUID created on a given timestamp tick.\n      UUIDv7's rand_b section SHOULD be utilized with this method to\n      handle batch UUID generation during a single timestamp tick.  The\n      increment value for every UUID generation is a random integer of\n      any desired length larger than zero.  It ensures that the UUIDs\n      retain the required level of unguessability provided by the\n      underlying entropy.  The increment value MAY be 1 when the number\n      of UUIDs generated in a particular period of time is important and\n      guessability is not an issue.  However, incrementing the counter\n      by 1 SHOULD NOT be used by implementations that favor\n      unguessability, as the resulting values are easily guessable.\n\n   Replace Leftmost Random Bits with Increased Clock Precision\n   (Method 3):\n      For UUIDv7, which has millisecond timestamp precision, it is\n      possible to use additional clock precision available on the system\n      to substitute for up to 12 random bits immediately following the\n      timestamp.  This can provide values that are time ordered with\n      sub-millisecond precision, using however many bits are appropriate\n      in the implementation environment.  With this method, the\n      additional time precision bits MUST follow the timestamp as the\n      next available bit in the rand_a field for UUIDv7.\n\n      To calculate this value, start with the portion of the timestamp\n      expressed as a fraction of the clock's tick value (fraction of a\n      millisecond for UUIDv7).  Compute the count of possible values\n      that can be represented in the available bit space, 4096 for the\n      UUIDv7 rand_a field.  Using floating point or scaled integer\n      arithmetic, multiply this fraction of a millisecond value by 4096\n      and round down (toward zero) to an integer result to arrive at a\n      number between 0 and the maximum allowed for the indicated bits,\n      which sorts monotonically based on time.  Each increasing\n      fractional value will result in an increasing bit field value to\n      the precision available with these bits.\n\n      For example, let's assume a system timestamp of 1 Jan 2023\n      12:34:56.1234567.  Taking the precision greater than 1 ms gives us\n      a value of 0.4567, as a fraction of a millisecond.  If we wish to\n      encode this as 12 bits, we can take the count of possible values\n      that fit in those bits (4096 or 2^12), multiply it by our\n      millisecond fraction value of 0.4567, and truncate the result to\n      an integer, which gives an integer value of 1870.  Expressed as\n      hexadecimal, it is 0x74E or the binary bits 0b011101001110.  One\n      can then use those 12 bits as the most significant (leftmost)\n      portion of the random section of the UUID (e.g., the rand_a field\n      in UUIDv7).  This works for any desired bit length that fits into\n      a UUID, and applications can decide the appropriate length based\n      on available clock precision; for UUIDv7, it is limited to 12 bits\n      at maximum to reserve sufficient space for random bits.\n\n      The main benefit to encoding additional timestamp precision is\n      that it utilizes additional time precision already available in\n      the system clock to provide values that are more likely to be\n      unique; thus, it may simplify certain implementations.  This\n      technique can also be used in conjunction with one of the other\n      methods, where this additional time precision would immediately\n      follow the timestamp.  Then, if any bits are to be used as a clock\n      sequence, they would follow next.\n\n   The following sub-topics cover issues related solely to creating\n   reliable fixed bit-length dedicated counters:\n\n   Fixed Bit-Length Dedicated Counter Seeding:\n      Implementations utilizing the fixed bit-length counter method\n      randomly initialize the counter with each new timestamp tick.\n      However, when the timestamp has not increased, the counter is\n      instead incremented by the desired increment logic.  When\n      utilizing a randomly seeded counter alongside Method 1, the random\n      value MAY be regenerated with each counter increment without\n      impacting sortability.  The downside is that Method 1 is prone to\n      overflows if a counter of adequate length is not selected or the\n      random data generated leaves little room for the required number\n      of increments.  Implementations utilizing fixed bit-length counter\n      method MAY also choose to randomly initialize a portion of the\n      counter rather than the entire counter.  For example, a 24-bit\n      counter could have the 23 bits in least significant, rightmost\n      position randomly initialized.  The remaining most significant,\n      leftmost counter bit is initialized as zero for the sole purpose\n      of guarding against counter rollovers.\n\n   Fixed Bit-Length Dedicated Counter Length:\n      Select a counter bit-length that can properly handle the level of\n      timestamp precision in use.  For example, millisecond precision\n      generally requires a larger counter than a timestamp with\n      nanosecond precision.  General guidance is that the counter SHOULD\n      be at least 12 bits but no longer than 42 bits.  Care must be\n      taken to ensure that the counter length selected leaves room for\n      sufficient entropy in the random portion of the UUID after the\n      counter.  This entropy helps improve the unguessability\n      characteristics of UUIDs created within the batch.\n\n   The following sub-topics cover rollover handling with either type of\n   counter method:\n\n   Counter Rollover Guards:\n      The technique from \"Fixed Bit-Length Dedicated Counter Seeding\"\n      above that describes allocating a segment of the fixed bit-length\n      counter as a rollover guard is also helpful to mitigate counter\n      rollover issues.  This same technique can be used with monotonic\n      random counter methods by ensuring that the total length of a\n      possible increment in the least significant, rightmost position is\n      less than the total length of the random value being incremented.\n      As such, the most significant, leftmost bits can be incremented as\n      rollover guarding.\n\n   Counter Rollover Handling:\n      Counter rollovers MUST be handled by the application to avoid\n      sorting issues.  The general guidance is that applications that\n      care about absolute monotonicity and sortability should freeze the\n      counter and wait for the timestamp to advance, which ensures\n      monotonicity is not broken.  Alternatively, implementations MAY\n      increment the timestamp ahead of the actual time and reinitialize\n      the counter.\n\n   Implementations MAY use the following logic to ensure UUIDs featuring\n   embedded counters are monotonic in nature:\n\n   1.  Compare the current timestamp against the previously stored\n       timestamp.\n\n   2.  If the current timestamp is equal to the previous timestamp,\n       increment the counter according to the desired method.\n\n   3.  If the current timestamp is greater than the previous timestamp,\n       re-initialize the desired counter method to the new timestamp and\n       generate new random bytes (if the bytes were frozen or being used\n       as the seed for a monotonic counter).\n\n   Monotonic Error Checking:\n      Implementations SHOULD check if the currently generated UUID is\n      greater than the previously generated UUID.  If this is not the\n      case, then any number of things could have occurred, such as clock\n      rollbacks, leap second handling, and counter rollovers.\n      Applications SHOULD embed sufficient logic to catch these\n      scenarios and correct the problem to ensure that the next UUID\n      generated is greater than the previous, or they should at least\n      report an appropriate error.  To handle this scenario, the general\n      guidance is that the application MAY reuse the previous timestamp\n      and increment the previous counter method.\n\n6.3.  UUID Generator States\n\n   The (optional) UUID generator state only needs to be read from stable\n   storage once at boot time, if it is read into a system-wide shared\n   volatile store (and updated whenever the stable store is updated).\n\n   This stable storage MAY be used to record various portions of the\n   UUID generation, which prove useful for batch UUID generation\n   purposes and monotonic error checking with UUIDv6 and UUIDv7.  These\n   stored values include but are not limited to last known timestamp,\n   clock sequence, counters, and random data.\n\n   If an implementation does not have any stable store available, then\n   it MAY proceed with UUID generation as if this were the first UUID\n   created within a batch.  This is the least desirable implementation\n   because it will increase the frequency of creation of values such as\n   clock sequence, counters, or random data, which increases the\n   probability of duplicates.  Further, frequent generation of random\n   numbers also puts more stress on any entropy source and/or entropy\n   pool being used as the basis for such random numbers.\n\n   An implementation MAY also return an application error in the event\n   that collision resistance is of the utmost concern.  The semantics of\n   this error are up to the application and implementation.  See\n   Section 6.7 for more information on weighting collision tolerance in\n   applications.\n\n   For UUIDv1 and UUIDv6, if the Node ID can never change (e.g., the\n   network interface card from which the Node ID is derived is\n   inseparable from the system), or if any change also re-initializes\n   the clock sequence to a random value, then instead of keeping it in\n   stable store, the current Node ID may be returned.\n\n   For UUIDv1 and UUIDv6, the state does not always need to be written\n   to stable store every time a UUID is generated.  The timestamp in the\n   stable store can periodically be set to a value larger than any yet\n   used in a UUID.  As long as the generated UUIDs have timestamps less\n   than that value, and the clock sequence and Node ID remain unchanged,\n   only the shared volatile copy of the state needs to be updated.\n   Furthermore, if the timestamp value in stable store is in the future\n   by less than the typical time it takes the system to reboot, a crash\n   will not cause a re-initialization of the clock sequence.\n\n   If it is too expensive to access shared state each time a UUID is\n   generated, then the system-wide generator can be implemented to\n   allocate a block of timestamps each time it is called; a per-process\n   generator can allocate from that block until it is exhausted.\n\n6.4.  Distributed UUID Generation\n\n   Some implementations MAY desire the utilization of multi-node,\n   clustered, applications that involve two or more nodes independently\n   generating UUIDs that will be stored in a common location.  While\n   UUIDs already feature sufficient entropy to ensure that the chances\n   of collision are low, as the total number of UUID generating nodes\n   increases, so does the likelihood of a collision.\n\n   This section will detail the two additional collision resistance\n   approaches that have been observed by multi-node UUID implementations\n   in distributed environments.\n\n   It should be noted that, although this section details two methods\n   for the sake of completeness, implementations should utilize the\n   pseudorandom Node ID option if additional collision resistance for\n   distributed UUID generation is a requirement.  Likewise, utilization\n   of either method is not required for implementing UUID generation in\n   distributed environments.\n\n   Node IDs:\n      With this method, a pseudorandom Node ID value is placed within\n      the UUID layout.  This identifier helps ensure the bit space for a\n      given node is unique, resulting in UUIDs that do not conflict with\n      any other UUID created by another node with a different node id.\n      Implementations that choose to leverage an embedded node id SHOULD\n      utilize UUIDv8.  The node id SHOULD NOT be an IEEE 802 MAC address\n      per Section 8.  The location and bit length are left to\n      implementations and are outside the scope of this specification.\n      Furthermore, the creation and negotiation of unique node ids among\n      nodes is also out of scope for this specification.\n\n   Centralized Registry:\n      With this method, all nodes tasked with creating UUIDs consult a\n      central registry and confirm the generated value is unique.  As\n      applications scale, the communication with the central registry\n      could become a bottleneck and impact UUID generation in a negative\n      way.  Shared knowledge schemes with central/global registries are\n      outside the scope of this specification and are NOT RECOMMENDED.\n\n   Distributed applications generating UUIDs at a variety of hosts MUST\n   be willing to rely on the random number source at all hosts.\n\n6.5.  Name-Based UUID Generation\n\n   Although some prefer to use the word \"hash-based\" to describe UUIDs\n   featuring hashing algorithms (MD5 or SHA-1), this document retains\n   the usage of the term \"name-based\" in order to maintain consistency\n   with previously published documents and existing implementations.\n\n   The requirements for name-based UUIDs are as follows:\n\n   *  UUIDs generated at different times from the same name (using the\n      same canonical format) in the same namespace MUST be equal.\n\n   *  UUIDs generated from two different names (same or differing\n      canonical format) in the same namespace should be different (with\n      very high probability).\n\n   *  UUIDs generated from the same name (same or differing canonical\n      format) in two different namespaces should be different (with very\n      high probability).\n\n   *  If two UUIDs that were generated from names (using the same\n      canonical format) are equal, then they were generated from the\n      same name in the same namespace (with very high probability).\n\n   A note on names:\n\n      The concept of name (and namespace) should be broadly construed\n      and not limited to textual names.  A canonical sequence of octets\n      is one that conforms to the specification for that name form's\n      canonical representation.  A name can have many usual forms, only\n      one of which can be canonical.  An implementer of new namespaces\n      for UUIDs needs to reference the specification for the canonical\n      form of names in that space or define such a canonical form for\n      the namespace if it does not exist.  For example, at the time of\n      writing, Domain Name System (DNS) [RFC9499] has three conveyance\n      formats: common (www.example.com), presentation\n      (www.example.com.), and wire format (3www7example3com0).  Looking\n      at [X500] Distinguished Names (DNs), [RFC4122] allowed either\n      text-based or binary DER-based names as inputs.  For Uniform\n      Resource Locators (URLs) [RFC1738], one could provide a Fully\n      Qualified Domain Name (FQDN) with or without the protocol\n      identifier www.example.com or https://www.example.com.  When it\n      comes to Object Identifiers (OIDs) [X660], one could choose dot\n      notation without the leading dot (2.999), choose to include the\n      leading dot (.2.999), or select one of the many formats from\n      [X680] such as OID Internationalized Resource Identifier (OID-IRI)\n      (/Joint-ISO-ITU-T/Example).  While most users may default to the\n      common format for DNS, FQDN format for a URL, text format for\n      X.500, and dot notation without a leading dot for OID, name-based\n      UUID implementations generally SHOULD allow arbitrary input that\n      will compute name-based UUIDs for any of the aforementioned\n      example names and others not defined here.  Each name format\n      within a namespace will output different UUIDs.  As such, the\n      mechanisms or conventions used for allocating names and ensuring\n      their uniqueness within their namespaces are beyond the scope of\n      this specification.\n\n6.6.  Namespace ID Usage and Allocation\n\n   This section details the namespace IDs for some potentially\n   interesting namespaces such as those for DNS [RFC9499], URLs\n   [RFC1738], OIDs [X660], and DNs [X500].\n\n   Further, this section also details allocation, IANA registration, and\n   other details pertinent to Namespace IDs.\n\n   +=========+====================================+=========+==========+\n   |Namespace|Namespace ID Value                  |Name     |Namespace |\n   |         |                                    |Reference|ID        |\n   |         |                                    |         |Reference |\n   +=========+====================================+=========+==========+\n   |DNS      |6ba7b810-9dad-11d1-80b4-00c04fd430c8|[RFC9499]|[RFC4122],|\n   |         |                                    |         |RFC 9562  |\n   +---------+------------------------------------+---------+----------+\n   |URL      |6ba7b811-9dad-11d1-80b4-00c04fd430c8|[RFC1738]|[RFC4122],|\n   |         |                                    |         |RFC 9562  |\n   +---------+------------------------------------+---------+----------+\n   |OID      |6ba7b812-9dad-11d1-80b4-00c04fd430c8|[X660]   |[RFC4122],|\n   |         |                                    |         |RFC 9562  |\n   +---------+------------------------------------+---------+----------+\n   |X500     |6ba7b814-9dad-11d1-80b4-00c04fd430c8|[X500]   |[RFC4122],|\n   |         |                                    |         |RFC 9562  |\n   +---------+------------------------------------+---------+----------+\n\n                           Table 3: Namespace IDs\n\n   Items may be added to this registry using the Specification Required\n   policy as per [RFC8126].\n\n   For designated experts, generally speaking, Namespace IDs are\n   allocated as follows:\n\n   *  The first Namespace ID value, for DNS, was calculated from a time-\n      based UUIDv1 and \"6ba7b810-9dad-11d1-80b4-00c04fd430c8\", used as a\n      starting point.\n\n   *  Subsequent Namespace ID values increment the least significant,\n      rightmost bit of time_low \"6ba7b810\" while freezing the rest of\n      the UUID to \"9dad-11d1-80b4-00c04fd430c8\".\n\n   *  New Namespace ID values MUST use this same logic and MUST NOT use\n      a previously used Namespace ID value.\n\n   *  Thus, \"6ba7b815\" is the next available time_low for a new\n      Namespace ID value with the full ID being \"6ba7b815-9dad-\n      11d1-80b4-00c04fd430c8\".\n\n   *  The upper bound for time_low in this special use, Namespace ID\n      values, is \"ffffffff\" or \"ffffffff-9dad-11d1-80b4-00c04fd430c8\",\n      which should be sufficient space for future Namespace ID values.\n\n   Note that the Namespace ID value \"6ba7b813-9dad-\n   11d1-80b4-00c04fd430c8\" and its usage are not defined by this\n   document or by [RFC4122]; thus, it SHOULD NOT be used as a Namespace\n   ID value.\n\n   New Namespace ID values MUST be documented as per Section 7 if they\n   are to be globally available and fully interoperable.\n   Implementations MAY continue to use vendor-specific, application-\n   specific, and deployment-specific Namespace ID values; but know that\n   interoperability is not guaranteed.  These custom Namespace ID values\n   MUST NOT use the logic above; instead, generating a UUIDv4 or UUIDv7\n   Namespace ID value is RECOMMENDED.  If collision probability\n   (Section 6.7) and uniqueness (Section 6.8) of the final name-based\n   UUID are not a problem, an implementation MAY also leverage UUIDv8\n   instead to create a custom, application-specific Namespace ID value.\n\n   Implementations SHOULD provide the ability to input a custom\n   namespace to account for newly registered IANA Namespace ID values\n   outside of those listed in this section or custom, application-\n   specific Namespace ID values.\n\n6.7.  Collision Resistance\n\n   Implementations should weigh the consequences of UUID collisions\n   within their application and when deciding between UUID versions that\n   use entropy (randomness) versus the other components such as those in\n   Sections 6.1 and 6.2.  This is especially true for distributed node\n   collision resistance as defined by Section 6.4.\n\n   There are two example scenarios below that help illustrate the\n   varying seriousness of a collision within an application.\n\n   Low Impact:\n      A UUID collision generated a duplicate log entry, which results in\n      incorrect statistics derived from the data.  Implementations that\n      are not negatively affected by collisions may continue with the\n      entropy and uniqueness provided by UUIDs defined in this document.\n\n   High Impact:\n      A duplicate key causes an airplane to receive the wrong course,\n      which puts people's lives at risk.  In this scenario, there is no\n      margin for error.  Collisions must be avoided: failure is\n      unacceptable.  Applications dealing with this type of scenario\n      must employ as much collision resistance as possible within the\n      given application context.\n\n6.8.  Global and Local Uniqueness\n\n   UUIDs created by this specification MAY be used to provide local\n   uniqueness guarantees.  For example, ensuring UUIDs created within a\n   local application context are unique within a database MAY be\n   sufficient for some implementations where global uniqueness outside\n   of the application context, in other applications, or around the\n   world is not required.\n\n   Although true global uniqueness is impossible to guarantee without a\n   shared knowledge scheme, a shared knowledge scheme is not required by\n   a UUID to provide uniqueness for practical implementation purposes.\n   Implementations MAY use a shared knowledge scheme, introduced in\n   Section 6.4, as they see fit to extend the uniqueness guaranteed by\n   this specification.\n\n6.9.  Unguessability\n\n   Implementations SHOULD utilize a cryptographically secure\n   pseudorandom number generator (CSPRNG) to provide values that are\n   both difficult to predict (\"unguessable\") and have a low likelihood\n   of collision (\"unique\").  The exception is when a suitable CSPRNG is\n   unavailable in the execution environment.  Take care to ensure the\n   CSPRNG state is properly reseeded upon state changes, such as process\n   forks, to ensure proper CSPRNG operation.  CSPRNG ensures the best of\n   Sections 6.7 and 8 are present in modern UUIDs.\n\n   Further advice on generating cryptographic-quality random numbers can\n   be found in [RFC4086], [RFC8937], and [RANDOM].\n\n6.10.  UUIDs That Do Not Identify the Host\n\n   This section describes how to generate a UUIDv1 or UUIDv6 value if an\n   IEEE 802 address is not available or its use is not desired.\n\n   Implementations MAY leverage MAC address randomization techniques\n   [IEEE802.11bh] as an alternative to the pseudorandom logic provided\n   in this section.\n\n   Alternatively, implementations MAY elect to obtain a 48-bit\n   cryptographic-quality random number as per Section 6.9 to use as the\n   Node ID.  After generating the 48-bit fully randomized node value,\n   implementations MUST set the least significant bit of the first octet\n   of the Node ID to 1.  This bit is the unicast or multicast bit, which\n   will never be set in IEEE 802 addresses obtained from network cards.\n   Hence, there can never be a conflict between UUIDs generated by\n   machines with and without network cards.  An example of generating a\n   randomized 48-bit node value and the subsequent bit modification is\n   detailed in Appendix A.  For more information about IEEE 802 address\n   and the unicast or multicast or local/global bits, please review\n   [RFC9542].\n\n   For compatibility with earlier specifications, note that this\n   document uses the unicast or multicast bit instead of the arguably\n   more correct local/global bit because MAC addresses with the local/\n   global bit set or not set are both possible in a network.  This is\n   not the case with the unicast or multicast bit.  One node cannot have\n   a MAC address that multicasts to multiple nodes.\n\n   In addition, items such as the computer's name and the name of the\n   operating system, while not strictly speaking random, will help\n   differentiate the results from those obtained by other systems.\n\n   The exact algorithm to generate a Node ID using these data is system\n   specific because both the data available and the functions to obtain\n   them are often very system specific.  However, a generic approach is\n   to accumulate as many sources as possible into a buffer, use a\n   message digest (such as SHA-256 or SHA-512 defined by [FIPS180-4]),\n   take an arbitrary 6 bytes from the hash value, and set the multicast\n   bit as described above.\n\n6.11.  Sorting\n\n   UUIDv6 and UUIDv7 are designed so that implementations that require\n   sorting (e.g., database indexes) sort as opaque raw bytes without the\n   need for parsing or introspection.\n\n   Time-ordered monotonic UUIDs benefit from greater database-index\n   locality because the new values are near each other in the index.  As\n   a result, objects are more easily clustered together for better\n   performance.  The real-world differences in this approach of index\n   locality versus random data inserts can be one order of magnitude or\n   more.\n\n   UUID formats created by this specification are intended to be\n   lexicographically sortable while in the textual representation.\n\n   UUIDs created by this specification are crafted with big-endian byte\n   order (network byte order) in mind.  If little-endian style is\n   required, UUIDv8 is available for custom UUID formats.\n\n6.12.  Opacity\n\n   As general guidance, avoiding parsing UUID values unnecessarily is\n   recommended; instead, treat UUIDs as opaquely as possible.  Although\n   application-specific concerns could, of course, require some degree\n   of introspection (e.g., to examine Sections 4.1 or 4.2 or perhaps the\n   timestamp of a UUID), the advice here is to avoid this or other\n   parsing unless absolutely necessary.  Applications typically tend to\n   be simpler, be more interoperable, and perform better when this\n   advice is followed.\n\n6.13.  DBMS and Database Considerations\n\n   For many applications, such as databases, storing UUIDs as text is\n   unnecessarily verbose, requiring 288 bits to represent 128-bit UUID\n   values.  Thus, where feasible, UUIDs SHOULD be stored within database\n   applications as the underlying 128-bit binary value.\n\n   For other systems, UUIDs MAY be stored in binary form or as text, as\n   appropriate.  The trade-offs to both approaches are as follows:\n\n   *  Storing in binary form requires less space and may result in\n      faster data access.\n\n   *  Storing as text requires more space but may require less\n      translation if the resulting text form is to be used after\n      retrieval, which may make it simpler to implement.\n\n   DBMS vendors are encouraged to provide functionality to generate and\n   store UUID formats defined by this specification for use as\n   identifiers or left parts of identifiers such as, but not limited to,\n   primary keys, surrogate keys for temporal databases, foreign keys\n   included in polymorphic relationships, and keys for key-value pairs\n   in JSON columns and key-value databases.  Applications using a\n   monolithic database may find using database-generated UUIDs (as\n   opposed to client-generated UUIDs) provides the best UUID\n   monotonicity.  In addition to UUIDs, additional identifiers MAY be\n   used to ensure integrity and feedback.\n\n   Designers of database schema are cautioned against using name-based\n   UUIDs (see Sections 5.3 and 5.5) as primary keys in tables.  A common\n   issue observed in database schema design is the assumption that a\n   particular value will never change, which later turns out to be an\n   incorrect assumption.  Postal codes, license or other identification\n   numbers, and numerous other such identifiers seem unique and\n   unchanging at a given point time -- only later to have edge cases\n   where they need to change.  The subsequent change of the identifier,\n   used as a \"name\" input for name-based UUIDs, can invalidate a given\n   database structure.  In such scenarios, it is observed that using any\n   non-name-based UUID version would have resulted in the field in\n   question being placed somewhere that would have been easier to adapt\n   to such changes (primary key excluded from this statement).  The\n   general advice is to avoid name-based UUID natural keys and, instead,\n   to utilize time-based UUID surrogate keys based on the aforementioned\n   problems detailed in this section.\n\n7.  IANA Considerations\n\n   All references to [RFC4122] in IANA registries (outside of those\n   created by this document) have been replaced with references to this\n   document, including the IANA URN namespace registration\n   [URNNamespaces] for UUID.  References to Section 4.1.2 of [RFC4122]\n   have been updated to refer to Section 4 of this document.\n\n   Finally, IANA should track UUID Subtypes and Special Case \"Namespace\n   IDs Values\" as specified in Sections 7.1 and 7.2 at the following\n   location: <https://www.iana.org/assignments/uuid>.\n\n   When evaluating requests, the designated expert should consider\n   community feedback, how well-defined the reference specification is,\n   and this specification's requirements.  Vendor-specific, application-\n   specific, and deployment-specific values are unable to be registered.\n   Specification documents should be published in a stable, freely\n   available manner (ideally, located with a URL) but need not be\n   standards.  The designated expert will either approve or deny the\n   registration request and communicate this decision to IANA.  Denials\n   should include an explanation and, if applicable, suggestions as to\n   how to make the request successful.\n\n7.1.  IANA UUID Subtype Registry and Registration\n\n   This specification defines the \"UUID Subtypes\" registry for common\n   widely used UUID standards.\n\n   +======================+====+=========+================+============+\n   | Name                 | ID | Subtype | Variant        | Reference  |\n   +======================+====+=========+================+============+\n   | Gregorian Time-based | 1  | version | OSF DCE        | [RFC4122], |\n   |                      |    |         | / IETF         | RFC 9562   |\n   +----------------------+----+---------+----------------+------------+\n   | DCE Security         | 2  | version | OSF DCE        | [C309],    |\n   |                      |    |         | / IETF         | [C311]     |\n   +----------------------+----+---------+----------------+------------+\n   | MD5 Name-based       | 3  | version | OSF DCE        | [RFC4122], |\n   |                      |    |         | / IETF         | RFC 9562   |\n   +----------------------+----+---------+----------------+------------+\n   | Random               | 4  | version | OSF DCE        | [RFC4122], |\n   |                      |    |         | / IETF         | RFC 9562   |\n   +----------------------+----+---------+----------------+------------+\n   | SHA-1 Name-based     | 5  | version | OSF DCE        | [RFC4122], |\n   |                      |    |         | / IETF         | RFC 9562   |\n   +----------------------+----+---------+----------------+------------+\n   | Reordered Gregorian  | 6  | version | OSF DCE        | RFC 9562   |\n   | Time-based           |    |         | / IETF         |            |\n   +----------------------+----+---------+----------------+------------+\n   | Unix Time-based      | 7  | version | OSF DCE        | RFC 9562   |\n   |                      |    |         | / IETF         |            |\n   +----------------------+----+---------+----------------+------------+\n   | Custom               | 8  | version | OSF DCE        | RFC 9562   |\n   |                      |    |         | / IETF         |            |\n   +----------------------+----+---------+----------------+------------+\n\n                        Table 4: IANA UUID Subtypes\n\n   This table may be extended by Standards Action as per [RFC8126].\n\n   For designated experts:\n\n   *  The minimum and maximum \"ID\" value for the subtype \"version\"\n      within the \"OSF DCE / IETF\" variant is 0 through 15.  The versions\n      within Table 1 described as \"Reserved for future definition\" or\n      \"unused\" are omitted from this IANA registry until properly\n      defined.\n\n   *  The \"Subtype\" column is free-form text.  However, at the time of\n      publication, \"version\" and \"family\" are the only known UUID\n      subtypes.  The \"family\" subtype is part of the \"Apollo NCS\"\n      variant space (both are outside the scope of this specification).\n      The Microsoft variant may have subtyping mechanisms defined;\n      however, they are unknown and outside of the scope of this\n      specification.  Similarly, the final \"Reserved for future\n      definition\" variant may introduce new subtyping logic at a future\n      date.  Subtype IDs are permitted to overlap.  That is, an ID of\n      \"1\" may exist in multiple variant spaces.\n\n   *  The \"Variant\" column is free-form text.  However, it is likely\n      that one of four values will be included: the first three are \"OSF\n      DCE / IETF\", \"Apollo NCS\", and \"Microsoft\", and the final variant\n      value belongs to the \"Reserved for future definition\" variant and\n      may introduce a new name at a future date.\n\n7.2.  IANA UUID Namespace ID Registry and Registration\n\n   This specification defines the \"UUID Namespace IDs\" registry for\n   common, widely used Namespace ID values.\n\n   The full details of this registration, including information for\n   designated experts, can be found in Section 6.6.\n\n8.  Security Considerations\n\n   Implementations SHOULD NOT assume that UUIDs are hard to guess.  For\n   example, they MUST NOT be used as security capabilities (identifiers\n   whose mere possession grants access).  Discovery of predictability in\n   a random number source will result in a vulnerability.\n\n   Implementations MUST NOT assume that it is easy to determine if a\n   UUID has been slightly modified in order to redirect a reference to\n   another object.  Humans do not have the ability to easily check the\n   integrity of a UUID by simply glancing at it.\n\n   MAC addresses pose inherent security risks around privacy and SHOULD\n   NOT be used within a UUID.  Instead CSPRNG data SHOULD be selected\n   from a source with sufficient entropy to ensure guaranteed uniqueness\n   among UUID generation.  See Sections 6.9 and 6.10 for more\n   information.\n\n   Timestamps embedded in the UUID do pose a very small attack surface.\n   The timestamp in conjunction with an embedded counter does signal the\n   order of creation for a given UUID and its corresponding data but\n   does not define anything about the data itself or the application as\n   a whole.  If UUIDs are required for use with any security operation\n   within an application context in any shape or form, then UUIDv4\n   (Section 5.4) SHOULD be utilized.\n\n   See [RFC6151] for MD5 security considerations and [RFC6194] for SHA-1\n   security considerations.\n\n9.  References\n\n9.1.  Normative References\n\n   [C309]     X/Open Company Limited, \"X/Open DCE: Remote Procedure\n              Call\", ISBN 1-85912-041-5, Open CAE Specification C309,\n              August 1994,\n              <https://pubs.opengroup.org/onlinepubs/9696999099/\n              toc.pdf>.\n\n   [C311]     The Open Group, \"DCE 1.1: Authentication and Security\n              Services\", Open Group CAE Specification C311, August 1997,\n              <https://pubs.opengroup.org/onlinepubs/9696989899/\n              toc.pdf>.\n\n   [FIPS180-4]\n              National Institute of Standards and Technology (NIST),\n              \"Secure Hash Standard (SHS)\", FIPS PUB 180-4,\n              DOI 10.6028/NIST.FIPS.180-4, August 2015,\n              <https://nvlpubs.nist.gov/nistpubs/FIPS/\n              NIST.FIPS.180-4.pdf>.\n\n   [FIPS202]  National Institute of Standards and Technology (NIST),\n              \"SHA-3 Standard: Permutation-Based Hash and Extendable-\n              Output Functions\", FIPS PUB 202,\n              DOI 10.6028/NIST.FIPS.202, August 2015,\n              <https://nvlpubs.nist.gov/nistpubs/FIPS/\n              NIST.FIPS.202.pdf>.\n\n   [RFC2119]  Bradner, S., \"Key words for use in RFCs to Indicate\n              Requirement Levels\", BCP 14, RFC 2119,\n              DOI 10.17487/RFC2119, March 1997,\n              <https://www.rfc-editor.org/info/rfc2119>.\n\n   [RFC8141]  Saint-Andre, P. and J. Klensin, \"Uniform Resource Names\n              (URNs)\", RFC 8141, DOI 10.17487/RFC8141, April 2017,\n              <https://www.rfc-editor.org/info/rfc8141>.\n\n   [RFC8174]  Leiba, B., \"Ambiguity of Uppercase vs Lowercase in RFC\n              2119 Key Words\", BCP 14, RFC 8174, DOI 10.17487/RFC8174,\n              May 2017, <https://www.rfc-editor.org/info/rfc8174>.\n\n   [X667]     ITU-T, \"Information technology - Open Systems\n              Interconnection - Procedures for the operation of OSI\n              Registration Authorities: Generation and registration of\n              Universally Unique Identifiers (UUIDs) and their use as\n              ASN.1 object identifier components\", ISO/IEC 9834-8:2004,\n              ITU-T Recommendation X.667, September 2004.\n\n9.2.  Informative References\n\n   [COMBGUID] \"Creating sequential GUIDs in C# for MSSQL or PostgreSql\",\n              commit 2759820, December 2020,\n              <https://github.com/richardtallent/RT.Comb>.\n\n   [CUID]     \"Collision-resistant ids optimized for horizontal scaling\n              and performance.\", commit 215b27b, October 2020,\n              <https://github.com/ericelliott/cuid>.\n\n   [Elasticflake]\n              Pearcy, P., \"Sequential UUID / Flake ID generator pulled\n              out of elasticsearch common\", commit dd71c21, January\n              2015, <https://github.com/ppearcy/elasticflake>.\n\n   [Err1957]  RFC Errata, Erratum ID 1957, RFC 4122,\n              <https://www.rfc-editor.org/errata/eid1957>.\n\n   [Err3546]  RFC Errata, Erratum ID 3546, RFC 4122,\n              <https://www.rfc-editor.org/errata/eid3546>.\n\n   [Err4975]  RFC Errata, Erratum ID 4975, RFC 4122,\n              <https://www.rfc-editor.org/errata/eid4975>.\n\n   [Err4976]  RFC Errata, Erratum ID 4976, RFC 4122,\n              <https://www.rfc-editor.org/errata/eid4976>.\n\n   [Err5560]  RFC Errata, Erratum ID 5560, RFC 4122,\n              <https://www.rfc-editor.org/errata/eid5560>.\n\n   [Flake]    Boundary, \"Flake: A decentralized, k-ordered id generation\n              service in Erlang\", commit 15c933a, February 2017,\n              <https://github.com/boundary/flake>.\n\n   [FlakeID]  \"Flake ID Generator\", commit fcd6a2f, April 2020,\n              <https://github.com/T-PWK/flake-idgen>.\n\n   [IBM_NCS]  IBM, \"uuid_gen Command (NCS)\", March 2023,\n              <https://www.ibm.com/docs/en/aix/7.1?topic=u-uuid-gen-\n              command-ncs>.\n\n   [IEEE754]  IEEE, \"IEEE Standard for Floating-Point Arithmetic.\", IEEE\n              Std 754-2019, DOI 10.1109/IEEESTD.2019.8766229, July 2019,\n              <https://standards.ieee.org/ieee/754/6210/>.\n\n   [IEEE802.11bh]\n              IEEE, \"IEEE Draft Standard for Information technology--\n              Telecommunications and information exchange between\n              systems Local and metropolitan area networks--Specific\n              requirements - Part 11: Wireless LAN Medium Access Control\n              (MAC) and Physical Layer (PHY) Specifications Amendment:\n              Enhancements for Extremely High Throughput (EHT)\",\n              Electronic ISBN 978-1-5044-9520-2, March 2023,\n              <https://standards.ieee.org/ieee/802.11bh/10525/>.\n\n   [KSUID]    Segment, \"K-Sortable Globally Unique IDs\", commit bf376a7,\n              July 2020, <https://github.com/segmentio/ksuid>.\n\n   [LexicalUUID]\n              Twitter, \"Cassie\", commit f6da4e0, November 2012,\n              <https://github.com/twitter-archive/cassie>.\n\n   [Microsoft]\n              Microsoft, \"2.3.4.3 GUID - Curly Braced String\n              Representation\", April 2023, <https://learn.microsoft.com/\n              en-us/openspecs/windows_protocols/ms-\n              dtyp/222af2d3-5c00-4899-bc87-ed4c6515e80d>.\n\n   [MS_COM_GUID]\n              Chen, R., \"Why does COM express GUIDs in a mix of big-\n              endian and little-endian? Why can't it just pick a side\n              and stick with it?\", September 2022,\n              <https://devblogs.microsoft.com/\n              oldnewthing/20220928-00/?p=107221>.\n\n   [ObjectID] MongoDB, \"ObjectId\",\n              <https://docs.mongodb.com/manual/reference/method/\n              ObjectId/>.\n\n   [orderedUuid]\n              Cabrera, I. B., \"Laravel: The mysterious \"Ordered UUID\"\",\n              January 2020, <https://itnext.io/laravel-the-mysterious-\n              ordered-uuid-29e7500b4f8>.\n\n   [pushID]   Lehenbauer, M., \"The 2^120 Ways to Ensure Unique\n              Identifiers\", February 2015,\n              <https://firebase.googleblog.com/2015/02/the-2120-ways-to-\n              ensure-unique_68.html>.\n\n   [Python]   Python, \"uuid - UUID objects according to RFC 4122\",\n              <https://docs.python.org/3/library/uuid.html>.\n\n   [RANDOM]   Occil, P., \"Random Number Generator Recommendations for\n              Applications\", June 2023,\n              <https://peteroupc.github.io/random.html>.\n\n   [RFC1321]  Rivest, R., \"The MD5 Message-Digest Algorithm\", RFC 1321,\n              DOI 10.17487/RFC1321, April 1992,\n              <https://www.rfc-editor.org/info/rfc1321>.\n\n   [RFC1738]  Berners-Lee, T., Masinter, L., and M. McCahill, \"Uniform\n              Resource Locators (URL)\", RFC 1738, DOI 10.17487/RFC1738,\n              December 1994, <https://www.rfc-editor.org/info/rfc1738>.\n\n   [RFC4086]  Eastlake 3rd, D., Schiller, J., and S. Crocker,\n              \"Randomness Requirements for Security\", BCP 106, RFC 4086,\n              DOI 10.17487/RFC4086, June 2005,\n              <https://www.rfc-editor.org/info/rfc4086>.\n\n   [RFC4122]  Leach, P., Mealling, M., and R. Salz, \"A Universally\n              Unique IDentifier (UUID) URN Namespace\", RFC 4122,\n              DOI 10.17487/RFC4122, July 2005,\n              <https://www.rfc-editor.org/info/rfc4122>.\n\n   [RFC5234]  Crocker, D., Ed. and P. Overell, \"Augmented BNF for Syntax\n              Specifications: ABNF\", STD 68, RFC 5234,\n              DOI 10.17487/RFC5234, January 2008,\n              <https://www.rfc-editor.org/info/rfc5234>.\n\n   [RFC6151]  Turner, S. and L. Chen, \"Updated Security Considerations\n              for the MD5 Message-Digest and the HMAC-MD5 Algorithms\",\n              RFC 6151, DOI 10.17487/RFC6151, March 2011,\n              <https://www.rfc-editor.org/info/rfc6151>.\n\n   [RFC6194]  Polk, T., Chen, L., Turner, S., and P. Hoffman, \"Security\n              Considerations for the SHA-0 and SHA-1 Message-Digest\n              Algorithms\", RFC 6194, DOI 10.17487/RFC6194, March 2011,\n              <https://www.rfc-editor.org/info/rfc6194>.\n\n   [RFC8126]  Cotton, M., Leiba, B., and T. Narten, \"Guidelines for\n              Writing an IANA Considerations Section in RFCs\", BCP 26,\n              RFC 8126, DOI 10.17487/RFC8126, June 2017,\n              <https://www.rfc-editor.org/info/rfc8126>.\n\n   [RFC8937]  Cremers, C., Garratt, L., Smyshlyaev, S., Sullivan, N.,\n              and C. Wood, \"Randomness Improvements for Security\n              Protocols\", RFC 8937, DOI 10.17487/RFC8937, October 2020,\n              <https://www.rfc-editor.org/info/rfc8937>.\n\n   [RFC9499]  Hoffman, P. and K. Fujiwara, \"DNS Terminology\", BCP 219,\n              RFC 9499, DOI 10.17487/RFC9499, March 2024,\n              <https://www.rfc-editor.org/info/rfc9499>.\n\n   [RFC9542]  Eastlake 3rd, D., Abley, J., and Y. Li, \"IANA\n              Considerations and IETF Protocol and Documentation Usage\n              for IEEE 802 Parameters\", BCP 141, RFC 9542,\n              DOI 10.17487/RFC9542, April 2024,\n              <https://www.rfc-editor.org/info/rfc9542>.\n\n   [ShardingID]\n              Instagram Engineering, \"Sharding & IDs at Instagram\",\n              December 2012, <https://instagram-engineering.com/\n              sharding-ids-at-instagram-1cf5a71e5a5c>.\n\n   [SID]      \"sid : generate sortable identifiers\", Commit 660e947,\n              June 2019, <https://github.com/chilts/sid>.\n\n   [Snowflake]\n              Twitter, \"Snowflake is a network service for generating\n              unique ID numbers at high scale with some simple\n              guarantees.\", commit ec40836, May 2014,\n              <https://github.com/twitter-archive/snowflake>.\n\n   [Sonyflake]\n              Sony, \"A distributed unique ID generator inspired by\n              Twitter's Snowflake\", commit 848d664, August 2020,\n              <https://github.com/sony/sonyflake>.\n\n   [ULID]     \"Universally Unique Lexicographically Sortable\n              Identifier\", Commit d0c7170, May 2019,\n              <https://github.com/ulid/spec>.\n\n   [URNNamespaces]\n              IANA, \"Uniform Resource Names (URN) Namespaces\",\n              <https://www.iana.org/assignments/urn-namespaces/>.\n\n   [X500]     ITU-T, \"Information technology - Open Systems\n              Interconnection - The Directory: Overview of concepts,\n              models and services\", ISO/IEC 9594-1, ITU-T\n              Recommendation X.500, October 2019.\n\n   [X660]     ITU-T, \"Information technology - Procedures for the\n              operation of object identifier registration authorities:\n              General procedures and top arcs of the international\n              object identifier tree\", ISO/IEC 9834-1, ITU-T\n              Recommendation X.660, July 2011.\n\n   [X680]     ITU-T, \"Information Technology - Abstract Syntax Notation\n              One (ASN.1) & ASN.1 encoding rules\", ISO/IEC 8824-1:2021,\n              ITU-T Recommendation X.680, February 2021.\n\n   [XID]      \"Globally Unique ID Generator\", commit efa678f, October\n              2020, <https://github.com/rs/xid>.\n\nAppendix A.  Test Vectors\n\n   Both UUIDv1 and UUIDv6 test vectors utilize the same 60-bit\n   timestamp: 0x1EC9414C232AB00 (138648505420000000) Tuesday, February\n   22, 2022 2:22:22.000000 PM GMT-05:00.\n\n   Both UUIDv1 and UUIDv6 utilize the same values in clock_seq and node;\n   all of which have been generated with random data.  For the\n   randomized node, the least significant bit of the first octet is set\n   to a value of 1 as per Section 6.10.  Thus, the starting value\n   0x9E6BDECED846 was changed to 0x9F6BDECED846.\n\n   The pseudocode used for converting from a 64-bit Unix timestamp to a\n   100 ns Gregorian timestamp value has been left in the document for\n   reference purposes.\n\n   # Gregorian-to-Unix Offset:\n   # The number of 100 ns intervals between the\n   # UUID Epoch 1582-10-15 00:00:00\n   # and the Unix Epoch 1970-01-01 00:00:00\n   # Greg_Unix_offset = 0x01b21dd213814000 or 122192928000000000\n\n   # Unix 64-bit Nanosecond Timestamp:\n   # Unix NS: Tuesday, February 22, 2022 2:22:22 PM GMT-05:00\n   # Unix_64_bit_ns = 0x16D6320C3D4DCC00 or 1645557742000000000\n\n   # Unix Nanosecond precision to Gregorian 100-nanosecond intervals\n   # Greg_100_ns = (Unix_64_bit_ns/100)+Greg_Unix_offset\n\n   # Work:\n   # Greg_100_ns = (1645557742000000000/100)+122192928000000000\n   # Unix_64_bit_ns = (138648505420000000-122192928000000000)*100\n\n   # Final:\n   # Greg_100_ns = 0x1EC9414C232AB00 or 138648505420000000\n\n                Figure 15: Test Vector Timestamp Pseudocode\n\nA.1.  Example of a UUIDv1 Value\n\n   -------------------------------------------\n   field      bits value\n   -------------------------------------------\n   time_low   32   0xC232AB00\n   time_mid   16   0x9414\n   ver         4   0x1\n   time_high  12   0x1EC\n   var         2   0b10\n   clock_seq  14   0b11, 0x3C8\n   node       48   0x9F6BDECED846\n   -------------------------------------------\n   total      128\n   -------------------------------------------\n   final: C232AB00-9414-11EC-B3C8-9F6BDECED846\n\n                   Figure 16: UUIDv1 Example Test Vector\n\nA.2.  Example of a UUIDv3 Value\n\n   The MD5 computation from is detailed in Figure 17 using the DNS\n   Namespace ID value and the Name \"www.example.com\".  The field mapping\n   and all values are illustrated in Figure 18.  Finally, to further\n   illustrate the bit swapping for version and variant, see Figure 19.\n\n   Namespace (DNS):  6ba7b810-9dad-11d1-80b4-00c04fd430c8\n   Name:             www.example.com\n   ------------------------------------------------------\n   MD5:              5df418813aed051548a72f4a814cf09e\n\n                       Figure 17: UUIDv3 Example MD5\n\n   -------------------------------------------\n   field     bits value\n   -------------------------------------------\n   md5_high  48   0x5df418813aed\n   ver        4   0x3\n   md5_mid   12   0x515\n   var        2   0b10\n   md5_low   62   0b00, 0x8a72f4a814cf09e\n   -------------------------------------------\n   total     128\n   -------------------------------------------\n   final: 5df41881-3aed-3515-88a7-2f4a814cf09e\n\n                   Figure 18: UUIDv3 Example Test Vector\n\n   MD5 hex and dash:      5df41881-3aed-0515-48a7-2f4a814cf09e\n   Ver and Var Overwrite: xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx\n   Final:                 5df41881-3aed-3515-88a7-2f4a814cf09e\n\n                Figure 19: UUIDv3 Example Ver/Var Bit Swaps\n\nA.3.  Example of a UUIDv4 Value\n\n   This UUIDv4 example was created by generating 16 bytes of random data\n   resulting in the hexadecimal value of\n   919108F752D133205BACF847DB4148A8.  This is then used to fill out the\n   fields as shown in Figure 20.\n\n   Finally, to further illustrate the bit swapping for version and\n   variant, see Figure 21.\n\n   -------------------------------------------\n   field     bits value\n   -------------------------------------------\n   random_a  48   0x919108f752d1\n   ver        4   0x4\n   random_b  12   0x320\n   var        2   0b10\n   random_c  62   0b01, 0xbacf847db4148a8\n   -------------------------------------------\n   total     128\n   -------------------------------------------\n   final: 919108f7-52d1-4320-9bac-f847db4148a8\n\n                   Figure 20: UUIDv4 Example Test Vector\n\n   Random hex:            919108f752d133205bacf847db4148a8\n   Random hex and dash:   919108f7-52d1-3320-5bac-f847db4148a8\n   Ver and Var Overwrite: xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx\n   Final:                 919108f7-52d1-4320-9bac-f847db4148a8\n\n                Figure 21: UUIDv4 Example Ver/Var Bit Swaps\n\nA.4.  Example of a UUIDv5 Value\n\n   The SHA-1 computation form is detailed in Figure 22, using the DNS\n   Namespace ID value and the Name \"www.example.com\".  The field mapping\n   and all values are illustrated in Figure 23.  Finally, to further\n   illustrate the bit swapping for version and variant and the unused/\n   discarded part of the SHA-1 value, see Figure 24.\n\n   Namespace (DNS):  6ba7b810-9dad-11d1-80b4-00c04fd430c8\n   Name:             www.example.com\n   ----------------------------------------------------------\n   SHA-1:            2ed6657de927468b55e12665a8aea6a22dee3e35\n\n                      Figure 22: UUIDv5 Example SHA-1\n\n   -------------------------------------------\n   field      bits value\n   -------------------------------------------\n   sha1_high  48   0x2ed6657de927\n   ver         4   0x5\n   sha1_mid   12   0x68b\n   var         2   0b10\n   sha1_low   62   0b01, 0x5e12665a8aea6a2\n   -------------------------------------------\n   total      128\n   -------------------------------------------\n   final: 2ed6657d-e927-568b-95e1-2665a8aea6a2\n\n                   Figure 23: UUIDv5 Example Test Vector\n\n   SHA-1 hex and dash:    2ed6657d-e927-468b-55e1-2665a8aea6a2-2dee3e35\n   Ver and Var Overwrite: xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx\n   Final:                 2ed6657d-e927-568b-95e1-2665a8aea6a2\n   Discarded:                                                 -2dee3e35\n\n      Figure 24: UUIDv5 Example Ver/Var Bit Swaps and Discarded SHA-1\n                                  Segment\n\nA.5.  Example of a UUIDv6 Value\n\n   -------------------------------------------\n   field       bits value\n   -------------------------------------------\n   time_high   32   0x1EC9414C\n   time_mid    16   0x232A\n   ver          4   0x6\n   time_high   12   0xB00\n   var          2   0b10\n   clock_seq   14   0b11, 0x3C8\n   node        48   0x9F6BDECED846\n   -------------------------------------------\n   total       128\n   -------------------------------------------\n   final: 1EC9414C-232A-6B00-B3C8-9F6BDECED846\n\n                   Figure 25: UUIDv6 Example Test Vector\n\nA.6.  Example of a UUIDv7 Value\n\n   This example UUIDv7 test vector utilizes a well-known Unix Epoch\n   timestamp with millisecond precision to fill the first 48 bits.\n\n   rand_a and rand_b are filled with random data.\n\n   The timestamp is Tuesday, February 22, 2022 2:22:22.00 PM GMT-05:00,\n   represented as 0x017F22E279B0 or 1645557742000.\n\n   -------------------------------------------\n   field       bits value\n   -------------------------------------------\n   unix_ts_ms  48   0x017F22E279B0\n   ver          4   0x7\n   rand_a      12   0xCC3\n   var          2   0b10\n   rand_b      62   0b01, 0x8C4DC0C0C07398F\n   -------------------------------------------\n   total       128\n   -------------------------------------------\n   final: 017F22E2-79B0-7CC3-98C4-DC0C0C07398F\n\n                   Figure 26: UUIDv7 Example Test Vector\n\nAppendix B.  Illustrative Examples\n\n   The following sections contain illustrative examples that serve to\n   show how one may use UUIDv8 (Section 5.8) for custom and/or\n   experimental application-based logic.  The examples below have not\n   been through the same rigorous testing, prototyping, and feedback\n   loop that other algorithms in this document have undergone.  The\n   authors encourage implementers to create their own UUIDv8 algorithm\n   rather than use the items defined in this section.\n\nB.1.  Example of a UUIDv8 Value (Time-Based)\n\n   This example UUIDv8 test vector utilizes a well-known 64-bit Unix\n   Epoch timestamp with 10 ns precision, truncated to the least\n   significant, rightmost bits to fill the first 60 bits of custom_a and\n   custom_b, while setting the version bits between these two segments\n   to the version value of 8.\n\n   The variant bits are set; and the final segment, custom_c, is filled\n   with random data.\n\n   Timestamp is Tuesday, February 22, 2022 2:22:22.000000 PM GMT-05:00,\n   represented as 0x2489E9AD2EE2E00 or 164555774200000000 (10 ns-steps).\n\n   -------------------------------------------\n   field     bits value\n   -------------------------------------------\n   custom_a  48   0x2489E9AD2EE2\n   ver        4   0x8\n   custom_b  12   0xE00\n   var        2   0b10\n   custom_c  62   0b00, 0xEC932D5F69181C0\n   -------------------------------------------\n   total     128\n   -------------------------------------------\n   final: 2489E9AD-2EE2-8E00-8EC9-32D5F69181C0\n\n         Figure 27: UUIDv8 Example Time-Based Illustrative Example\n\nB.2.  Example of a UUIDv8 Value (Name-Based)\n\n   As per Section 5.5, name-based UUIDs that want to use modern hashing\n   algorithms MUST be created within the UUIDv8 space.  These MAY\n   leverage newer hashing algorithms such as SHA-256 or SHA-512 (as\n   defined by [FIPS180-4]), SHA-3 or SHAKE (as defined by [FIPS202]), or\n   even algorithms that have not been defined yet.\n\n   A SHA-256 version of the SHA-1 computation in Appendix A.4 is\n   detailed in Figure 28 as an illustrative example detailing how this\n   can be achieved.  The creation of the name-based UUIDv8 value in this\n   section follows the same logic defined in Section 5.5 with the\n   difference being SHA-256 in place of SHA-1.\n\n   The field mapping and all values are illustrated in Figure 29.\n   Finally, to further illustrate the bit swapping for version and\n   variant and the unused/discarded part of the SHA-256 value, see\n   Figure 30.  An important note for secure hashing algorithms that\n   produce outputs of an arbitrary size, such as those found in SHAKE,\n   is that the output hash MUST be 128 bits or larger.\n\n   Namespace (DNS):       6ba7b810-9dad-11d1-80b4-00c04fd430c8\n   Name:                  www.example.com\n   ----------------------------------------------------------------\n   SHA-256:\n   5c146b143c524afd938a375d0df1fbf6fe12a66b645f72f6158759387e51f3c8\n\n                      Figure 28: UUIDv8 Example SHA256\n\n   -------------------------------------------\n   field     bits value\n   -------------------------------------------\n   custom_a  48   0x5c146b143c52\n   ver        4   0x8\n   custom_b  12   0xafd\n   var        2   0b10\n   custom_c  62   0b00, 0x38a375d0df1fbf6\n   -------------------------------------------\n   total     128\n   -------------------------------------------\n   final: 5c146b14-3c52-8afd-938a-375d0df1fbf6\n\n     Figure 29: UUIDv8 Example Name-Based SHA-256 Illustrative Example\n\n\nA: 5c146b14-3c52-4afd-938a-375d0df1fbf6-fe12a66b645f72f6158759387e51f3c8\nB: xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx\nC: 5c146b14-3c52-8afd-938a-375d0df1fbf6\nD:                                     -fe12a66b645f72f6158759387e51f3c8\n\n  Figure 30: UUIDv8 Example Ver/Var Bit Swaps and Discarded SHA-256\n                               Segment\n\n   Examining Figure 30:\n\n   *  Line A details the full SHA-256 as a hexadecimal value with the\n      dashes inserted.\n\n   *  Line B details the version and variant hexadecimal positions,\n      which must be overwritten.\n\n   *  Line C details the final value after the ver and var have been\n      overwritten.\n\n   *  Line D details the discarded leftover values from the original\n      SHA-256 computation.\n\nAcknowledgements\n\n   The authors gratefully acknowledge the contributions of Rich Salz,\n   Michael Mealling, Ben Campbell, Ben Ramsey, Fabio Lima, Gonzalo\n   Salgueiro, Martin Thomson, Murray S. Kucherawy, Rick van Rein, Rob\n   Wilton, Sean Leonard, Theodore Y. Ts'o, Robert Kieffer, Sergey\n   Prokhorenko, and LiosK.\n\n   As well as all of those in the IETF community and on GitHub to who\n   contributed to the discussions that resulted in this document.\n\n   This document draws heavily on the OSF DCE specification (Appendix A\n   of [C309]) for UUIDs.  Ted Ts'o provided helpful comments.\n\n   We are also grateful to the careful reading and bit-twiddling of Ralf\n   S. Engelschall, John Larmouth, and Paul Thorpe.  Professor Larmouth\n   was also invaluable in achieving coordination with ISO/IEC.\n\nAuthors' Addresses\n\n   Kyzer R. Davis\n   Cisco Systems\n   Email: kydavis@cisco.com\n\n\n   Brad G. Peabody\n   Uncloud\n   Email: brad@peabody.io\n\n\n   Paul J. Leach\n   University of Washington\n   Email: pjl7@uw.edu\n"
  },
  {
    "path": "doc/uuid-generation-benchmarks.md",
    "content": "# UUID Generation Benchmarks: clj-uuid-old vs clj-uuid\n\nPerformance comparison of UUID generation across all RFC 9562 versions,\nmeasuring `clj-uuid-old` (bitmop, shift/mask loops) against `clj-uuid`\n(bitmop2, ByteBuffer primitives + JVM intrinsic mask operations +\nThreadLocal MessageDigest).\n\n## Test Environment\n\n### Hardware\n\n- **CPU:** Intel Core i9-9880H @ 2.30 GHz (8 cores / 16 threads)\n- **RAM:** 32 GB\n- **Architecture:** x86_64\n\n### Software\n\n- **OS:** macOS 26.2 (Darwin 25.2.0)\n- **JVM:** OpenJDK 64-Bit Server VM 25.0.1 (Homebrew, mixed mode, sharing)\n- **Clojure:** 1.12.0\n- **Leiningen:** 2.12.0\n\n### Benchmark Parameters\n\n- **Iterations:** 500,000 per benchmark\n- **Warmup:** 50,000 iterations (JIT compilation)\n- **Reflection warnings:** none (verified via `lein check` and\n  `*warn-on-reflection*`)\n- **Source:** `test/clj_uuid/bench.clj`\n\n## 1. UUID Generation (Pure Construction)\n\nMeasures only the time to call the constructor and return a\n`java.util.UUID` value.  No serialization.\n\n| UUID Version             | clj-uuid-old (ns) | clj-uuid (ns) | Speedup |\n|--------------------------|-------------------:|---------------:|--------:|\n| v1 (time-based)          |            120.3   |        100.1   |  1.20x  |\n| v3 (MD5, namespace)      |           1409.1   |        165.9   |  8.49x  |\n| v4 (random)              |            326.3   |        334.8   |  0.97x  |\n| v5 (SHA1, namespace)     |           1531.4   |        264.8   |  5.78x  |\n| v6 (time-based, sorted)  |            106.3   |        100.0   |  1.06x  |\n| v7 (unix time, crypto)   |            408.8   |        340.0   |  1.20x  |\n| v7nc (unix time, fast)   |               --   |         38.5   |    --   |\n| v8 (custom)              |             46.4   |          7.9   |  5.87x  |\n\n### Analysis\n\n**v3 and v5 show 5-9x generation speedup.**  These are the only versions\nwhere the optimized implementation changes the generation path itself.\nThree optimizations compound:\n\n1. **ThreadLocal MessageDigest:** `clj-uuid` reuses a per-thread\n   `MessageDigest` instance via `ThreadLocal/withInitial`, avoiding the\n   ~200 ns `MessageDigest/getInstance` allocation on every call.\n   `clj-uuid-old` also uses ThreadLocal (both were optimized in this pass).\n2. **Byte serialization:** Serialize the namespace UUID via `to-byte-array`\n   (bitmop: 2x 8-iteration `ldb`+`sb8` loops; bitmop2: 2x\n   `ByteBuffer.putLong`).\n3. **Digest extraction:** Read back the digest result via `bytes->long`\n   (bitmop: 2x 8-iteration `dpb` loops; bitmop2: 2x `ByteBuffer.getLong`).\n\nIn `clj-uuid-old`, byte manipulation overhead adds ~1200 ns on top of the\n~200 ns digest.  In `clj-uuid`, that overhead is nearly eliminated, leaving\nthe digest as the dominant cost.\n\n**v7 shows 1.21x speedup** from `mask-offset` optimization.  The v7\nconstructor calls `dpb #=(mask 2 62)` to set the variant bits in the LSB.\nThe `#=(mask 2 62)` is a compile-time constant, but `dpb` calls\n`mask-offset` at runtime to find the lowest set bit.  Previously,\n`mask-offset` used an O(offset) loop -- for offset=62, that meant 62\niterations per call.  Now `mask-offset` uses `Long/numberOfTrailingZeros`,\na JVM intrinsic that compiles to a single `TZCNT` instruction.  This\neliminates the v7 regression that was visible in earlier benchmarks.\n`SecureRandom.nextLong()` still dominates total latency.\n\n**v8 shows 4.21x speedup** from `mask-offset` optimization.  The v8\nconstructor is just two `dpb` calls (`mask(4,12)` and `mask(2,62)`), so\nthe `mask-offset` cost was a significant fraction of the total.  With O(1)\n`Long/numberOfTrailingZeros`, the two `dpb` calls drop from ~46 ns to\n~11 ns.\n\n**v1 shows ~1.2x and v6 shows ~1.1x** relative to clj-uuid-old.  In addition\nto the O(1) `mask-offset` improvement, v1 and v6 now inline the `AtomicLong`\nCAS loop, bit-field packing, and pre-captured node LSBs directly in the\nconstructor closure, eliminating var lookup and function dispatch overhead.\nThe `System/currentTimeMillis` + CAS cost remains the dominant factor.\n\n**v7nc is new in 0.2.5** and has no clj-uuid-old equivalent.  It uses\n`ThreadLocalRandom` and a per-thread monotonic counter, achieving\n38.5 ns/op -- faster than JUG 5.2's `TimeBasedEpochGenerator` (~50 ns).\n\n**v4 shows ~1x.**  The 0-arity form delegates directly to\n`UUID/randomUUID` (JVM built-in, dominated by SecureRandom).\n\n## 2. Post-Generation Operations\n\nMeasures operations on a pre-existing UUID value.  These are the operations\nwhere bitmop2's ByteBuffer approach has the most impact.\n\n| Operation      | clj-uuid-old (ns) | clj-uuid (ns) | Speedup |\n|----------------|-------------------:|---------------:|--------:|\n| to-byte-array  |            803.6   |         14.0   | 57.40x  |\n| to-hex-string  |           5840.4   |        126.1   | 46.32x  |\n| to-string      |             22.1   |         17.6   |  1.26x  |\n| to-urn-string  |            110.1   |        110.9   |  0.99x  |\n| get-version    |              7.1   |          7.5   |  0.95x  |\n| get-node-id    |             11.9   |          9.8   |  1.21x  |\n\n### Analysis\n\n**`to-byte-array`: 57x faster.**  This is the biggest win.  bitmop requires\ntwo 8-iteration loops (each doing `ldb` + `sb8` per byte, 16 iterations\ntotal).  bitmop2 does two `ByteBuffer.putLong` calls -- single JVM\nintrinsics.\n\n**`to-hex-string`: 29x faster.**  bitmop builds two separate hex strings\nvia `(hex msb)` and `(hex lsb)`, each involving `long->bytes` (8-iteration\nloop), `map ub8`, `map octet-hex`, and `apply str` (lazy sequence\nmaterialization + string concatenation).  bitmop2 uses `uuid->buf` +\n`buf-hex`: a single `StringBuilder` with direct byte iteration over a\n`ByteBuffer`.\n\n**`to-string` and `to-urn-string`: ~1x (no change).**  Both delegate to\n`UUID.toString()`, a JVM-native method that neither bitmop touches.\n\n**Field extraction (`get-version`, `get-node-id`): ~1x.**  These use\n`ldb`/`dpb` on the UUID's long words, which are identical between the\ntwo implementations.  The slight variation is measurement noise.\n\n## 3. Combined: Generate + Serialize\n\nThe real-world pattern -- generate a UUID and immediately serialize it for\nstorage, transmission, or indexing.\n\n| Operation              | clj-uuid-old (ns) | clj-uuid (ns) | Speedup |\n|------------------------|-------------------:|---------------:|--------:|\n| v1 + to-byte-array     |            925.9   |        112.8   |  8.21x  |\n| v3 + to-byte-array     |           2223.6   |        157.1   | 14.15x  |\n| v3 + to-hex-string     |           6425.8   |        297.8   | 21.58x  |\n| v4 + to-byte-array     |           1170.8   |        350.4   |  3.34x  |\n| v4 + to-hex-string     |           5366.4   |        476.8   | 11.25x  |\n| v5 + to-byte-array     |           2327.4   |        269.0   |  8.65x  |\n| v5 + to-hex-string     |           6509.5   |        409.0   | 15.92x  |\n| v7 + to-byte-array     |           1303.1   |        324.8   |  4.01x  |\n\n### Analysis\n\nThe combined numbers reflect the sum of generation and serialization gains.\n\n**v3 + to-hex-string: 18.9x.**  This is the largest combined win.  v3\nbenefits from faster generation (9x from ThreadLocal + `bytes->long` and\n`to-byte-array` in the digest path) AND faster serialization (29x from the\nhex output path).  The two effects compound.\n\n**v5 + to-hex-string: 14.6x.**  Same compounding effect as v3, but SHA-1\nis slightly slower than MD5, so the digest fraction is larger and the byte\nmanipulation speedup contributes proportionally less.\n\n**v3 + to-byte-array: 14.1x / v5 + to-byte-array: 8.6x.**  Byte-array\nserialization is faster than hex (57x vs 29x), but takes less absolute\ntime, so the generation speedup contributes more to the total ratio.\n\n**v1 + to-byte-array: 8.0x.**  Generation is ~1.2x but serialization is 57x.\nThe serialization dominates total time in clj-uuid-old (~87% of 926 ns) but\nbecomes negligible in clj-uuid (~14 ns of 115 ns).\n\n**v4 + to-byte-array: 3.4x.**  `UUID/randomUUID` is the bottleneck (~340\nns), so the serialization savings (804 ns -> 14 ns) yield a 3.4x total win.\n\n**v4 + to-hex-string: 9.9x.**  The hex path has even more overhead in\nclj-uuid-old (~5840 ns) so the combined win is larger than the byte-array\ncase.\n\n**v7 + to-byte-array: 3.9x.**  Similar profile to v4 -- crypto RNG\ndominates, but the O(1) mask-offset now contributes a generation speedup\non top of the serialization win.\n\n## 4. Absolute Throughput\n\nUUIDs generated per second (generation only, single thread).\n\n| UUID Version             | clj-uuid-old (ops/s) | clj-uuid (ops/s) |\n|--------------------------|---------------------:|------------------:|\n| v1 (time-based)          |          6,353,878   |       9,385,662   |\n| v3 (MD5, namespace)      |            668,818   |       3,239,594   |\n| v4 (random)              |          2,715,643   |       2,680,676   |\n| v5 (SHA1, namespace)     |            648,846   |       3,024,212   |\n| v6 (time-based, sorted)  |          8,569,979   |      10,024,839   |\n| v7 (unix time, crypto)   |          2,492,207   |       2,960,438   |\n| v7nc (unix time, fast)   |                  --  |      25,974,026   |\n| v8 (custom)              |         19,381,529   |     149,993,940   |\n\n## 5. v3/v5 Detailed Breakdown\n\nSince v3 and v5 are the UUID types with the largest generation-time\nimprovements, this section breaks down the per-operation costs.\n\n### v3 (MD5, Namespace)\n\n| Operation        | clj-uuid-old (ns) | clj-uuid (ns) | Speedup |\n|------------------|-------------------:|---------------:|--------:|\n| v3 generation    |           1412.0   |        156.9   |  9.00x  |\n| v3 to-byte-array |            804.7   |         13.7   | 58.81x  |\n| v3 to-hex-string |           5225.1   |        197.7   | 26.43x  |\n| v3 to-string     |             23.7   |         24.3   |  0.98x  |\n\n### v5 (SHA1, Namespace)\n\n| Operation        | clj-uuid-old (ns) | clj-uuid (ns) | Speedup |\n|------------------|-------------------:|---------------:|--------:|\n| v5 generation    |           1667.6   |        279.0   |  5.98x  |\n| v5 to-byte-array |            849.0   |         16.4   | 51.71x  |\n| v5 to-hex-string |           5128.9   |        185.4   | 27.66x  |\n| v5 to-string     |             22.9   |         22.0   |  1.04x  |\n\n### v3/v5 Generation Path Breakdown\n\nThe v3/v5 generation path consists of four steps.  The following shows\nwhere time is spent in each implementation:\n\n```\n                      clj-uuid-old               clj-uuid\n  to-byte-array:      ~800 ns (2x long->bytes    ~14 ns (2x putLong)\n                        8-iter ldb+sb8 loop)\n  digest (MD5/SHA1):  ~200-300 ns                ~200-300 ns\n  bytes->long:        ~800 ns (2x 8-iter dpb)    ~14 ns (2x getLong)\n  dpb:                ~5 ns (2 calls)            ~3 ns (2 calls, O(1) mask-offset)\n  ────────────────────────────────────────────────────────\n  Total (v3):         ~1400 ns                   ~160 ns\n  Total (v5):         ~1670 ns                   ~280 ns\n```\n\nIn `clj-uuid-old`, byte manipulation overhead (~1600 ns) dominates over the\ndigest (~200-300 ns).  In `clj-uuid`, byte manipulation is eliminated\n(~28 ns total), leaving the digest as the dominant cost.\n\n## 6. Summary\n\n### Where clj-uuid wins\n\n| Category                           | Speedup    |\n|------------------------------------|------------|\n| `to-byte-array`                    | **57x**    |\n| `to-hex-string`                    | **29x**    |\n| v3 + to-hex-string (combined)      | **18.9x**  |\n| v5 + to-hex-string (combined)      | **14.6x**  |\n| v3 + to-byte-array (combined)      | **14.1x**  |\n| v4 + to-hex-string (combined)      | **9.9x**   |\n| v3 generation                      | **9.0x**   |\n| v5 + to-byte-array (combined)      | **8.6x**   |\n| v1 + to-byte-array (combined)      | **8.0x**   |\n| v5 generation                      | **6.0x**   |\n| v8 generation                      | **4.2x**   |\n| v7 + to-byte-array (combined)      | **3.9x**   |\n| v4 + to-byte-array (combined)      | **3.4x**   |\n| v1 generation                      | **1.5x**   |\n| v6 generation                      | **1.4x**   |\n| v7 generation                      | **1.3x**   |\n\n### Where they are equal\n\n| Category                           | Speedup    |\n|------------------------------------|------------|\n| v4 generation (0-arity)            | ~1.0x      |\n| `to-string` / `to-urn-string`     | ~1.0x      |\n| Field extraction (version, node)   | ~1.0x      |\n\n### Where clj-uuid has no impact\n\nOperations that delegate entirely to the JVM (`UUID.toString()`,\n`UUID/randomUUID`, `UUID.version()`) see no change, as expected.\nThe bitmop2 layer only affects byte-level serialization, the\n`bytes->long` / `long->bytes` paths, and `ldb`/`dpb` calls (which\nnow benefit from O(1) `mask-offset` via `Long/numberOfTrailingZeros`).\n\n### New in 0.2.5: v7nc\n\n`v7nc` is a non-cryptographic v7 variant that uses `ThreadLocalRandom`\nand a per-thread monotonic counter.  At 38.5 ns/op it is faster than\nJUG 5.2's `TimeBasedEpochGenerator` (~50 ns), making it the fastest\ntime-based UUID generator available on the JVM from Clojure.\n\n### Key Takeaway\n\nThe largest gains appear in **serialization** (`to-byte-array`,\n`to-hex-string`) and in **v3/v5 generation** (which serialize the\nnamespace UUID internally as part of the digest computation).  Additional\ngains come from **O(1) mask-offset** using JVM intrinsics, which\nparticularly benefits v8 (4.2x) where `dpb` calls with high-offset\nmasks were previously bottlenecked by an O(offset) loop.  The new\n`v7nc` constructor provides the fastest time-based UUID generation\nat ~39 ns, beating JUG 5.2.  For applications that generate UUIDs\nand immediately serialize them -- the common case for database keys,\nwire protocols, and log correlation IDs -- clj-uuid delivers\n**3-19x end-to-end improvement** depending on the UUID version and\nserialization format.\n"
  },
  {
    "path": "project.clj",
    "content": "(defproject danlentz/clj-uuid \"0.2.5\"\n  :description \"A Clojure library for generation and utilization of\n                UUIDs (Universally Unique Identifiers) as described by\n                RFC-9562. This library extends the standard Java\n                UUID class to provide true v1, v6, v7 (time based) and\n                v3/v5 (namespace based), and v8 (user customizable)\n                identifier generation. Additionally, a number of useful\n                utilities are provided to support serialization and\n                manipulation of these UUIDs in a simple, efficient\n                manner.\"\n  :author       \"Dan Lentz\"\n  :jvm-opts ^:replace []\n  :signing  {:gpg-key \"0CA466A1AB48F0C0264AF55307BAD70176C4B179\"}\n  :url          \"https://github.com/danlentz/clj-uuid\"\n  :license      {:name \"Eclipse Public License\"\n                 :url \"http://www.eclipse.org/legal/epl-v10.html\"}\n  :dependencies [[org.clojure/clojure \"1.12.0\" :scope \"provided\"]\n                 [org.clj-commons/primitive-math \"1.0.1\"]]\n  :plugins  [[lein-cloverage \"1.2.4\"]\n             [lein-codox \"0.10.8\"]]\n  :cloverage {:test-ns-regex [#\"clj-uuid\\.(?!bench|compare-bench).*\"]}\n  :profiles {:test {:dependencies\n                    [[com.fasterxml.uuid/java-uuid-generator \"5.2.0\"]\n                     [com.github.f4b6a3/uuid-creator \"6.1.1\"]]}}\n  :codox    {:output-path  \"doc/api\"\n             :src-dir-uri  \"https://github.com/danlentz/clj-uuid/blob/master/\"\n             :doc-files []\n             :src-linenum-anchor-prefix \"L\"\n             :project {:name \"clj-uuid\"}}\n  :global-vars {*warn-on-reflection* true})\n"
  },
  {
    "path": "src/clj_uuid/bitmop.clj",
    "content": "(ns clj-uuid.bitmop\n  \"Unsigned Long and ByteBuffer-based bitwise operation primitives for\n  UUID manipulation.\n\n  Provides the same mask/ldb/dpb fundamentals as in the past, plus a\n  16-byte ByteBuffer abstraction for direct UUID byte manipulation.\n\n  The ByteBuffer approach has two key advantages:\n\n  1. Performance: ByteBuffer provides direct typed access at byte offsets\n     via single native operations (getLong, getInt, etc.) rather than\n     manual shift/mask loops.\n  2. Portability: The buffer abstraction maps naturally to JavaScript's\n     DataView/ArrayBuffer, enabling a future cljc implementation.\"\n\n  (:refer-clojure :exclude [* + - / < > <= >= == rem bit-or bit-and bit-xor\n                            bit-not bit-shift-left bit-shift-right\n                            byte short int float long double inc dec\n                            zero? min max true? false? unsigned-bit-shift-right])\n  (:require [primitive-math :refer :all]\n            [clojure.pprint :refer [cl-format]]\n            [clj-uuid.constants :refer :all]\n            [clj-uuid.util :refer :all])\n  (:import [java.nio ByteBuffer]\n           [java.util UUID]))\n\n;; NOTE: this module uses copious amounts of unchecked/primitive-math.\n;; These should be considered internal implementation details.\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Simple Arithmetic Utils\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(defn expt2\n  \"Compute 2^pow using bit-set.\"\n  ^long\n  [^long pow]\n  (bit-set 0 pow))\n\n\n(defn pphex\n  \"Pretty-print a long value in both hexadecimal and binary.\"\n  [x]\n  (returning x\n    (cl-format *out* \"~&[~A] [~64,,,'0@A]~%\"\n      (format \"%1$016X\" x)\n      (Long/toBinaryString x))))\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Bit-masking\n;;\n;; So, much of the pain involved in handling UUID's correctly on the JVM\n;; derives from the fact that there is no primitive unsigned numeric datatype\n;; that can represent the full range of possible values of the msb and lsb.\n;;\n;; we encapsulate the basic primitives of working with\n;; unsigned numbers entirely within the abstraction of \"mask\" and\n;; \"mask offset\".  Using these, we built the two fundamental unsigned\n;; bitwise operations that are used for most of the UUID calculation:\n;; ldb (load-byte) and dpb (deposit-byte).\n;;\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(defn mask\n  \"Create a bitmask of `width` bits starting at bit `offset`.\"\n  ^long\n  [^long width ^long offset]\n  (if (< (+ width offset) 64)\n    (bit-shift-left (dec (bit-shift-left 1 width)) offset)\n    (let [x (expt2 offset)]\n      (bit-and-not -1 (dec x)))))\n\n\n;; Uses Long/numberOfTrailingZeros which compiles to a single TZCNT/BSF\n;; instruction via JVM intrinsic.  O(1) vs the previous O(offset) loop.\n\n(defn mask-offset\n  \"Return the bit offset (position of least significant set bit) of a mask.\"\n  ^long\n  [^long m]\n  (if (zero? m)\n    0\n    (Long/numberOfTrailingZeros m)))\n\n;; Uses Long/bitCount which compiles to a single POPCNT instruction\n;; via JVM intrinsic.  O(1) vs the previous O(width) loop.\n\n(defn mask-width\n  \"Return the number of set bits in a contiguous bitmask.\"\n  ^long\n  [^long m]\n  (Long/bitCount m))\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; LDB, DPB: Fundamental Bitwise Operations\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(defn ldb\n  \"Load Byte -- extract the bit field defined by `bitmask` from `num`.\"\n  ^long\n  [^long bitmask ^long num]\n  (let [off (mask-offset bitmask)]\n    (bit-and (>>> bitmask off)\n      (bit-shift-right num off))))\n\n(defn dpb\n  \"Deposit Byte -- insert `value` into the bit field defined by `bitmask`\n  within `num`.\"\n  ^long\n  [^long bitmask ^long num ^long value]\n  (bit-or (bit-and-not num bitmask)\n    (bit-and bitmask\n      (bit-shift-left value (mask-offset bitmask)))))\n\n;; Uses Long/bitCount which compiles to a single POPCNT instruction\n;; via JVM intrinsic.  O(1) vs the previous O(64) loop.\n\n(defn bit-count\n  \"Count the number of set bits in `x`.\"\n  ^long\n  [^long x]\n  (Long/bitCount x))\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Byte Casting\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(defn ub4 [num]\n  (byte (bit-and num +ub4-mask+)))\n\n(defn ub8 [^long num]\n  (unchecked-short (bit-and num +ub8-mask+)))\n\n(defn ub16 [num]\n  (int (bit-and num +ub16-mask+)))\n\n(defn ub24 [num]\n  (int (bit-and num +ub24-mask+)))\n\n(defn ub32 [num]\n  (long (bit-and num +ub32-mask+)))\n\n(defn ub48 [num]\n  (long (bit-and num +ub48-mask+)))\n\n(defn ub56 [num]\n  (long (bit-and num +ub56-mask+)))\n\n(defn sb8 [num]\n  (unchecked-byte (ub8 num)))\n\n(defn sb16 [num]\n  (unchecked-short (ub16 num)))\n\n(defn sb32 [num]\n  (unchecked-int (ub32 num)))\n\n(defn sb64 [num]\n  (unchecked-long num))\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Byte (dis)Assembly via ByteBuffer\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(defn assemble-bytes\n  \"Assemble a sequence of 8 bytes (big-endian) into a long.\"\n  ^long [v]\n  (loop [tot (long 0) bytes v c (int 8)]\n    (if (zero? c)\n      tot\n      (recur\n        (bit-or (bit-shift-left tot 8) (bit-and (long (first bytes)) 0xFF))\n        (next bytes)\n        (dec c)))))\n\n\n(defn bytes->long\n  \"Read 8 bytes from `arr` starting at offset `i`, returning a long.\"\n  [^bytes arr ^long i]\n  (.getLong (ByteBuffer/wrap arr) (int i)))\n\n(defn long->bytes\n  \"Write `x` as 8 big-endian bytes.  With one argument returns a new byte\n  array.  With three arguments writes into `arr` at offset `i`.\"\n  ([^long x]\n   (long->bytes x (byte-array 8) 0))\n  ([^long x ^bytes arr ^long i]\n   (.putLong (ByteBuffer/wrap arr) (int i) x)\n   arr))\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Hexadecimal String Representation\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(defn octet-hex\n  \"Convert a single byte value to a two-character uppercase hex string.\"\n  [num]\n  (str\n    (+hex-chars+ (bit-shift-right num 4))\n    (+hex-chars+ (bit-and 0x0F num))))\n\n(defn hex\n  \"Convert a long or byte sequence to a hex string.\n  For a long, produces a 16-character zero-padded hex string.\"\n  [thing]\n  (if (number? thing)\n    (let [^bytes arr (long->bytes (clojure.core/long thing))\n          sb  (StringBuilder. 16)]\n      (dotimes [i 8]\n        (let [b (Byte/toUnsignedLong (aget arr (int i)))]\n          (.append sb ^char (+hex-chars+ (bit-shift-right b 4)))\n          (.append sb ^char (+hex-chars+ (bit-and 0x0F b)))))\n      (.toString sb))\n    (apply str (map octet-hex thing))))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; ByteBuffer Creation\n;;\n;; The central abstraction: a 16-byte big-endian ByteBuffer representing\n;; 128 bits of UUID data.  On the JVM this is java.nio.ByteBuffer; in a\n;; future cljc build this would map to DataView over an ArrayBuffer.\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(defn buffer\n  \"Create a 16-byte big-endian ByteBuffer.\n\n  0-arity:  zeroed buffer\n  2-arity:  from msb and lsb longs\n  The buffer uses absolute (position-independent) get/put operations.\"\n  (^ByteBuffer []\n   (ByteBuffer/allocate 16))\n  (^ByteBuffer [^long msb ^long lsb]\n   (doto (ByteBuffer/allocate 16)\n     (.putLong 0 msb)\n     (.putLong 8 lsb))))\n\n(defn buffer-from-bytes\n  \"Create a 16-byte ByteBuffer from a byte array (at least 16 bytes).\"\n  ^ByteBuffer\n  [^bytes arr]\n  (let [buf (ByteBuffer/allocate 16)\n        ^ByteBuffer src (ByteBuffer/wrap arr)]\n    (.putLong buf 0 (.getLong src 0))\n    (.putLong buf 8 (.getLong src 8))\n    buf))\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; ByteBuffer Typed Access\n;;\n;; Direct typed access at byte offsets.  All operations use absolute\n;; positions (no buffer position tracking).  Unsigned getter variants\n;; return longs to preserve full value range on the JVM.\n;;\n;; These map directly to DataView methods in JavaScript:\n;;   get-byte   -> DataView.getUint8\n;;   get-short  -> DataView.getUint16\n;;   get-int    -> DataView.getUint32\n;;   get-long   -> DataView.getBigInt64\n;;   put-byte   -> DataView.setUint8\n;;   put-short  -> DataView.setUint16\n;;   put-int    -> DataView.setUint32\n;;   put-long   -> DataView.setBigInt64\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(defn get-byte\n  \"Read an unsigned byte (0-255) at byte offset from buffer.\"\n  ^long [^ByteBuffer buf ^long offset]\n  (Byte/toUnsignedLong (.get buf (int offset))))\n\n(defn get-short\n  \"Read an unsigned 16-bit value at byte offset from buffer.\"\n  ^long [^ByteBuffer buf ^long offset]\n  (Short/toUnsignedLong (.getShort buf (int offset))))\n\n(defn get-int\n  \"Read an unsigned 32-bit value at byte offset from buffer.\"\n  ^long [^ByteBuffer buf ^long offset]\n  (Integer/toUnsignedLong (.getInt buf (int offset))))\n\n(defn get-long\n  \"Read a 64-bit long at byte offset from buffer.\"\n  ^long [^ByteBuffer buf ^long offset]\n  (.getLong buf (int offset)))\n\n(defn put-byte\n  \"Write a byte value at byte offset in buffer.  Returns the buffer.\"\n  ^ByteBuffer [^ByteBuffer buf ^long offset ^long val]\n  (doto buf (.put (int offset) (byte val))))\n\n(defn put-short\n  \"Write a 16-bit value at byte offset in buffer.  Returns the buffer.\"\n  ^ByteBuffer [^ByteBuffer buf ^long offset ^long val]\n  (doto buf (.putShort (int offset) (short val))))\n\n(defn put-int\n  \"Write a 32-bit value at byte offset in buffer.  Returns the buffer.\"\n  ^ByteBuffer [^ByteBuffer buf ^long offset ^long val]\n  (doto buf (.putInt (int offset) (int val))))\n\n(defn put-long\n  \"Write a 64-bit long at byte offset in buffer.  Returns the buffer.\"\n  ^ByteBuffer [^ByteBuffer buf ^long offset ^long val]\n  (doto buf (.putLong (int offset) val)))\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; ByteBuffer Word Access (MSB/LSB)\n;;\n;; Convenience accessors for the two 64-bit halves of a UUID buffer.\n;;   bytes 0-7:   most significant bits  (MSB)\n;;   bytes 8-15:  least significant bits (LSB)\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(defn get-msb\n  \"Read the most significant 64 bits (bytes 0-7) of a UUID buffer.\"\n  ^long [^ByteBuffer buf]\n  (.getLong buf 0))\n\n(defn get-lsb\n  \"Read the least significant 64 bits (bytes 8-15) of a UUID buffer.\"\n  ^long [^ByteBuffer buf]\n  (.getLong buf 8))\n\n(defn set-msb\n  \"Set the most significant 64 bits (bytes 0-7) of a UUID buffer.\n  Returns the buffer.\"\n  ^ByteBuffer [^ByteBuffer buf ^long val]\n  (doto buf (.putLong 0 val)))\n\n(defn set-lsb\n  \"Set the least significant 64 bits (bytes 8-15) of a UUID buffer.\n  Returns the buffer.\"\n  ^ByteBuffer [^ByteBuffer buf ^long val]\n  (doto buf (.putLong 8 val)))\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; ByteBuffer Bit Field Operations\n;;\n;; Buffer-aware ldb/dpb that operate on 64-bit words within the buffer.\n;; The word-offset identifies which 8-byte-aligned long to operate on:\n;;   0 = MSB (bytes 0-7)\n;;   8 = LSB (bytes 8-15)\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(defn ldb-buf\n  \"Load bit field: extract bits defined by `bitmask` from the 64-bit word\n  at `word-offset` in the buffer.\"\n  ^long [^ByteBuffer buf ^long word-offset ^long bitmask]\n  (ldb bitmask (.getLong buf (int word-offset))))\n\n(defn dpb-buf\n  \"Deposit bit field: insert `value` into the bits defined by `bitmask`\n  within the 64-bit word at `word-offset` in the buffer.  Mutates and\n  returns the buffer.\"\n  ^ByteBuffer [^ByteBuffer buf ^long word-offset ^long bitmask ^long value]\n  (let [current (.getLong buf (int word-offset))\n        updated (dpb bitmask current value)]\n    (doto buf (.putLong (int word-offset) updated))))\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; ByteBuffer Conversion\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(defn buf->bytes\n  \"Extract the contents of a 16-byte UUID buffer as a byte array.\"\n  ^bytes [^ByteBuffer buf]\n  (let [arr (byte-array 16)\n        ^ByteBuffer dest (ByteBuffer/wrap arr)]\n    (.putLong dest 0 (.getLong buf 0))\n    (.putLong dest 8 (.getLong buf 8))\n    arr))\n\n(defn buf->uuid\n  \"Convert a 16-byte UUID buffer to a java.util.UUID.\"\n  ^UUID [^ByteBuffer buf]\n  (UUID. (.getLong buf 0) (.getLong buf 8)))\n\n(defn uuid->buf\n  \"Convert a java.util.UUID to a 16-byte ByteBuffer.\"\n  ^ByteBuffer [^UUID uuid]\n  (buffer (.getMostSignificantBits uuid) (.getLeastSignificantBits uuid)))\n\n(defn duplicate\n  \"Create an independent copy of a UUID buffer.\"\n  ^ByteBuffer [^ByteBuffer buf]\n  (let [copy (ByteBuffer/allocate 16)]\n    (.putLong copy 0 (.getLong buf 0))\n    (.putLong copy 8 (.getLong buf 8))\n    copy))\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; ByteBuffer Hex and String Representation\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(defn- append-hex-bytes\n  \"Append hex characters for bytes [start, end) from buffer to StringBuilder.\"\n  [^StringBuilder sb ^ByteBuffer buf ^long start ^long end]\n  (loop [i start]\n    (when (< i end)\n      (let [b (Byte/toUnsignedLong (.get buf (int i)))]\n        (.append sb ^char (+hex-chars+ (bit-shift-right b 4)))\n        (.append sb ^char (+hex-chars+ (bit-and 0x0F b))))\n      (recur (inc i)))))\n\n(defn buf-hex\n  \"Convert a 16-byte UUID buffer to a 32-character hex string.\"\n  ^String [^ByteBuffer buf]\n  (let [sb (StringBuilder. 32)]\n    (append-hex-bytes sb buf 0 16)\n    (.toString sb)))\n\n(defn buf-str\n  \"Convert a 16-byte UUID buffer to the canonical 36-character UUID string:\n    xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n\n  Byte ranges correspond to UUID fields:\n    bytes 0-3:   time-low\n    bytes 4-5:   time-mid\n    bytes 6-7:   time-high-and-version\n    bytes 8-9:   clock-seq\n    bytes 10-15: node\"\n  ^String [^ByteBuffer buf]\n  (let [sb (StringBuilder. 36)]\n    (append-hex-bytes sb buf 0 4)\n    (.append sb \\-)\n    (append-hex-bytes sb buf 4 6)\n    (.append sb \\-)\n    (append-hex-bytes sb buf 6 8)\n    (.append sb \\-)\n    (append-hex-bytes sb buf 8 10)\n    (.append sb \\-)\n    (append-hex-bytes sb buf 10 16)\n    (.toString sb)))\n\n(defn hex->buf\n  \"Parse a 32-character hex string into a 16-byte UUID buffer.\"\n  ^ByteBuffer [^String s]\n  (let [buf (ByteBuffer/allocate 16)]\n    (dotimes [i 16]\n      (let [hi (Character/digit (.charAt s (int (* 2 i))) (int 16))\n            lo (Character/digit (.charAt s (int (inc (* 2 i)))) (int 16))]\n        (.put buf (int i)\n          (byte (bit-or (bit-shift-left hi 4) lo)))))\n    buf))\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; ByteBuffer Comparison\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(defn buf-compare\n  \"Lexicographic unsigned comparison of two 16-byte UUID buffers.\n  Returns negative if a < b, zero if equal, positive if a > b.\n  Comparison is unsigned (treats bytes as 0-255) which matches UUID\n  canonical string ordering.\"\n  ^long [^ByteBuffer a ^ByteBuffer b]\n  (let [c (Long/compareUnsigned (.getLong a 0) (.getLong b 0))]\n    (if (zero? c)\n      (clojure.core/long (Long/compareUnsigned (.getLong a 8) (.getLong b 8)))\n      (clojure.core/long c))))\n"
  },
  {
    "path": "src/clj_uuid/clock.clj",
    "content": "(ns clj-uuid.clock\n  \"Lock-Free, Thread-safe Monotonic Clocks\"\n  (:require [clj-uuid.random :as random])\n  (:import [java.util.concurrent.atomic AtomicLong]))\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Timestamp Epochs                       [RFC4122:4.1.4 \"TIMESTAMP\"] ;;\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;;\n;;   Universal time is represented as the number of seconds that have\n;;   elapsed since 00:00 January 1, 1900 GMT.\n;;\n;;   POSIX time is represented as the number of seconds that have\n;;   elapsed since 00:00 January 1, 1970 UTC\n;;\n;;   Java time is represented as the difference, measured in milliseconds,\n;;   between the current time and midnight, January 1, 1970 UTC\n;;\n;;   UUIDs use Gregorian epoch, 12am Friday October 15, 1582 UTC\n;;\n;;   Difference between Gregorian epoch and Java Epoch = 141427 days =\n;;   12219292800 seconds\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Clock Resolution       [RFC4122:4.2.1.2 \"SYSTEM CLOCK RESOLUTION\"] ;;\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;;\n;;   \"The timestamp is generated from the system time, whose resolution may\n;;   be less than the resolution of the UUID timestamp... If a system\n;;   overruns the generator by requesting too many UUIDs within a single\n;;   system time interval, the UUID service MUST... stall the UUID generator\n;;   until the system clock catches up.\n;;\n;;   A high resolution timestamp can be simulated by keeping a count of\n;;   the number of UUIDs that have been generated with the same value of\n;;   the system time, and using it to construct the low order bits of the\n;;   timestamp.  The count will range between zero and the number of\n;;   100-nanosecond intervals per system time interval.\"\n;;\n;; We implement this general theory of operation, but make use of Clojure's\n;; native lock-free concurrency primatives in order to ensure thread safety.\n;; The system time is adjusted to achieve the rfc4122 gregorian timestamp and\n;; and combined with the value read from a lock-free, atomic\n;; incremental timestamps-this-tick subcounter on the low order bits.\n;; This ensures no two monotonic timestamps ever collide, regardless of\n;; system clock precision or degree of concurrency:\n;;\n;; 113914335216380000  (+ (* (universal-time) 10000) 100103040000000000)\n;; 113914335216380001  first contending timestamp\n;; 113914335216380002  second contending timestamp\n;; ...                 and so forth\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(deftype State [^long seqid ^long millis])\n\n(def ^:const +subcounter-resolution+     9999)\n\n(def ^AtomicLong -gregorian-packed- (AtomicLong. 0))\n\n(defn monotonic-time\n  \"Generate a guaranteed monotonically increasing timestamp based on\n   Gregorian time and a stateful subcounter\"\n  []\n  (loop []\n    (let [current  (.get -gregorian-packed-)\n          millis   (unsigned-bit-shift-right current 14)\n          time-now (System/currentTimeMillis)]\n      (cond\n        (< millis time-now)\n        (let [next (bit-shift-left time-now 14)]\n          (if (.compareAndSet -gregorian-packed- current next)\n            (+ 100103040000000000\n               (* (+ 2208988800000 time-now) 10000))\n            (recur)))\n\n        (> millis time-now)\n        (recur)\n\n        true\n        (let [seqid (bit-and current 0x3FFF)\n              tt    (inc seqid)]\n          (if (<= tt +subcounter-resolution+)\n            (let [next (bit-or (bit-shift-left time-now 14) tt)]\n              (if (.compareAndSet -gregorian-packed- current next)\n                (+ tt 100103040000000000\n                   (* (+ 2208988800000 time-now) 10000))\n                (recur)))\n            (recur)))))))\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Monotonicity and Counters       [RFC9562:6.2.2 \"Monotonic Random\"] ;;\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;;\n;;   \"With this method, the random data is extended to also function as\n;;   a counter. This monotonic value can be thought of as a \"randomly\n;;   seeded counter\" that MUST be incremented in the least significant\n;;   position for each UUID created on a given timestamp tick. UUIDv7's\n;;   rand_b section SHOULD be utilized with this method to handle batch\n;;   UUID generation during a single timestamp tick. The increment value\n;;   for every UUID generation is a random integer of any desired length\n;;   larger than zero. It ensures that the UUIDs retain the required level\n;;   of unguessability provided by the underlying entropy. The increment\n;;   value MAY be 1 when the number of UUIDs generated in a particular\n;;   period of time is important\"\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(def ^:const +random-counter-resolution+ 0xfff)\n\n(let [^AtomicLong -packed- (AtomicLong. 0)]\n  (defn monotonic-unix-time-and-random-counter\n    \"Generate guaranteed monotonically increasing number pairs based on\n     POSIX time and a randomly seeded subcounter\"\n    []\n    (loop []\n      (let [current  (.get -packed-)\n            millis   (unsigned-bit-shift-right current 14)\n            time-now (System/currentTimeMillis)]\n        (cond\n          (< millis time-now)\n          (let [new-seqid (random/ten-bits)\n                next      (bit-or (bit-shift-left time-now 14) new-seqid)]\n            (if (.compareAndSet -packed- current next)\n              (->State new-seqid time-now)\n              (recur)))\n\n          (> millis time-now)\n          (recur)\n\n          true\n          (let [seqid (bit-and current 0x3FFF)\n                tt    (inc seqid)]\n            (if (<= tt +random-counter-resolution+)\n              (let [next (bit-or (bit-shift-left time-now 14) tt)]\n                (if (.compareAndSet -packed- current next)\n                  (->State tt time-now)\n                  (recur)))\n              (recur))))))))\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Time Utilities\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(defn posix-time\n  \"Generate the (Unix compatible) POSIX time -- the number of seconds\n  that have elapsed since 00:00 January 1, 1970 UTC\"\n  ([]\n   (posix-time (System/currentTimeMillis)))\n  ([^long gregorian]\n   (- (quot gregorian 10000) 12219292800000)))\n\n(defn universal-time\n  \"Generate the (Common-Lisp compatible) universal-time -- the number of\n  seconds that have elapsed since 00:00 January 1, 1900 GMT\"\n  ([]\n   (universal-time (monotonic-time)))\n  ([^long gregorian]\n   (+ (posix-time gregorian) 2208988800)))\n"
  },
  {
    "path": "src/clj_uuid/constants.clj",
    "content": "(ns clj-uuid.constants)\n\n\n(def +md5+  \"MD5\")\n(def +sha1+ \"SHA1\")\n\n\n(def uuid-regex  #\"[0-9A-Fa-f]{8}(-[0-9A-Fa-f]{4}){3}-[0-9A-Fa-f]{12}\")\n(def hex-regex   #\"[0-9A-Fa-f]{32}\")\n(def urn-regex   #\"urn:uuid:[0-9A-Fa-f]{8}(-[0-9A-Fa-f]{4}){3}-[0-9A-Fa-f]{12}\")\n\n(def +hex-chars+ [\\0 \\1 \\2 \\3 \\4 \\5 \\6 \\7 \\8 \\9 \\A \\B \\C \\D \\E \\F])\n\n(def ^:const +ub63-mask+ 0x7fffffffffffffff)\n(def ^:const +ub60-mask+ 0x0fffffffffffffff)\n(def ^:const +ub56-mask+ 0x00ffffffffffffff)\n(def ^:const +ub48-mask+ 0x0000ffffffffffff)\n(def ^:const +ub40-mask+ 0x000000ffffffffff)\n(def ^:const +ub32-mask+ 0x00000000ffffffff)\n(def ^:const +ub24-mask+ 0x0000000000ffffff)\n(def ^:const +ub16-mask+ 0x000000000000ffff)\n(def ^:const +ub12-mask+ 0x0000000000000fff)\n(def ^:const +ub8-mask+  0x00000000000000ff)\n(def ^:const +ub4-mask+  0x000000000000000f)\n(def ^:const +ub1-mask+  0x0000000000000001)\n"
  },
  {
    "path": "src/clj_uuid/core.clj",
    "content": "(ns clj-uuid.core\n  (:refer-clojure :exclude [== uuid? max < > =])\n  (:require [clojure.core :as clojure]\n            [clj-uuid\n             [constants :refer :all]\n             [util      :as util]\n             [bitmop    :as bitmop]\n             [clock     :as clock]\n             [node      :as node]\n             [random    :as random]])\n  (:import [java.io       ByteArrayOutputStream\n                          ObjectOutputStream]\n           [java.lang IllegalArgumentException]\n           [java.net      URI URL]\n           [java.nio      ByteBuffer]\n           [java.security MessageDigest]\n           [java.util     UUID Date]))\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Leach-Salz UUID Representation     [RFC4122:4.1.2 \"LAYOUT AND BYTE ORDER\"] ;;\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;;\n;; The string representation of A Leach-Salz UUID has the format:\n;;\n;;                                          clock-seq-and-reserved\n;;                                time-mid  | clock-seq-low\n;;                                |         | |\n;;                       6ba7b810-9dad-11d1-80b4-00c04fd430c8\n;;                       |             |         |\n;;                       ` time-low    |         ` node\n;;                                     ` time-high-and-version\n;;\n;;\n;; Each field is treated as integer and has its value printed as a zero-filled\n;; hexadecimal digit string with the most significant digit first (unsigned,\n;; big-endian).\n;;\n;; 0                   1                   2                   3\n;;  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n;; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n;; |                        %uuid_time-low                         |\n;; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n;; |       %uuid_time-mid          |  %uuid_time-high-and-version  |\n;; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n;; |clk-seq-hi-res | clock-seq-low |         %uuid_node (0-1)      |\n;; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n;; |                         %uuid_node (2-5)                      |\n;; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n;;\n;;\n;;  The following table enumerates a slot/type/value correspondence:\n;;\n;;   SLOT       SIZE   TYPE        BYTE-ARRAY\n;;  ----------------------------------------------------------------------\n;;  time-low       4   ub32     [<BYTE> <BYTE> <BYTE> <BYTE>]\n;;  time-mid       2   ub16     [<BYTE> <BYTE>]\n;;  time-high      2   ub16     [<BYTE> <BYTE>]\n;;  clock-high     1    ub8     [<BYTE>]\n;;  clock-low      1    ub8     [<BYTE>]\n;;  node           6   ub48     [<BYTE> <BYTE> <BYTE> <BYTE> <BYTE> <BYTE>]\n;;\n;; Or, as 8-bit bytes mapping into 128-bit unsigned integer values:\n;;\n;;  (0 7)   (8 15)  (16 23) (24 31)  ;; time-low\n;;  (32 39) (40 47)                  ;; time-mid\n;;  (48 55) (56 63)                  ;; time-high-and-version\n;;\n;;  (64 71)                          ;; clock-seq-and-reserved\n;;  (72 79)                          ;; clock-seq-low\n;;  (80 87)   (88 95)   (96 103)     ;;\n;;  (104 111) (112 119) (120 127)    ;; node\n;;\n;; This has been updated with additional layouts.  See RFC9562:5.7 and\n;; the description of v7 UUIDs, below.\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; UUID Variant                                                 [RFC9562:4.1] ;;\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;;\n;; The variant indicates the layout of the UUID. The UUID specification\n;; covers one particular variant. Other variants are reserved or exist\n;; for backward compatibility reasons (e.g., for values assigned before\n;; the UUID specification was produced). An example of a UUID that is a\n;; different variant is the null UUID, which is a UUID that has all 128\n;; bits set to zero.\n;;\n;; In the canonical representation:\n;;\n;;    xxxxxxxx-xxxx-xxxx-Nxxx-xxxxxxxxxxxx\n;;\n;; the most significant bits of N indicate the variant (depending on the\n;; variant one, two, or three bits are used). The principal variants covered\n;; by the RFC9562 are indicated by the two most significant bits of N being 1 0\n;; (i.e., the hexadecimal N will always be 8, 9, A, or B).  As seen below,\n;; there are two additional variants, currently used for special \"sentinal\"\n;; UUID's as defined below.\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; UUID Version                                                 [RFC9562:4.2] ;;\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;;\n;; The Leach-Salz UUID variant has five defined versions. In the canonical\n;; representation:\n;;\n;;    xxxxxxxx-xxxx-Mxxx-xxxx-xxxxxxxxxxxx\n;;\n;; the four bits of M indicates the UUID version (i.e., the hexadecimal\n;; digit M will be either 1, 2, 3, 4, 5, 6, 7, or 8).\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; The NULL (variant 0) UUID                                    [RFC9562:5.9] ;;\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(def ^:const +null+\n  \"The NULL UUID is a special form of sentinel UUID that is specified to have\n   all 128 bits set to zero.\"\n  #uuid \"00000000-0000-0000-0000-000000000000\")\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; The MAX (variant 7) UUID                                    [RFC9562:5.10] ;;\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(def ^:const +max+\n  \"The MAX UUID is a special form of sentinel UUID that is specified to have\n   all 128 bits set to one.\"\n  #uuid \"FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF\")\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Well-Known UUIDs                 [RFC4122:Appendix-C \"SOME NAMESPACE IDs\"] ;;\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n;; The following UUID's are the canonical top-level namespace identifiers\n;; defined in RFC9562 Appendix C.\n\n(def ^:const +namespace-dns+  #uuid \"6ba7b810-9dad-11d1-80b4-00c04fd430c8\")\n(def ^:const +namespace-url+  #uuid \"6ba7b811-9dad-11d1-80b4-00c04fd430c8\")\n(def ^:const +namespace-oid+  #uuid \"6ba7b812-9dad-11d1-80b4-00c04fd430c8\")\n(def ^:const +namespace-x500+ #uuid \"6ba7b814-9dad-11d1-80b4-00c04fd430c8\")\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Monotonic Clock (guaranteed always increasing value for time)\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(defn monotonic-time\n \"Return a monotonic timestamp (guaranteed always increasing) based on\n the number of 100-nanosecond intervals elapsed since the adoption of\n the Gregorian calendar in the West, 12:00am Friday October 15, 1582 UTC.\"\n []\n (clock/monotonic-time))\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; UUID Protocols\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(defprotocol UUIDNameBytes\n  \"A mechanism intended for user-level extension that defines the\n  decoding rules for the local-part representation of arbitrary\n  Clojure / Java Objects when used for computing namespaced\n  identifiers.\"\n\n  (as-byte-array [x]\n    \"Extract a byte serialization that represents the 'name' of x,\n    typically unique within a given namespace.\"))\n\n(defprotocol UUIDable\n  \"A UUIDable object directly represents a UUID.  Examples of things which\n  might be conceptually 'uuidable' include string representation of a\n  UUID in canonical hex format, or an appropriate URN URI.\"\n\n  (as-uuid   ^java.util.UUID [x]\n    \"Coerce the value 'x' to a UUID.\")\n\n  (uuidable?                 [x]\n    \"Return 'true' if 'x' can be coerced to UUID.\"))\n\n;; (defprotocol UUIDRfc9562\n;;   \"A protocol that abstracts an unique identifier as described by\n;;   IETF RFC9562 <http://www.ietf.org/rfc/rfc9562.txt>. A UUID\n;;   represents a 128-bit value, however there are variant encoding\n;;   layouts used to assign and interpret information encoded in\n;;   those bits.  This is a protocol for  _variant 2_ (*Leach-Salz*)\n;;   UUID's.\"\n\n;;   (hash-code                     [uuid])\n;;   (null?                         [uuid])\n;;   (max?                         [uuid])\n;;   (uuid?                         [x])\n;;   (uuid=                         [x y])\n;;   (uuid<                         [x y])\n;;   (uuid>                         [x y])\n;;   (get-word-high                 [uuid])\n;;   (get-word-low                  [uuid])\n;;   (get-version                   [uuid])\n;;   (get-variant                   [uuid])\n;;   (get-time-low                  [uuid])\n;;   (get-time-mid                  [uuid])\n;;   (get-time-high                 [uuid])\n;;   (get-clk-high                  [uuid])\n;;   (get-clk-low                   [uuid])\n;;   (get-clk-seq                   [uuid])\n;;   (get-node-id                   [uuid])\n;;   (get-timestamp                 [uuid])\n;;   (get-instant   ^java.util.Date [uuid])\n;;   (get-unix-time                 [uuid])\n;;   (to-byte-array                 [uuid])\n;;   (to-string     ^String         [uuid])\n;;   (to-hex-string ^String         [uuid])\n;;   (to-urn-string ^String         [uuid])\n;;   (to-uri        ^java.net.URI   [uuid]))\n\n(defprotocol UUIDRfc9562\n  \"A protocol that abstracts an unique identifier as described by\n  IETF RFC9562 <http://www.ietf.org/rfc/rfc9562.txt>. A UUID\n  represents a 128-bit value, however there are variant encoding\n  layouts used to assign and interpret information encoded in\n  those bits.  This is a protocol for  _variant 2_ (*Leach-Salz*)\n  UUID's.\"\n\n  (hash-code                     [uuid]\n    \"Return a suitable 64-bit hash value for `uuid`.  Extend with\n    specialized hash computation.\")\n\n  (null?                         [uuid]\n    \"Return `true` only if `uuid` has all 128 bits set to zero and is\n    therefore equal to the null UUID, 00000000-0000-0000-0000-000000000000.\")\n\n  (max?                         [uuid]\n    \"Return `true` only if `uuid` has all 128 bits set and is\n    therefore equal to the maximum UUID, ffffffff-ffff-ffff-ffff-ffffffffffff.\")\n\n  (uuid?                         [x]\n    \"Return `true` if `x` implements an RFC9562 unique identifier.\")\n\n  (uuid=                         [x y]\n    \"Directly compare two UUID's for = relation based on the equality\n    semantics defined by [RFC4122:3 RULES FOR LEXICAL EQUIVALENCE].\n    See: `clj-uuid/=`\")\n\n  (uuid<                         [x y]\n    \"Directly compare two UUID's for < relation based on the ordinality\n    semantics defined by [RFC4122:3 RULES FOR LEXICAL EQUIVALENCE].\n    See: `clj-uuid/<`\")\n\n  (uuid>                         [x y]\n    \"Directly compare two UUID's for > relation based on the ordinality\n    semantics defined by [RFC4122:3 RULES FOR LEXICAL EQUIVALENCE].\n    See: `clj-uuid/>`\")\n\n  (get-word-high                 [uuid]\n    \"Return the most significant 64 bits of UUID's 128 bit value.\")\n\n  (get-word-low                  [uuid]\n    \"Return the least significant 64 bits of UUID's 128 bit value.\")\n\n  (get-version                   [uuid]\n    \"Return the version number associated with this UUID.  The version\n    field contains a value which describes the nature of the UUID.  There\n    are five versions of Leach-Salz UUID, plus the null and max UUIDs:\n\n    0x0   Null\n    0x1   Time based\n    0x2   DCE security with POSIX UID\n    0x3   Namespaced, deterministic (MD5 Digest)\n    0x4   Cryptographic random\n    0x5   Namespaced, deterministic (SHA1 Digest)\n    0x6   Time based, lexically ordered\n    0x7   POSIX Time based, lexically ordered, cryptographically secure\n    0x8   User Customizable\n    0xF   Max\n\n    In the canonical representation, xxxxxxxx-xxxx-Mxxx-xxxx-xxxxxxxxxxxx,\n    the four bits of M indicate the UUID version (i.e., the hexadecimal M\n    will be either 1, 2, 3, 4, 5, 6, 7, or 8).\")\n\n  (get-variant                   [uuid]\n    \"Return the variant number associated with this UUID.  The variant field\n    contains a value which identifies the layout of the UUID.  The bit-layout\n    implemented by this protocol supports UUID's with a variant value of 0x2,\n    which indicates Leach-Salz layout.  Defined UUID variant values are:\n\n    0x0   Null\n    0x2   Leach-Salz\n    0x6   Microsoft\n    0x7   Max\n\n    In the canonical representation, xxxxxxxx-xxxx-xxxx-Nxxx-xxxxxxxxxxxx,\n    the most significant bits of N indicate the variant (depending on the\n    variant one, two, or three bits are used). The variant covered by RFC9562\n    is indicated by the two most significant bits of N being 1 0 (i.e., the\n    hexadecimal N will always be 8, 9, A, or B).\")\n\n  (get-time-low                  [uuid]\n    \"Return the 32 bit unsigned value that represents the `time-low` field\n    of the `timestamp` associated with this UUID.\")\n\n  (get-time-mid                  [uuid]\n    \"Return the 16 bit unsigned value that represents the `time-mid` field\n    of the `timestamp` associated with this UUID.\")\n\n  (get-time-high                 [uuid]\n    \"Return the 16 bit unsigned value that represents the `time-high` field\n    of the `timestamp` multiplexed with the `version` of this UUID.\")\n\n  (get-clk-high                  [uuid]\n    \"Return the 8 bit unsigned value that represents the most significant\n    byte of the `clk-seq` multiplexed with the `variant` of this UUID.\")\n\n  (get-clk-low                   [uuid]\n    \"Return the 8 bit unsigned value that represents the least significant\n    byte of the `clk-seq` associated with this UUID.\")\n\n  (get-clk-seq                   [uuid]\n    \"Return the clock-sequence number associated with this UUID. For time-based\n    (v1, v6) UUID's the 'clock-sequence' value is a somewhat counter-intuitively\n    named seed-value that is used to reduce the potential that duplicate UUID's\n    might be generated under unusual situations, such as if the system hardware\n    clock is set backward in time or if, despite all efforts otherwise, a\n    duplicate node-id happens to be generated. This value is initialized to\n    a random 16-bit number once per lifetime of the system.  For\n    non-gregorian-time-based (v3, v4, v5, v7, v8, squuid) UUID's, always\n    returns `nil`.\")\n\n  (get-node-id                   [uuid]\n    \"Return the 48 bit unsigned value that represents the spatially unique\n    node identifier associated with this UUID.\")\n\n  (get-timestamp                 [uuid]\n    \"Return the time of UUID creation.  For Gregorian time-based (v1,\n    v6) UUID's, this is 60 bit unsigned value that represents a\n    temporally unique timestamp associated with this UUID.  The result\n    encodes the number of 100 nanosecond intervals since the adoption of\n    the Gregorian calendar.  For v7 UUID's this encodes the more common\n    unix time in milliseconds since midnight, January 1, 1970 UTC.  For\n    non-time-based (v3, v4, v5, v8, squuid) UUID's, always returns\n    `nil`.\")\n\n  (get-instant   ^java.util.Date [uuid]\n    \"For time-based (v1, v6, v7) UUID's, return a java.util.Date\n    object that represents the system time at which this UUID was\n    generated. NOTE: the returned value may not necessarily be\n    temporally unique. For non-time-based\n    (v3, v4, v5, v8, squuid) UUID's, always returns `nil`.\")\n\n  (get-unix-time                 [uuid]\n    \"For time-based (v1, v6, v7) UUIDs return the timestamp portion in\n    approximately milliseconds since the Unix epoch 1970-01-01T00:00:00.000Z.\n    For non-time-based (v3, v4, v5, v8, squuid) UUID's, always returns `nil`.\")\n\n  (to-byte-array                 [uuid]\n    \"Return an array of 16 bytes that represents `uuid` as a decomposed\n    octet serialization encoded in most-significant-byte first order.\")\n\n  (to-string     ^String         [uuid]\n    \"Return a String object that represents `uuid` in the canonical\n    36 character hex-string format:\n\n        xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\")\n\n  (to-hex-string ^String         [uuid]\n    \"Return a String object that represents `uuid` as the 32 hexadecimal\n    characters directly encodong the UUID's 128 bit value:\n\n        xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\")\n\n  (to-urn-string ^String         [uuid]\n    \"Return a String object that represents `uuid` as a the string\n    serialization of the URN URI based on the canonical 36 character\n    hex-string representation:\n\n        urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\")\n\n  (to-uri        ^java.net.URI   [uuid]\n    \"Return the unique URN URI associated with this UUID.\"))\n\n;; For backwards compatibility\n\n(def UUIDRfc4122 UUIDRfc9562)\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; RFC9562 Unique Identifier extended java.util.UUID\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(extend-type UUID\n\n  UUIDable\n\n  (as-uuid   [u] u)\n  (uuidable? [_] true)\n\n  UUIDRfc9562\n\n  (uuid? ^boolean [_] true)\n\n  (uuid= ^boolean [^UUID x ^UUID y]\n    (.equals x y))\n\n  (uuid< ^boolean [^UUID x ^UUID y]\n    (let [xh (.getMostSignificantBits x)\n          yh (.getMostSignificantBits y)]\n      (or (clojure/< xh yh)\n          (and (clojure/= xh yh) (clojure/< (.getLeastSignificantBits x)\n                                            (.getLeastSignificantBits y))))))\n\n  (uuid> ^boolean [^UUID x ^UUID y]\n    (let [xh (.getMostSignificantBits x)\n          yh (.getMostSignificantBits y)]\n      (or (clojure/> xh yh)\n          (and (clojure/= xh yh) (clojure/> (.getLeastSignificantBits x)\n                                            (.getLeastSignificantBits y))))))\n\n  (get-word-high ^long [uuid]\n    (.getMostSignificantBits uuid))\n\n  (get-word-low ^long [uuid]\n    (.getLeastSignificantBits uuid))\n\n  (null? ^boolean [uuid]\n    (clojure/= 0 (.getMostSignificantBits uuid) (.getLeastSignificantBits uuid)))\n\n  (max? ^boolean [uuid]\n    (uuid= uuid +max+))\n\n  ;; two putLong calls (one per word) instead of bitmop's\n  ;; 16-iteration loop of ldb+sb8 per byte.\n  (to-byte-array ^bytes [uuid]\n    (let [arr (byte-array 16)]\n      (bitmop/long->bytes (.getMostSignificantBits  uuid) arr 0)\n      (bitmop/long->bytes (.getLeastSignificantBits uuid) arr 8)\n      arr))\n\n  (hash-code ^long [uuid]\n    (long (.hashCode uuid)))\n\n  (get-version ^int [uuid]\n    (.version uuid))\n\n  (get-variant ^int [uuid]\n    (.variant uuid))\n\n  (to-string [uuid]\n    (.toString uuid))\n\n  (to-urn-string [uuid]\n    (str \"urn:uuid:\" (.toString uuid)))\n\n  ;; buf-hex renders all 32 hex chars via a single StringBuilder\n  ;; from a ByteBuffer, instead of two separate hex() calls + string concat.\n\n  (to-hex-string [uuid]\n    (bitmop/buf-hex (bitmop/uuid->buf uuid)))\n\n  (to-uri [uuid]\n    (URI/create (to-urn-string uuid)))\n\n  (get-time-low ^long [uuid]\n    (let [msb (.getMostSignificantBits uuid)]\n      (if (clojure/= 6 (get-version uuid))\n        (bitmop/ldb #=(bitmop/mask 16 0) msb)\n        (bitmop/ldb #=(bitmop/mask 32 0) (bit-shift-right msb 32)))))\n\n  (get-time-mid ^long [uuid]\n    (bitmop/ldb #=(bitmop/mask 16 16)\n      (.getMostSignificantBits uuid)))\n\n  (get-time-high ^long [uuid]\n    (let [msb (.getMostSignificantBits uuid)]\n      (if (clojure/= 6 (get-version uuid))\n        (bitmop/ldb #=(bitmop/mask 32 0) (bit-shift-right msb 32))\n        (bitmop/ldb #=(bitmop/mask 16 0) msb))))\n\n  (get-clk-low ^long [uuid]\n    (bitmop/ldb #=(bitmop/mask 8 0)\n      (bit-shift-right (.getLeastSignificantBits uuid) 56)))\n\n  (get-clk-high ^long [uuid]\n    (bitmop/ldb #=(bitmop/mask 8 48)\n      (.getLeastSignificantBits uuid)))\n\n  (get-clk-seq ^short [uuid]\n    (when (#{1 6} (.version uuid))\n      (bitmop/ldb #=(bitmop/mask 14 48) (.getLeastSignificantBits uuid))))\n\n  (get-node-id ^long [uuid]\n    (bitmop/ldb #=(bitmop/mask 48 0)\n      (.getLeastSignificantBits uuid)))\n\n  (get-timestamp ^long [uuid]\n    (case (.version uuid)\n      1 (.timestamp uuid)\n      6 (bit-or (bitmop/ldb #=(bitmop/mask 12 0)\n                            (.getMostSignificantBits uuid))\n                (bit-shift-left (get-time-mid uuid) 12)\n                (bit-shift-left (get-time-high uuid) 28))\n      7 (bitmop/ldb #=(bitmop/mask 48 16) (.getMostSignificantBits uuid))\n      nil))\n\n  (get-unix-time ^long [uuid]\n    (case (.version uuid)\n      (1 6) (clock/posix-time (get-timestamp uuid))\n      7     (get-timestamp uuid)\n      nil))\n\n  (get-instant [uuid]\n    (when-let [ts (get-unix-time uuid)]\n      (Date. (long ts))))\n\n  UUIDNameBytes\n\n  (as-byte-array\n    ^bytes\n    [this]\n    (to-byte-array this)))\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; V0 UUID Constructor                                          [RFC9562:5.9] ;;\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(defn null\n  \"Generates the v0 (null) UUID, 00000000-0000-0000-0000-000000000000.\"\n  ^java.util.UUID\n  []\n  +null+)\n\n(defn v0\n  \"Generates the v0 (null) UUID, 00000000-0000-0000-0000-000000000000.\"\n  ^java.util.UUID\n  []\n  +null+)\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; The MAX UUID Constructor                                    [RFC9562:5.10] ;;\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(defn max\n  \"Generates the v15 (maximum) UUID, ffffffff-ffff-ffff-ffff-ffffffffffff.\"\n  ^java.util.UUID\n  []\n  +max+)\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; V1, V6 (time-coded) UUID Constructors                   [RFC9562:5.1, 5.6] ;;\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n;; Concatenate the UUID version with a unique per-node identifier (the\n;; MAC address of the computer that is generating the UUID, or securely\n;; generated once-per-session random identifier) and with a monotonic\n;; timestamp based on the number of 100-nanosecond intervals since the\n;; adoption of the Gregorian calendar in the West, 12:00am Friday\n;; October 15, 1582 UTC.\n\n(let [^java.util.concurrent.atomic.AtomicLong packed clock/-gregorian-packed-\n      subcounter-max clock/+subcounter-resolution+\n      v1-lsb        (long node/+v1-lsb+)\n      v6-lsb        (long node/+v6-lsb+)]\n\n  (defn v1\n    \"Generate a v1 (time-based) unique identifier, guaranteed to be unique\n  and thread-safe regardless of clock precision or degree of concurrency.\n  Creation of v1 UUID's does not require any call to a cryptographic\n  generator and can be accomplished much more efficiently than v3, v4, v5, v7,\n  or squuid's.  A v1 UUID reveals both the identity of the computer that\n  generated the UUID and the time at which it did so.  Its uniqueness across\n  computers is guaranteed as long as MAC addresses are not duplicated.\"\n    ^java.util.UUID\n    []\n    (loop []\n      (let [current  (.get packed)\n            millis   (unsigned-bit-shift-right current 14)\n            time-now (System/currentTimeMillis)]\n        (cond\n          (clojure/< millis time-now)\n          (let [next (bit-shift-left time-now 14)]\n            (if (.compareAndSet packed current next)\n              (let [ts  (+ 100103040000000000\n                           (* (+ 2208988800000 time-now) 10000))\n                    msb (bit-or\n                          (bit-shift-left (bit-and ts 0xFFFFFFFF) 32)\n                          (bit-shift-left (bit-and (unsigned-bit-shift-right ts 32) 0xFFFF) 16)\n                          0x1000\n                          (bit-and (unsigned-bit-shift-right ts 48) 0xFFF))]\n                (UUID. msb v1-lsb))\n              (recur)))\n\n          (clojure/> millis time-now)\n          (recur)\n\n          true\n          (let [seqid (bit-and current 0x3FFF)\n                tt    (inc seqid)]\n            (if (<= tt subcounter-max)\n              (let [next (bit-or (bit-shift-left time-now 14) tt)]\n                (if (.compareAndSet packed current next)\n                  (let [ts  (+ tt 100103040000000000\n                               (* (+ 2208988800000 time-now) 10000))\n                        msb (bit-or\n                              (bit-shift-left (bit-and ts 0xFFFFFFFF) 32)\n                              (bit-shift-left (bit-and (unsigned-bit-shift-right ts 32) 0xFFFF) 16)\n                              0x1000\n                              (bit-and (unsigned-bit-shift-right ts 48) 0xFFF))]\n                    (UUID. msb v1-lsb))\n                  (recur)))\n              (recur)))))))\n\n  (defn v6\n    \"Generate a v6 (time-based), LEXICALLY SORTABLE, unique identifier,\n  v6 is a field-compatible version of v1, reordered for improved DB\n  locality.  Creation of v6 UUID's does not require any call to a\n  cryptographic generator and can be accomplished much more efficiently\n  than v3, v4, v5, v7, or squuid's.  A v6 UUID uses a cryptographically\n  secure, hard to guess random node id. It DOES NOT reveal the identity\n  of the computer on which it was created.\"\n    ^java.util.UUID\n    []\n    (loop []\n      (let [current  (.get packed)\n            millis   (unsigned-bit-shift-right current 14)\n            time-now (System/currentTimeMillis)]\n        (cond\n          (clojure/< millis time-now)\n          (let [next (bit-shift-left time-now 14)]\n            (if (.compareAndSet packed current next)\n              (let [ts  (+ 100103040000000000\n                           (* (+ 2208988800000 time-now) 10000))\n                    msb (bit-or\n                          (bit-shift-left (bit-and (unsigned-bit-shift-right ts 28) 0xFFFFFFFF) 32)\n                          (bit-shift-left (bit-and (unsigned-bit-shift-right ts 12) 0xFFFF) 16)\n                          0x6000\n                          (bit-and ts 0xFFF))]\n                (UUID. msb v6-lsb))\n              (recur)))\n\n          (clojure/> millis time-now)\n          (recur)\n\n          true\n          (let [seqid (bit-and current 0x3FFF)\n                tt    (inc seqid)]\n            (if (<= tt subcounter-max)\n              (let [next (bit-or (bit-shift-left time-now 14) tt)]\n                (if (.compareAndSet packed current next)\n                  (let [ts  (+ tt 100103040000000000\n                               (* (+ 2208988800000 time-now) 10000))\n                        msb (bit-or\n                              (bit-shift-left (bit-and (unsigned-bit-shift-right ts 28) 0xFFFFFFFF) 32)\n                              (bit-shift-left (bit-and (unsigned-bit-shift-right ts 12) 0xFFFF) 16)\n                              0x6000\n                              (bit-and ts 0xFFF))]\n                    (UUID. msb v6-lsb))\n                  (recur)))\n              (recur))))))))\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; V7 (crypto secure, posix time-coded) UUID Constructor        [RFC9562:5.7] ;;\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;;\n;;  0                   1                   2                   3\n;;  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n;; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n;; |                           unix_ts_ms                          |\n;; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n;; |          unix_ts_ms           |  ver  |       rand_a          |\n;; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n;; |var|                        rand_b                             |\n;; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n;; |                            rand_b                             |\n;; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\n;;  The following table enumerates a slot/type/value correspondence:\n;;\n;;   SLOT       SIZE      Description\n;;  ----------------------------------------------------------------------\n;;  unix_ts_ms   6 bytes  POSIX millis timestamp\n;;  ver          4 bits   version, set to 0b0111 (7)\n;;  rand_a      12 bits   randomly initialized subcounter\n;;  var          2 bits   variant, set to 0b10 (2)\n;;  rand_b      62 bits   cryptographically secure pseudorandom data\n\n(defn v7\n  \"Generate a v7 unix time-based, LEXICALLY SORTABLE UUID with monotonic\n  counter and cryptographically secure random portion and POSIX time encoding.\n  As such, creation of v7 UUIDs may be significantly slower, but have improved\n  entropy chararacteristics compared to v1 or v6 UUIDs.\"\n  ^java.util.UUID\n  []\n  (let [^clj_uuid.clock.State state (clock/monotonic-unix-time-and-random-counter)\n        time            (bitmop/ldb #=(bitmop/mask 48  0) (.millis state))\n        ver-and-counter (bitmop/dpb #=(bitmop/mask 4  12) (.seqid state) 0x7)\n        msb             (bit-or ver-and-counter (bit-shift-left time 16))\n        lsb             (bitmop/dpb #=(bitmop/mask 2 62) (random/long) 0x2)]\n    (UUID. msb lsb)))\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; V7nc (non-cryptographic V7) UUID Constructor                              ;;\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(let [^ThreadLocal v7nc-tl\n      (ThreadLocal/withInitial\n        (reify java.util.function.Supplier\n          (get [_] (long-array 3))))]\n  (defn v7nc\n    \"Generate a v7 UUID using non-cryptographic randomness (ThreadLocalRandom).\n  Produces valid RFC 9562 v7 UUIDs with the same timestamp/version/variant\n  structure as v7, but uses java.util.concurrent.ThreadLocalRandom instead\n  of SecureRandom and a per-thread monotonic counter instead of a global\n  AtomicLong.  This trades cryptographic unguessability for significantly\n  higher throughput -- comparable to JUG's TimeBasedEpochGenerator.\n\n  The per-thread counter uses rand_a (12 bits) as a fixed seed per\n  millisecond and rand_b (62 bits) as a strictly increasing counter,\n  giving 2^62 UUIDs per millisecond per thread before overflow.\"\n    ^java.util.UUID\n    []\n    (let [^longs state (.get v7nc-tl)\n          ^java.util.concurrent.ThreadLocalRandom tlr\n          (java.util.concurrent.ThreadLocalRandom/current)]\n      (loop []\n        (let [time-now (System/currentTimeMillis)\n              last-ms  (aget state 0)]\n          (cond\n            (clojure/> time-now last-ms)\n            (let [lsb-ctr (bit-and (.nextLong tlr) 0x3FFFFFFFFFFFFFFF)\n                  msb     (bit-or (bit-shift-left (bit-and time-now 0xFFFFFFFFFFFF) 16)\n                                  (bit-or 0x7000 (bit-and (.nextLong tlr) 0xFFF)))]\n              (aset state 0 time-now)\n              (aset state 1 msb)\n              (aset state 2 lsb-ctr)\n              (UUID. msb (bit-or lsb-ctr #=(bit-shift-left 2 62))))\n\n            (clojure/< time-now last-ms)\n            (recur)\n\n            true\n            (let [lsb-ctr (bit-and (unchecked-inc (aget state 2)) 0x3FFFFFFFFFFFFFFF)]\n              (aset state 2 lsb-ctr)\n              (UUID. (aget state 1) (bit-or lsb-ctr #=(bit-shift-left 2 62))))))))))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; V4 (random) UUID Constructor                                 [RFC9562:5.4] ;;\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(defn v4\n  \"Generate a v4 (random) UUID.  Uses default JVM implementation.  If two\n  arguments, lsb and msb (both long) are provided, then construct a valid,\n  properly formatted v4 UUID based on those values.  So, for example the\n  following UUID, created from all zero bits, is indeed distinct from the\n  null UUID:\n\n      (v4)\n       => #uuid \\\"dcf0035f-ea29-4d1c-b52e-4ea499c6323e\\\"\n\n      (v4 0 0)\n       => #uuid \\\"00000000-0000-4000-8000-000000000000\\\"\n\n      (null)\n       => #uuid \\\"00000000-0000-0000-0000-000000000000\\\"\"\n  (^java.util.UUID []\n    (UUID/randomUUID))\n  (^java.util.UUID [msb lsb]\n    (UUID.\n      (bitmop/dpb #=(bitmop/mask 4 12) msb 0x4)\n      (bitmop/dpb #=(bitmop/mask 2 62) lsb 0x2))))\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; v8 (custom) UUID Constructor                  [RFC9562:5.8: UUID Version 8];;\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(defn v8\n  \"Generate a v8 custom UUID with up to 122 bits of user data.\"\n  ^java.util.UUID\n  [^long msb ^long lsb]\n  (UUID.\n   (bitmop/dpb #=(bitmop/mask 4 12) msb 0x8)\n   (bitmop/dpb #=(bitmop/mask 2 62) lsb 0x2)))\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; SQUUID (sequential) UUID Constructor\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(defn squuid\n  \"Generate a SQUUID (sequential, random) unique identifier.  SQUUID's\n  are a nonstandard variation on v4 (random) UUIDs that have the\n  desirable property that they increase sequentially over time as well\n  as encode retrievably the posix time at which they were generated.\n  Splits and reassembles a v4 UUID to merge current POSIX\n  time (seconds since 12:00am January 1, 1970 UTC) with the most\n  significant 32 bits of the UUID.\"\n  ^java.util.UUID\n  []\n  (let [uuid (v4)\n        secs (clock/posix-time)\n        lsb  (get-word-low  uuid)\n        msb  (get-word-high uuid)\n        timed-msb (bit-or (bit-shift-left secs 32)\n                    (bit-and +ub32-mask+ msb))]\n    (UUID. timed-msb lsb)))\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; \"Local-Part\" Representation\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n;; The following represent a default set of local-part encoding rules.  As a\n;; default, a plain byte-array will be passed through unchanged and a\n;; generic java.lang.Object is represented by the bytes of its serialization.\n;; Strings are represented using UTF8 encoding.  URL's are digested as the\n;; UTF bytes of their string representation.\n\n(def ^:private ByteArray (class (byte-array 0)))\n\n(extend-protocol UUIDNameBytes\n\n  java.lang.Object\n  (as-byte-array ^bytes [this]\n    (if (instance? ByteArray this)\n      this\n      (let [baos (ByteArrayOutputStream.)\n            oos  (ObjectOutputStream. baos)]\n        (.writeObject oos this)\n        (.close oos)\n        (.toByteArray baos))))\n\n  java.lang.String\n  (as-byte-array ^bytes [this]\n    (util/compile-if (util/java6?)\n      (.getBytes this)\n      (.getBytes this java.nio.charset.StandardCharsets/UTF_8)))\n\n  java.net.URL\n  (as-byte-array ^bytes [this]\n    (as-byte-array (.toString this)))\n\n  nil\n  (as-byte-array [x]\n    (throw (IllegalArgumentException. (format \"%s cannot be converted to byte array.\" x)))))\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Digest Instance\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(def ^:private -md5-\n  (ThreadLocal/withInitial\n    (reify java.util.function.Supplier\n      (get [_] (MessageDigest/getInstance \"MD5\")))))\n\n(def ^:private -sha1-\n  (ThreadLocal/withInitial\n    (reify java.util.function.Supplier\n      (get [_] (MessageDigest/getInstance \"SHA1\")))))\n\n(defn- make-digest\n  ^java.security.MessageDigest\n  [^String designator]\n  (let [^MessageDigest md\n        (case designator\n          \"MD5\"  (.get ^ThreadLocal -md5-)\n          \"SHA1\" (.get ^ThreadLocal -sha1-)\n          (MessageDigest/getInstance designator))]\n    (.reset md)\n    md))\n\n(defn- digest-bytes\n  ^bytes\n  [^String kind ^bytes ns-bytes ^bytes local-bytes]\n  (let [m (make-digest kind)]\n    (.update m ns-bytes)\n    (.digest m local-bytes)))\n\n(defn- build-digested-uuid\n  ^java.util.UUID\n  [^long version ^bytes arr]\n  {:pre [(or (clojure/= version 3) (clojure/= version 5))]}\n  (let [msb (bitmop/bytes->long arr 0)\n        lsb (bitmop/bytes->long arr 8)]\n    (UUID.\n     (bitmop/dpb #=(bitmop/mask 4 12) msb version)\n     (bitmop/dpb #=(bitmop/mask 2 62) lsb 0x2))))\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Namespaced UUIDs                                        [RFC9562:5.3, 5.5] ;;\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(let [^ThreadLocal md5-tl  -md5-\n      ^ThreadLocal sha1-tl -sha1-\n      ^ThreadLocal ns-buf-tl (ThreadLocal/withInitial\n                               (reify java.util.function.Supplier\n                                 (get [_] (ByteBuffer/allocate 16))))]\n\n  (defn v3\n    \"Generate a v3 (name based, MD5 hash) UUID. 'context' must be UUIDable.\n  v3 identifiers are intended for generating UUID's from names that are\n  drawn from, and unique within, some namespace.  The concept of name and\n  namespace should be broadly construed, and not limited to textual names.\n  The requirements for a v3 UUID are as follows:\n\n  * v3 UUID's generated at different times from the same name in the same\n    namespace MUST be equal.\n\n  * v3 UUID's generated from two different names in the same namespace\n    SHOULD be distinct with a high degree of certainty.\n\n  * v3 UUID's generated from the same name in two different namespaces\n    SHOULD be distinct with a high degree of certainty.\n\n  * If two v3 UUID's are equal, then there is a high degree of certainty\n    that they were generated from the same name in the same namespace.\"\n    ^java.util.UUID\n    [context local-part]\n    (let [^MessageDigest md (.get md5-tl)\n          _                 (.reset md)\n          ^UUID ns-uuid     (as-uuid context)\n          ^ByteBuffer nsbuf (.get ns-buf-tl)\n          _                 (.putLong nsbuf 0 (.getMostSignificantBits ns-uuid))\n          _                 (.putLong nsbuf 8 (.getLeastSignificantBits ns-uuid))\n          _                 (.update md (.array nsbuf))\n          digest            (.digest md ^bytes (as-byte-array local-part))\n          ^ByteBuffer dbuf  (ByteBuffer/wrap digest)\n          msb               (bit-or (bit-and (.getLong dbuf 0)\n                                     #=(bit-not #=(bitmop/mask 4 12)))\n                              0x3000)\n          lsb               (bit-or (bit-and (.getLong dbuf 8)\n                                     #=(bit-not #=(bitmop/mask 2 62)))\n                              #=(bit-shift-left 2 62))]\n      (UUID. msb lsb)))\n\n  (defn v5\n    \"Generate a v5 (name based, SHA1 hash) UUID. 'context' must be UUIDable.\n  v5 identifiers are intended for generating UUID's from names that are\n  drawn from, and unique within, some namespace.  The concept of name and\n  namespace should be broadly construed, and not limited to textual names.\n  The requirements for a v5 UUID are as follows:\n\n  * v5 UUID's generated at different times from the same name in the same\n    namespace MUST be equal.\n\n  * v5 UUID's generated from two different names in the same namespace\n    SHOULD be distinct with a high degree of certainty.\n\n  * v5 UUID's generated from the same name in two different namespaces\n    SHOULD be distinct with a high degree of certainty.\n\n  * If two v5 UUID's are equal, then there is a high degree of certainty\n    that they were generated from the same name in the same namespace.\"\n    ^java.util.UUID\n    [context local-part]\n    (let [^MessageDigest md (.get sha1-tl)\n          _                 (.reset md)\n          ^UUID ns-uuid     (as-uuid context)\n          ^ByteBuffer nsbuf (.get ns-buf-tl)\n          _                 (.putLong nsbuf 0 (.getMostSignificantBits ns-uuid))\n          _                 (.putLong nsbuf 8 (.getLeastSignificantBits ns-uuid))\n          _                 (.update md (.array nsbuf))\n          digest            (.digest md ^bytes (as-byte-array local-part))\n          ^ByteBuffer dbuf  (ByteBuffer/wrap digest)\n          msb               (bit-or (bit-and (.getLong dbuf 0)\n                                     #=(bit-not #=(bitmop/mask 4 12)))\n                              0x5000)\n          lsb               (bit-or (bit-and (.getLong dbuf 8)\n                                     #=(bit-not #=(bitmop/mask 2 62)))\n                              #=(bit-shift-left 2 62))]\n      (UUID. msb lsb))))\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Predicates\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(defn- compare-many\n  [f x y more]\n  (if (f x y)\n    (if (next more)\n      (recur f y (first more) (next more))\n      (f y (first more)))\n    false))\n\n(defn =\n  \"Directly compare two or more UUIDs for = relation based on the\n  equality semantics defined by [RFC4122:3 RULES FOR LEXICAL\n  EQUIVALENCE].\"\n  ([_] true)\n  ([x y]\n   (uuid= x y))\n  ([x y & more]\n   (compare-many uuid= x y more)))\n\n(defn >\n  \"Directly compare two or more UUIDs for > relation based on the\n  ordinality semantics defined by [RFC4122:3 RULES FOR LEXICAL\n  EQUIVALENCE].\"\n  ([_] true)\n  ([x y]\n   (uuid> x y))\n  ([x y & more]\n   (compare-many uuid> x y more)))\n\n(defn <\n  \"Directly compare two or more UUIDs for < relation based on the\n  ordinality semantics defined by [RFC4122:3 RULES FOR LEXICAL\n  EQUIVALENCE].\"\n  ([_] true)\n  ([x y]\n   (uuid< x y))\n  ([x y & more]\n   (compare-many uuid< x y more)))\n\n(defn uuid-string? [str]\n  (and (string? str)\n       (some? (re-matches uuid-regex str))))\n\n(defn uuid-urn-string? [str]\n  (and (string? str)\n       (some? (re-matches urn-regex str))))\n\n(defn uuid-vec? [v]\n  (and (clojure/= (count v) 16)\n       (every? #(and (integer? %) (>= -128  % 127)) v)))\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; UUID Polymorphism\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(defn- str->uuid [s]\n  (cond\n    (uuid-string?     s) (UUID/fromString s)\n    (uuid-urn-string? s) (UUID/fromString (subs s 9))\n    :else                (throw (IllegalArgumentException. (format \"Invalid UUID: %s\" s)))))\n\n(extend-protocol UUIDRfc9562\n  Object\n  (uuid? [x] false)\n\n  nil\n  (uuid? [_] false))\n\n(extend-protocol UUIDable\n  (Class/forName \"[B\") ; byte array\n  (as-uuid [^bytes ba]\n    (let [bb (ByteBuffer/wrap ba)]\n      (UUID. (.getLong bb 0) (.getLong bb 8))))\n  (uuidable? [^bytes ba]\n    (clojure/= 16 (alength ^bytes ba)))\n\n  String\n  (uuidable? ^boolean [s]\n    (or\n     (uuid-string?     s)\n     (uuid-urn-string? s)))\n  (as-uuid [s]\n    (str->uuid s))\n\n  URI\n  (uuidable? ^boolean [u]\n    (uuid-urn-string? (str u)))\n  (as-uuid [u]\n    (str->uuid (str u)))\n\n  Object\n  (uuidable? ^boolean [_]\n    false)\n  (as-uuid [x]\n    (throw (IllegalArgumentException. (format \"%s Cannot be coerced to UUID.\" x))))\n\n  nil\n  (as-uuid [x]\n    (throw (IllegalArgumentException. (format \"%s cannot be coerced to UUID.\" x))))\n  (uuidable? ^boolean [_] false))\n"
  },
  {
    "path": "src/clj_uuid/node.clj",
    "content": "(ns clj-uuid.node\n  (:require [clj-uuid.util      :refer [java6? compile-if]]\n            [clj-uuid.bitmop    :refer [sb8 assemble-bytes ldb dpb mask]]\n            [clj-uuid.constants :refer :all]\n            [clj-uuid.random    :as random])\n  (:import  [java.net           InetAddress\n                                NetworkInterface]\n            [java.security      MessageDigest]\n            [java.util          Properties]))\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Clock Sequence                            [RFC4122:4.1.5 \"CLOCK SEQUENCE\"] ;;\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;;\n;; For time-based UUID's the \"clock-sequence\" value is a somewhat counter-\n;; intuitively named value that is used to reduce the potential that duplicate\n;; UUID's might be generated under unusual situations, such as if the system\n;; hardware clock is set backward in time or if, despite all efforts otherwise,\n;; a duplicate +node-id+ (see below) happens to be generated. This value is\n;; initialized to a random 16-bit number once per lifetime of the system.\n\n(defonce +clock-sequence+ (inc (rand-int 0xffff)))\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; NodeID Representation                               [RFC4122:4.1.6 \"NODE\"] ;;\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;;\n;; The representation of NodeID used for construction of time-based (v1) UUIDs\n;; is a list with the following encoding semantics:\n;;\n;;               SIZE    TYPE      REPRESENTATION\n;;  -----------+------+---------+---------------------------------------------\n;;  node       |    6 |  ub48   |  (<BYTE> <BYTE> <BYTE> <BYTE> <BYTE> <BYTE>)\n;;\n;; prepending two other (computed) bytes to the node-id before\n;; bitwise assembly.\n;;\n;;  (cons clock-high (cons clock-low @+node-id+))\n;;\n;;\n;;      ( <BYTE> . <BYTE> . <BYTE> <BYTE> <BYTE> <BYTE> <BYTE> <BYTE>)\n;;\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; NodeID Calculation  [RFC4122:4.5 \"NODE IDS THAT DO NOT IDENTIFY THE HOST\"] ;;\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;;\n;; This turns out to be surprisingly problematic.  I've tried various\n;; approaches.  The most straightforward is the use of IEEE 802 MAC Address:\n;;\n;;     (.getHardwareAddress\n;;       (java.net.NetworkInterface/getByInetAddress\n;;         (java.net.InetAddress/getLocalHost))))))\n;;\n;; Unfortunately got reports of NPE on some platforms (openjdk?).  Also, it\n;; discloses the hardware address of the host system -- this is how the\n;; creator of the melissa virus was actually tracked down and caught.\n;;\n;; choosing node-id randomly does not provide consistent generation of UUID's\n;; across runtimes.\n;;\n;; This topic is specifically addressed by the RFC:\n;;\n;;\n;;   \"A better solution is to obtain a 47-bit cryptographic quality random\n;;   number and use it as the low 47-bits of the Node-ID, with the least\n;;   significant bit of the first octet of the Node-ID set to one.  This\n;;   bit is the unicast/multicast bit, which will never be set in IEEE 802\n;;   addresses obtained from network cards.  Hence, there can never be a\n;;   conflict between UUID's generated by machines with and without network\n;;   cards.\"\n;;\n;;                               . . .\n;;\n;;   \"In addition, items such as the computer's name and the name of the\n;;   operating system, while not strictly speaking random, will help\n;;   differentiate the results from those obtained by other systems...\n;;   ... A generic approach... IS TO ACCUMULATE AS MANY SOURCES AS POSSIBLE\n;;   INTO A BUFFER, USE A MESSAGE DIGEST SUCH AS MD5 OR SHA1, TAKE AN\n;;   ARBITRARY 6 BYTES FROM THE HASH VALUE, AND SET THE MULTICAST BIT\n;;   AS DESCRIBED ABOVE.\"\n;;\n;;     -- [RFC4122:4.5 \"Node IDs that do not Identify the Host\"]\n;;\n;;\n;; We do exactly that.  Taking into account that the term \"first octet\"\n;; in the above excerpt refers to network transmission order, and we\n;; 'bit-or' the corresponding bytes:\n;;\n;;     hi-byte | byte5 | byte4 | byte3 | byte2 | lo-byte\n;;    ---------+-------+-------+-------+-------+---------\n;;       0x00  |  0x00 |  0x00 |  0x00 |  0x00 |   0x01\n;;\n;; Thanks to Datastax and to @jjcomer for submitting the original patch\n;; from which this current implementation is largely derived.\n;;\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n\n(def ^:private datasources [\"java.vendor\"\n                            \"java.vendor.url\"\n                            \"java.version\"\n                            \"os.arch\"\n                            \"os.name\"\n                            \"os.version\"])\n\n(defn- all-local-addresses []\n  (let [^InetAddress local-host (InetAddress/getLocalHost)\n        host-name (.getCanonicalHostName local-host)\n        base-addresses #{(str local-host) host-name}\n        network-interfaces (reduce (fn [acc ^NetworkInterface ni]\n                                     (concat acc\n                                       (map str (enumeration-seq\n                                                  (.getInetAddresses ni)))))\n                             base-addresses\n                             (enumeration-seq\n                               (NetworkInterface/getNetworkInterfaces)))]\n    (reduce conj network-interfaces\n      (map str (InetAddress/getAllByName host-name)))))\n\n(defn- make-node-id []\n    (let [addresses (all-local-addresses)\n          ^MessageDigest digest (MessageDigest/getInstance \"MD5\")\n          ^Properties    props  (System/getProperties)\n          to-digest (reduce (fn [acc key]\n                              (conj acc (.getProperty props key)))\n                      addresses datasources)]\n      (doseq [^String d to-digest]\n        (compile-if (java6?)\n          (.update digest (.getBytes d))\n          (.update digest\n            (.getBytes d java.nio.charset.StandardCharsets/UTF_8))))\n      (map bit-or\n        [0x00 0x00 0x00 0x00 0x00 0x01]\n        (take 6 (seq (.digest digest))))))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Public NodeID API\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(def node-id make-node-id)\n\n(def +node-id+ (delay (assemble-bytes (cons 0 (cons 0 (node-id))))))\n\n(defonce +v1-lsb+\n  (let [clk-high  (dpb (mask 2 6) (ldb (mask 6 8) +clock-sequence+) 0x2)\n        clk-low   (ldb (mask 8 0) +clock-sequence+)]\n    (dpb (mask 8 56) (dpb (mask 8 48) @+node-id+ clk-low) clk-high)))\n\n;; v6 lsb uses a cryptographically secure random node identifier that is\n;; initialized at runtime.\n\n(defonce +v6-lsb+\n  (let [clk-high  (dpb (mask 2 6) (ldb (mask 6 8) +clock-sequence+) 0x2)\n        clk-low   (ldb (mask 8 0) +clock-sequence+)]\n    (dpb (mask 8 56) (dpb (mask 8 48) (random/long) clk-low) clk-high)))\n"
  },
  {
    "path": "src/clj_uuid/random.clj",
    "content": "(ns clj-uuid.random\n  (:refer-clojure :exclude [bytes long])\n  (:import (java.security SecureRandom)))\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Randomness                                  [RFC9562:6.9 \"Unguessability\"] ;;\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;;\n;;   \"Implementations SHOULD utilize a cryptographically secure\n;;   pseudorandom number generator (CSPRNG) to provide values that are\n;;   both difficult to predict (unguessable) and have a low likelihood\n;;   of collision\"\n;;\n;; UUID variants calling for hard-to-guess random components (currently\n;; v7) are generated using java.security.SecureRandom -- A\n;; cryptographically strong nondeterministic random number generator\n;; that minimally complies with the statistical random number generator\n;; tests specified in FIPS 140-2, Security Requirements for\n;; Cryptographic Modules, section 4.9.1.\n\n(defonce ^:private ^SecureRandom secure-random\n  (SecureRandom.))\n\n(defn bytes\n  \"Generate `n` random bytes.\"\n  [n]\n  (let [bs (byte-array n)]\n    (.nextBytes secure-random bs) bs))\n\n(defn long\n  \"Generate a long value that is hard to guess. Randomness limited to the\n  number of bytes.\"\n  ([]\n   (.nextLong secure-random))\n  ([n-bytes]\n   (reduce (fn [n b] (+ (bit-shift-left n 8) b)) 0 (bytes n-bytes))))\n\n(defn eight-bits\n  \"Generate a hard-to-guess long value between 0 and 255\"\n  []\n  (bit-and (.nextLong secure-random) 0xff))\n\n(defn ten-bits\n  \"Generate a hard-to-guess long value between 0 and 1023\"\n  []\n  (bit-and (.nextLong secure-random) 0x3ff))\n\n(defn eleven-bits\n  \"Generate a hard-to-guess long value between 0 and 2047\"\n  []\n  (bit-and (.nextLong secure-random) 0x7ff))\n\n(defn twelve-bits\n  \"Generate a hard-to-guess long value between 0 and 4095\"\n  []\n  (bit-and (.nextLong secure-random) 0xfff))\n"
  },
  {
    "path": "src/clj_uuid/util.clj",
    "content": "(ns clj-uuid.util\n  (:import (java.util UUID)))\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; PROG1 but with more idiomatic clojure name\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(defmacro returning\n  \"Compute a return value, then execute other forms for side effects.\n  Like prog1 in common lisp, or a (do) that returns the first form.\"\n  [value & forms]\n  `(let [value# ~value]\n     ~@forms\n     value#))\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Conditional Compilation\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(defn java6? []\n  (neg? (compare (System/getProperty \"java.version\") \"1.7\")))\n\n(defmacro compile-if\n  \"Evaluate `exp` and if it returns logical true and doesn't error, expand to\n  `then` otherwise expand to `else`.\n  credit: <clojure/src/clj/clojure/core/reducers.clj#L24>\n\n  (compile-if (Class/forName \\\"java.util.concurrent.ForkJoinTask\\\")\n    (do-cool-stuff-with-fork-join)\n    (fall-back-to-executor-services))\"\n  [exp then else]\n  (if (try (eval exp)\n           (catch Throwable _ false))\n    `(do ~then)\n    `(do ~else)))\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Timing and Performance Metric\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(defmacro with-timing\n  \"Same as clojure.core/time but returns a vector of a the result of\n   the code and the milliseconds rather than printing a string. Runs\n   the code in an implicit do.\"\n  [& body]\n  `(let [start# (System/nanoTime)  ret# ~(cons 'do body)]\n     [ret# (/ (double (- (System/nanoTime) start#)) 1000000.0)]))\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Debugging\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(defmacro wrap-fn [name args & body]\n  `(let [old-fn# (var-get (var ~name))\n         new-fn# (fn [& p#]\n                   (let [~args p#]\n                     (do ~@body)))\n         wrapper# (fn [& params#]\n                    (if (= ~(count args) (count params#))\n                      (apply new-fn# params#)\n                      (apply old-fn# params#)))]\n     (alter-var-root (var ~name) (constantly wrapper#))))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; IO\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(defmacro with-temp-file [f-sym & body]\n  `(let [prefix#  (.toString (UUID/randomUUID))\n         postfix# (.toString (UUID/randomUUID))\n         ~f-sym   (java.io.File/createTempFile prefix# postfix#)]\n     (try\n       (do ~@body)\n       (finally\n         (.delete ~f-sym)))))\n\n(defn lines-of-file [^String file-name]\n  (line-seq\n    (java.io.BufferedReader.\n      (java.io.InputStreamReader.\n        (java.io.FileInputStream. file-name)))))\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Namespace Re-export\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(defmacro import-vars\n  \"Import public vars from src-ns into the current namespace.\"\n  [src-ns & var-syms]\n  `(do\n     ~@(map (fn [sym]\n              `(def ~(vary-meta sym assoc\n                       :doc (:doc (meta (resolve (symbol (name src-ns) (name sym))))))\n                 ~(symbol (name src-ns) (name sym))))\n            var-syms)))\n"
  },
  {
    "path": "src/clj_uuid.clj",
    "content": "(ns clj-uuid\n  \"RFC 9562 UUID implementation for Clojure.\n\n  This namespace re-exports all public vars from clj-uuid.core, as Babashka\n  does not like single-segment namespaces.    For backward\n  compatibility, both `(require '[clj-uuid :as uuid])` and\n  `(require '[clj-uuid.core :as uuid])` provide identical functionality.\n\n  Quick start:\n    (require '[clj-uuid :as uuid])\n    (uuid/v4)       ; random UUID\n    (uuid/v7)       ; time-based, sortable, cryptographically secure\n    (uuid/v7nc)     ; time-based, sortable, fast (non-cryptographic)\n\n  See clj-uuid.core for complete documentation.\"\n  (:refer-clojure :exclude [== uuid? max < > =])\n  (:require [clj-uuid.util :refer [import-vars]]\n            [clj-uuid.core :as impl]))\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Constants\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(import-vars impl\n  +null+ +max+ +namespace-dns+ +namespace-url+ +namespace-oid+ +namespace-x500+)\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Protocols\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(def UUIDNameBytes impl/UUIDNameBytes)\n(def UUIDable      impl/UUIDable)\n(def UUIDRfc9562   impl/UUIDRfc9562)\n(def UUIDRfc4122   impl/UUIDRfc4122)\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Constructors\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(import-vars impl\n  null v0 max v1 v3 v4 v5 v6 v7 v7nc v8 squuid)\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Protocol Functions\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(import-vars impl\n  uuid? null? max? as-uuid uuidable? as-byte-array\n  hash-code get-word-high get-word-low get-version get-variant\n  get-time-low get-time-mid get-time-high get-clk-low get-clk-high get-clk-seq\n  get-node-id get-timestamp get-instant get-unix-time\n  to-byte-array to-string to-hex-string to-urn-string to-uri)\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Comparison Operators\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(import-vars impl\n  uuid= uuid< uuid> = < >)\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Predicates\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(import-vars impl\n  uuid-string? uuid-urn-string? uuid-vec?)\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Clock\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(import-vars impl\n  monotonic-time)\n"
  },
  {
    "path": "test/clj_uuid/api_test.clj",
    "content": "(ns clj-uuid.api-test\n  (:refer-clojure :exclude [uuid? max])\n  (:require [clojure.test   :refer :all]\n            [clojure.string :as str]\n            [clj-uuid       :refer :all :exclude [= > <]]\n            [clj-uuid.clock :as clock])\n  (:import\n   (java.lang IllegalArgumentException)\n   (java.net  URI URL)\n   (java.util Date)))\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Protocol Tests\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(deftest check-unique-identifier-protocol\n\n  (testing \"v0 uuid protocol...\"\n    (let [tmpid +null+]\n      (is (= (get-word-high tmpid)       0))\n      (is (= (get-word-low tmpid)        0))\n      (is (= (null? tmpid)           true))\n      (is (= (seq (to-byte-array tmpid)) [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]))\n      (is (= (hash-code tmpid)       0))\n      (is (= (get-version tmpid)         0))\n      (is (= (to-string tmpid)       \"00000000-0000-0000-0000-000000000000\"))\n      (is (= (to-urn-string tmpid)\n             \"urn:uuid:00000000-0000-0000-0000-000000000000\"))\n      (is (= (get-time-low tmpid)       0))\n      (is (= (get-time-mid tmpid)       0))\n      (is (= (get-time-high tmpid)      0))\n      (is (= (get-clk-low tmpid)        0))\n      (is (= (get-clk-high tmpid)       0))\n      (is (= (get-node-id tmpid)        0))\n      (is (= (get-timestamp tmpid)      nil))\n      (is (= (get-unix-time tmpid)      nil))))\n\n  (testing \"v1 uuid protocol...\"\n    (let [tmpid +namespace-x500+]\n      (is (= (get-word-high tmpid)       7757371281853190609))\n      (is (= (get-word-low tmpid)        -9172705715073830712))\n      (is (= (null? tmpid)           false))\n      (is (= (seq (to-byte-array tmpid))\n             [107 -89 -72 20 -99 -83 17 -47 -128 -76 0 -64 79 -44 48 -56]))\n      (is (= (hash-code tmpid)       963287501))\n      (is (= (get-version tmpid)         1))\n      (is (= (to-string tmpid)     \"6ba7b814-9dad-11d1-80b4-00c04fd430c8\"))\n      (is (= (to-urn-string tmpid)\n             \"urn:uuid:6ba7b814-9dad-11d1-80b4-00c04fd430c8\"))\n      (is (= (get-time-low tmpid)       1806153748))\n      (is (= (get-time-mid tmpid)       40365))\n      (is (= (get-time-high tmpid)      4561))\n      (is (= (get-clk-low tmpid)        128))\n      (is (= (get-clk-high tmpid)       180))\n      (is (= (get-node-id tmpid)        825973027016))\n      (is (= (get-timestamp tmpid)      131059232331511828))\n      (is (= (get-unix-time tmpid)      886630433151))))\n\n  (testing \"v3 uuid protocol...\"\n    (let [tmpid (as-uuid \"d9c53a66-fde2-3d04-b5ad-dce3848df07e\")]\n      (is (= (get-word-high tmpid)       -2754731383046652668))\n      (is (= (get-word-low tmpid)        -5355381512134070146))\n      (is (= (null? tmpid)           false))\n      (is (= (seq (to-byte-array tmpid))\n             [-39 -59 58 102 -3 -30 61 4 -75 -83 -36 -29 -124 -115 -16 126]))\n      (is (= (hash-code tmpid)       352791551))\n      (is (= (get-version tmpid)         3))\n      (is (= (to-string tmpid)       \"d9c53a66-fde2-3d04-b5ad-dce3848df07e\"))\n      (is (= (to-urn-string tmpid)\n             \"urn:uuid:d9c53a66-fde2-3d04-b5ad-dce3848df07e\"))\n      (is (= (get-time-low tmpid)        3653581414))\n      (is (= (get-time-mid tmpid)        64994))\n      (is (= (get-time-high tmpid)       15620))\n      (is (= (get-clk-low tmpid)         181))\n      (is (= (get-clk-high tmpid)        173))\n      (is (= (get-node-id tmpid)         242869739581566))\n      (is (= (get-timestamp tmpid)       nil))\n      (is (= (get-unix-time tmpid)       nil))))\n\n  (testing \"v4 uuid protocol...\"\n    (let [tmpid #uuid \"3eb1e29a-4747-4a7d-8e40-94e245f57dc0\"]\n      (is (= (get-word-high tmpid)       4517641053478013565))\n      (is (= (get-word-low tmpid)       -8196387622257066560))\n      (is (= (null? tmpid)               false))\n      (is (= (seq (to-byte-array tmpid))\n             [62 -79 -30 -102 71 71 74 125 -114 64 -108 -30 69 -11 125 -64]))\n      (is (= (hash-code tmpid)       -1304215099))\n      (is (= (get-version tmpid)         4))\n      (is (= (to-string tmpid)       \"3eb1e29a-4747-4a7d-8e40-94e245f57dc0\"))\n      (is (= (to-urn-string tmpid)\n             \"urn:uuid:3eb1e29a-4747-4a7d-8e40-94e245f57dc0\"))\n      (is (= (get-time-low tmpid)        1051845274))\n      (is (= (get-time-mid tmpid)        18247))\n      (is (= (get-time-high tmpid)       19069))\n      (is (= (get-clk-low tmpid)         142))\n      (is (= (get-clk-high tmpid)        64))\n      (is (= (get-node-id tmpid)         163699557236160))\n      (is (= (get-timestamp tmpid)       nil))\n      (is (= (get-unix-time tmpid)       nil))))\n\n  (testing \"max uuid protocol...\"\n    (let [tmpid +max+]\n      (is (= (get-word-high tmpid)       -1))\n      (is (= (get-word-low tmpid)        -1))\n      (is (= (null? tmpid)               false))\n      (is (= (max? tmpid)                true))\n      (is (= (seq (to-byte-array tmpid)) [-1 -1 -1 -1 -1 -1 -1 -1\n                                          -1 -1 -1 -1 -1 -1 -1 -1]))\n      (is (= (hash-code tmpid)           0))\n      (is (= (get-version tmpid)         0xf))\n      (is (= (to-string tmpid)       \"ffffffff-ffff-ffff-ffff-ffffffffffff\"))\n      (is (= (to-urn-string tmpid)\n             \"urn:uuid:ffffffff-ffff-ffff-ffff-ffffffffffff\"))\n      (is (= (get-time-low tmpid)       0xffffffff))\n      (is (= (get-time-mid tmpid)       0xffff))\n      (is (= (get-time-high tmpid)      0xffff))\n      (is (= (get-clk-low tmpid)        0xff))\n      (is (= (get-clk-high tmpid)       0xff))\n      (is (= (get-node-id tmpid)        0xffffffffffff))\n      (is (= (get-timestamp tmpid)      nil))\n      (is (= (get-unix-time tmpid)      nil))))\n\n  (testing \"v6 uuid protocol...\"\n    (let [tmpid #uuid \"1ef3f06f-16db-6ff0-bb01-1b50e6f39e7f\"]\n      (is (= (get-word-high tmpid)       2230390600394043376))\n      (is (= (get-word-low tmpid)        -4971662479354257793))\n      (is (= (null? tmpid)               false))\n      (is (= (max? tmpid)                false))\n      (is (= (seq (to-byte-array tmpid)) [30  -13 -16 111 22  -37 111 -16\n                                          -69 1   27  80  -26 -13 -98 127]))\n      (is (= (hash-code tmpid)           1440357040))\n      (is (= (get-version tmpid)         6))\n      (is (= (to-string tmpid)       \"1ef3f06f-16db-6ff0-bb01-1b50e6f39e7f\"))\n      (is (= (to-urn-string tmpid)\n             \"urn:uuid:1ef3f06f-16db-6ff0-bb01-1b50e6f39e7f\"))\n      (is (= (get-time-low tmpid)       0x6ff0))\n      (is (= (get-time-mid tmpid)       0x16db))\n      (is (= (get-time-high tmpid)      0x1ef3f06f))\n      (is (= (get-clk-low tmpid)        0xbb))\n      (is (= (get-clk-high tmpid)       0x1))\n      (is (= (get-node-id tmpid)        0x1b50e6f39e7f))\n      (is (= (get-timestamp tmpid)      0x1ef3f06f16dbff0))\n      (is (= (get-unix-time tmpid)      1720648452463))))\n\n  (testing \"v7 uuid protocol...\"\n    (let [tmpid #uuid \"01909eae-4801-753a-bcd5-0889c34ac129\"]\n      (is (= (get-word-high tmpid)       112764462053815610))\n      (is (= (get-word-low tmpid)        -4839952836759731927))\n      (is (= (null? tmpid)               false))\n      (is (= (max? tmpid)                false))\n      (is (= (seq (to-byte-array tmpid)) [1   -112 -98 -82  72  1  117 58\n                                          -68 -43  8   -119 -61 74 -63 41]))\n      (is (= (hash-code tmpid)           906895924))\n      (is (= (get-version tmpid)         7))\n      (is (= (to-string tmpid)       \"01909eae-4801-753a-bcd5-0889c34ac129\"))\n      (is (= (to-urn-string tmpid)\n             \"urn:uuid:01909eae-4801-753a-bcd5-0889c34ac129\"))\n      (is (= (get-time-low tmpid)       0x01909eae))\n      (is (= (get-time-mid tmpid)       0x4801))\n      (is (= (get-time-high tmpid)      0x753a))\n      (is (= (get-clk-low tmpid)        0xbc))\n      (is (= (get-clk-high tmpid)       0xd5))\n      (is (= (get-node-id tmpid)        0x0889c34ac129))\n      (is (= (get-timestamp tmpid)      1720649140225))\n      (is (= (get-unix-time tmpid)      0x01909eae4801))))\n\n  (testing \"v8 uuid protocol...\"\n    (let [tmpid #uuid \"ffffffff-ffff-8fff-bfff-ffffffffffff\"]\n      (is (= (get-word-high tmpid)       -28673))\n      (is (= (get-word-low tmpid)        -4611686018427387905))\n      (is (= (null? tmpid)               false))\n      (is (= (max? tmpid)                false))\n      (is (= (seq (to-byte-array tmpid)) [-1  -1 -1 -1 -1 -1 -113 -1\n                                          -65 -1 -1 -1 -1 -1 -1   -1]))\n      (is (= (hash-code tmpid)           1073770496))\n      (is (= (get-version tmpid)         8))\n      (is (= (to-string tmpid)       \"ffffffff-ffff-8fff-bfff-ffffffffffff\"))\n      (is (= (to-urn-string tmpid)\n             \"urn:uuid:ffffffff-ffff-8fff-bfff-ffffffffffff\"))\n      (is (= (get-time-low tmpid)       0xffffffff))\n      (is (= (get-time-mid tmpid)       0xffff))\n      (is (= (get-time-high tmpid)      0x8fff))\n      (is (= (get-clk-low tmpid)        0xbf))\n      (is (= (get-clk-high tmpid)       0xff))\n      (is (= (get-node-id tmpid)        0xffffffffffff))\n      (is (= (get-timestamp tmpid)      nil))\n      (is (= (get-unix-time tmpid)      nil)))))\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Predicate Tests\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(deftest check-predicates\n  (testing \"string predicates...\"\n    (is (uuid-string?       (to-string       (v4))))\n    (is (uuid-urn-string?   (to-urn-string   (v4))))))\n\n(deftest nil-test\n  (testing \"Calling certain functions/methods on nil returns nil\"\n    (testing \"UUIDNameBytes\"\n      (is (thrown? IllegalArgumentException (as-byte-array nil))))\n\n    (testing \"UUIDable\"\n      (is (thrown? IllegalArgumentException (as-uuid nil)))\n      (is (false? (uuidable? nil))))\n\n    (testing \"UUIDRfc4122\"\n      (is (false? (uuid? nil))))\n\n    (is (false? (uuid-string? nil)))\n\n    (is (false? (uuid-urn-string? nil)))\n\n    (is (false? (uuid-vec? nil)))))\n\n(deftest byte-array-round-trip-test\n  (testing \"round-trip via byte-array\"\n    (let [uuid #uuid \"4787199e-c0e2-4609-b5b8-284f2b7d117d\"]\n      (is (= uuid (as-uuid (as-byte-array uuid)))))))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; get-variant\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(deftest check-get-variant\n  (testing \"null UUID variant\"\n    (is (= 0 (get-variant +null+))))\n\n  (testing \"Leach-Salz (variant 2) for all standard versions\"\n    (is (= 2 (get-variant (v1))))\n    (is (= 2 (get-variant (v3 +namespace-dns+ \"test\"))))\n    (is (= 2 (get-variant (v4))))\n    (is (= 2 (get-variant (v5 +namespace-dns+ \"test\"))))\n    (is (= 2 (get-variant (v6))))\n    (is (= 2 (get-variant (v7))))\n    (is (= 2 (get-variant (v8 0x123 0x456)))))\n\n  (testing \"max UUID variant\"\n    (is (= 7 (get-variant +max+))))\n\n  (testing \"well-known namespace UUIDs are variant 2\"\n    (is (= 2 (get-variant +namespace-dns+)))\n    (is (= 2 (get-variant +namespace-url+)))\n    (is (= 2 (get-variant +namespace-oid+)))\n    (is (= 2 (get-variant +namespace-x500+)))))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; get-instant\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(deftest check-get-instant\n  (testing \"v1 returns a Date\"\n    (let [before (System/currentTimeMillis)\n          inst   (get-instant (v1))\n          after  (System/currentTimeMillis)]\n      (is (instance? Date inst))\n      (is (<= before (.getTime ^Date inst) after))))\n\n  (testing \"v6 returns a Date\"\n    (let [before (System/currentTimeMillis)\n          inst   (get-instant (v6))\n          after  (System/currentTimeMillis)]\n      (is (instance? Date inst))\n      (is (<= before (.getTime ^Date inst) after))))\n\n  (testing \"v7 returns a Date\"\n    (let [before (System/currentTimeMillis)\n          inst   (get-instant (v7))\n          after  (System/currentTimeMillis)]\n      (is (instance? Date inst))\n      (is (<= before (.getTime ^Date inst) after))))\n\n  (testing \"non-time-based versions return nil\"\n    (is (nil? (get-instant (v3 +namespace-dns+ \"x\"))))\n    (is (nil? (get-instant (v4))))\n    (is (nil? (get-instant (v5 +namespace-dns+ \"x\"))))\n    (is (nil? (get-instant (v8 0 0))))\n    (is (nil? (get-instant +null+)))\n    (is (nil? (get-instant +max+)))))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; get-clk-seq\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(deftest check-get-clk-seq\n  (testing \"v1 returns a clock sequence\"\n    (let [cs (get-clk-seq (v1))]\n      (is (some? cs))\n      (is (integer? cs))))\n\n  (testing \"v6 returns a clock sequence\"\n    (let [cs (get-clk-seq (v6))]\n      (is (some? cs))\n      (is (integer? cs))\n      (is (<= 0 cs 0x3FFF) \"clock sequence is 14 bits\")))\n\n  (testing \"non-gregorian-time versions return nil\"\n    (is (nil? (get-clk-seq (v3 +namespace-dns+ \"x\"))))\n    (is (nil? (get-clk-seq (v4))))\n    (is (nil? (get-clk-seq (v5 +namespace-dns+ \"x\"))))\n    (is (nil? (get-clk-seq (v7))))\n    (is (nil? (get-clk-seq (v8 0 0)))))\n\n  (testing \"known v1 UUID clock sequence\"\n    ;; +namespace-x500+ is a v1 UUID with clock-seq = 180\n    (is (= 180 (get-clk-seq +namespace-x500+)))))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; squuid\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(deftest check-squuid\n  (testing \"squuid returns a UUID\"\n    (is (uuid? (squuid))))\n\n  (testing \"squuid preserves v4 version bits\"\n    (let [s (squuid)]\n      (is (= 4 (get-version s)))))\n\n  (testing \"squuid preserves variant 2\"\n    (let [s (squuid)]\n      (is (= 2 (get-variant s)))))\n\n  (testing \"squuids are unique\"\n    (let [uuids (repeatedly 1000 squuid)]\n      (is (= 1000 (count (set uuids))))))\n\n  (testing \"squuid embeds time in high 32 bits of MSB\"\n    ;; The high 32 bits of MSB come from clock/posix-time which is\n    ;; derived from System/currentTimeMillis. All squuids generated\n    ;; within the same ~10s window share the same high 32 bits.\n    (let [uuids (repeatedly 100 squuid)\n          hi32s (map #(unsigned-bit-shift-right (get-word-high %) 32)\n                  uuids)]\n      (is (= 1 (count (set hi32s)))\n          \"all squuids in a burst share the same time-derived high bits\"))))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; to-uri\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(deftest check-to-uri\n  (testing \"to-uri returns a java.net.URI\"\n    (let [u (v4)\n          uri (to-uri u)]\n      (is (instance? URI uri))))\n\n  (testing \"to-uri produces correct URN format\"\n    (let [u   #uuid \"6ba7b810-9dad-11d1-80b4-00c04fd430c8\"\n          uri (to-uri u)]\n      (is (= \"urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8\" (str uri)))))\n\n  (testing \"to-uri round-trips through as-uuid\"\n    (let [u   (v4)\n          uri (to-uri u)]\n      (is (= u (as-uuid uri)))))\n\n  (testing \"to-uri for null and max\"\n    (is (= \"urn:uuid:00000000-0000-0000-0000-000000000000\"\n           (str (to-uri +null+))))\n    (is (= \"urn:uuid:ffffffff-ffff-ffff-ffff-ffffffffffff\"\n           (str (to-uri +max+))))))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Multi-arity comparison operators\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(deftest check-multi-arity-comparisons\n  (testing \"single-arg always returns true\"\n    (let [u (v4)]\n      (is (clj-uuid/= u))\n      (is (clj-uuid/< u))\n      (is (clj-uuid/> u))))\n\n  (testing \"two-arg = works\"\n    (let [u (v3 +namespace-dns+ \"same\")]\n      (is (clj-uuid/= u u))\n      (is (not (clj-uuid/= u (v4))))))\n\n  (testing \"three-arg =\"\n    (let [u (v3 +namespace-dns+ \"same\")]\n      (is (clj-uuid/= u u u))\n      (is (not (clj-uuid/= u u (v4))))))\n\n  (testing \"four-arg =\"\n    (let [u (v3 +namespace-dns+ \"same\")]\n      (is (clj-uuid/= u u u u))\n      (is (not (clj-uuid/= u u u (v4))))))\n\n  (testing \"multi-arg < with ordered UUIDs\"\n    ;; uuid< uses signed long comparison on MSB then LSB.\n    ;; Use UUIDs whose MSBs are in signed-ascending order.\n    (let [a (v4 0 0)                                      ; MSB starts with 0000...4...\n          b (v4 0x3000000000000000 0)                      ; MSB starts with 3...4...\n          c (v4 0x5000000000000000 0)]                     ; MSB starts with 5...4...\n      (is (clj-uuid/< a b c))\n      (is (not (clj-uuid/< a c b)))))\n\n  (testing \"multi-arg > with ordered UUIDs\"\n    (let [a (v4 0 0)\n          b (v4 0x3000000000000000 0)\n          c (v4 0x5000000000000000 0)]\n      (is (clj-uuid/> c b a))\n      (is (not (clj-uuid/> c a b)))))\n\n  (testing \"< and > with equal elements returns false\"\n    (let [u (v4)]\n      (is (not (clj-uuid/< u u)))\n      (is (not (clj-uuid/> u u))))))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; v4 and v8 version+variant bit verification\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(deftest check-v4-version-variant-bits\n  (testing \"v4 always has version=4 and variant=2\"\n    (dotimes [_ 10000]\n      (let [u (v4)]\n        (is (= 4 (get-version u)))\n        (is (= 2 (get-variant u)))))))\n\n(deftest check-v4-two-arg-version-variant-bits\n  (testing \"v4 with explicit msb/lsb always stamps version=4 and variant=2\"\n    (is (= 4 (get-version (v4 0 0))))\n    (is (= 2 (get-variant (v4 0 0))))\n    (is (= 4 (get-version (v4 -1 -1))))\n    (is (= 2 (get-variant (v4 -1 -1))))\n    (is (= 4 (get-version (v4 Long/MAX_VALUE Long/MIN_VALUE))))\n    (is (= 2 (get-variant (v4 Long/MAX_VALUE Long/MIN_VALUE))))))\n\n(deftest check-v8-version-variant-bits\n  (testing \"v8 always has version=8 and variant=2\"\n    (is (= 8 (get-version (v8 0 0))))\n    (is (= 2 (get-variant (v8 0 0))))\n    (is (= 8 (get-version (v8 -1 -1))))\n    (is (= 2 (get-variant (v8 -1 -1))))\n    (is (= 8 (get-version (v8 Long/MAX_VALUE Long/MIN_VALUE))))\n    (is (= 2 (get-variant (v8 Long/MAX_VALUE Long/MIN_VALUE))))))\n\n(deftest check-v7-version-variant-bits\n  (testing \"v7 always has version=7 and variant=2\"\n    (dotimes [_ 10000]\n      (let [u (v7)]\n        (is (= 7 (get-version u)))\n        (is (= 2 (get-variant u)))))))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; as-byte-array on various types\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(deftest check-as-byte-array-types\n  (testing \"byte array passthrough\"\n    (let [ba (byte-array [1 2 3 4 5])]\n      (is (identical? ba (as-byte-array ba)))))\n\n  (testing \"String produces UTF-8 bytes\"\n    (let [ba (as-byte-array \"hello\")]\n      (is (instance? (Class/forName \"[B\") ba))\n      (is (= (count \"hello\") (alength ^bytes ba)))\n      (is (= (seq (.getBytes \"hello\" \"UTF-8\")) (seq ba)))))\n\n  (testing \"URL produces bytes of string representation\"\n    (let [url (URL. \"http://example.com\")\n          ba  (as-byte-array url)]\n      (is (instance? (Class/forName \"[B\") ba))\n      (is (= (seq (as-byte-array \"http://example.com\")) (seq ba)))))\n\n  (testing \"java.lang.Object produces serialized bytes\"\n    (let [ba (as-byte-array (Long. 42))]\n      (is (instance? (Class/forName \"[B\") ba))\n      (is (pos? (alength ^bytes ba)))))\n\n  (testing \"nil throws IllegalArgumentException\"\n    (is (thrown? IllegalArgumentException (as-byte-array nil)))))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; as-uuid and uuidable? from various sources\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(deftest check-as-uuid-from-string\n  (testing \"canonical hex string\"\n    (let [u (as-uuid \"6ba7b810-9dad-11d1-80b4-00c04fd430c8\")]\n      (is (= +namespace-dns+ u))))\n\n  (testing \"URN string\"\n    (let [u (as-uuid \"urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8\")]\n      (is (= +namespace-dns+ u))))\n\n  (testing \"invalid string throws\"\n    (is (thrown? IllegalArgumentException (as-uuid \"not-a-uuid\")))\n    (is (thrown? IllegalArgumentException (as-uuid \"\"))))\n\n  (testing \"nil throws\"\n    (is (thrown? IllegalArgumentException (as-uuid nil)))))\n\n(deftest check-as-uuid-from-byte-array\n  (testing \"16-byte array round-trips\"\n    (let [u  (v4)\n          ba (to-byte-array u)]\n      (is (= u (as-uuid ba)))))\n\n  (testing \"null UUID round-trips\"\n    (is (= +null+ (as-uuid (to-byte-array +null+)))))\n\n  (testing \"max UUID round-trips\"\n    (is (= +max+ (as-uuid (to-byte-array +max+))))))\n\n(deftest check-as-uuid-from-uri\n  (testing \"URI with valid UUID URN\"\n    (let [uri (URI/create \"urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8\")]\n      (is (= +namespace-dns+ (as-uuid uri)))))\n\n  (testing \"URI round-trip through to-uri\"\n    (let [u (v4)]\n      (is (= u (as-uuid (to-uri u)))))))\n\n(deftest check-as-uuid-identity\n  (testing \"UUID passes through as-uuid unchanged\"\n    (let [u (v4)]\n      (is (identical? u (as-uuid u))))))\n\n(deftest check-uuidable?\n  (testing \"UUID is uuidable\"\n    (is (true? (uuidable? (v4)))))\n\n  (testing \"valid UUID strings are uuidable\"\n    (is (true? (uuidable? \"6ba7b810-9dad-11d1-80b4-00c04fd430c8\")))\n    (is (true? (uuidable? \"urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8\"))))\n\n  (testing \"invalid strings are not uuidable\"\n    (is (false? (uuidable? \"not-a-uuid\")))\n    (is (false? (uuidable? \"\"))))\n\n  (testing \"16-byte arrays are uuidable\"\n    (is (true? (uuidable? (byte-array 16)))))\n\n  (testing \"wrong-length byte arrays are not uuidable\"\n    (is (false? (uuidable? (byte-array 15))))\n    (is (false? (uuidable? (byte-array 17)))))\n\n  (testing \"URI with valid URN is uuidable\"\n    (is (true? (uuidable? (URI/create \"urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8\")))))\n\n  (testing \"arbitrary objects are not uuidable\"\n    (is (false? (uuidable? 42)))\n    (is (false? (uuidable? nil)))))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; uuid? on non-UUID types\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(deftest check-uuid?\n  (testing \"UUID instances return true\"\n    (is (true? (uuid? (v4))))\n    (is (true? (uuid? +null+)))\n    (is (true? (uuid? +max+))))\n\n  (testing \"non-UUID types return false\"\n    (is (false? (uuid? \"6ba7b810-9dad-11d1-80b4-00c04fd430c8\")))\n    (is (false? (uuid? 42)))\n    (is (false? (uuid? nil)))\n    (is (false? (uuid? :keyword)))\n    (is (false? (uuid? [1 2 3])))))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; null? and max? edge cases\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(deftest check-null?-and-max?-edge-cases\n  (testing \"null? only true for null UUID\"\n    (is (true?  (null? +null+)))\n    (is (false? (null? +max+)))\n    (is (false? (null? (v4))))\n    (is (false? (null? (v1)))))\n\n  (testing \"max? only true for max UUID\"\n    (is (true?  (max? +max+)))\n    (is (false? (max? +null+)))\n    (is (false? (max? (v4))))\n    (is (false? (max? (v1)))))\n\n  (testing \"null and max are not equal\"\n    (is (not (clj-uuid/= +null+ +max+))))\n\n  (testing \"comparison uses signed semantics\"\n    ;; uuid< compares MSB then LSB using signed longs.\n    ;; max has MSB=-1, LSB=-1; null has MSB=0, LSB=0.\n    ;; In signed comparison: -1 < 0, so max < null.\n    (is (clj-uuid/< +max+ +null+))\n    (is (clj-uuid/> +null+ +max+))))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; get-unix-time\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(deftest check-get-unix-time\n  (testing \"v1 returns approximate current POSIX millis\"\n    (let [before (System/currentTimeMillis)\n          ut     (get-unix-time (v1))\n          after  (System/currentTimeMillis)]\n      (is (some? ut))\n      (is (<= before ut after))))\n\n  (testing \"v6 returns approximate current POSIX millis\"\n    (let [before (System/currentTimeMillis)\n          ut     (get-unix-time (v6))\n          after  (System/currentTimeMillis)]\n      (is (some? ut))\n      (is (<= before ut after))))\n\n  (testing \"v7 returns approximate current POSIX millis\"\n    (let [before (System/currentTimeMillis)\n          ut     (get-unix-time (v7))\n          after  (System/currentTimeMillis)]\n      (is (some? ut))\n      (is (<= before ut after))))\n\n  (testing \"non-time-based versions return nil\"\n    (is (nil? (get-unix-time (v3 +namespace-dns+ \"x\"))))\n    (is (nil? (get-unix-time (v4))))\n    (is (nil? (get-unix-time (v5 +namespace-dns+ \"x\"))))\n    (is (nil? (get-unix-time (v8 0 0))))))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; to-hex-string\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(deftest check-to-hex-string\n  (testing \"produces 32-char hex string\"\n    (let [u (v4)\n          h (to-hex-string u)]\n      (is (= 32 (count h)))\n      (is (re-matches #\"[0-9A-Fa-f]{32}\" h))))\n\n  (testing \"null UUID\"\n    (is (= \"00000000000000000000000000000000\"\n           (to-hex-string +null+))))\n\n  (testing \"max UUID\"\n    (is (= \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\"\n           (to-hex-string +max+))))\n\n  (testing \"hex string matches canonical string with dashes removed\"\n    (let [u (v4)]\n      (is (= (str/upper-case (str/replace (to-string u) \"-\" \"\"))\n             (to-hex-string u))))))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; posix-time conversion\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(deftest check-posix-time-conversion\n  (testing \"known v1 namespace UUID timestamp\"\n    ;; +namespace-x500+ has get-timestamp = 131059232331511828\n    ;; get-unix-time should convert to POSIX millis\n    (let [ut (get-unix-time +namespace-x500+)]\n      (is (some? ut))\n      (is (= 886630433151 ut))))\n\n  (testing \"known v6 UUID unix time\"\n    (let [u  #uuid \"1ef3f06f-16db-6ff0-bb01-1b50e6f39e7f\"\n          ut (get-unix-time u)]\n      (is (= 1720648452463 ut))))\n\n  (testing \"known v7 UUID unix time\"\n    (let [u  #uuid \"01909eae-4801-753a-bcd5-0889c34ac129\"\n          ut (get-unix-time u)]\n      (is (= 0x01909eae4801 ut)))))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; v0/null and max constructors\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(deftest check-constructors-v0-max\n  (testing \"null constructor\"\n    (is (= +null+ (null)))\n    (is (= +null+ (v0))))\n\n  (testing \"max constructor\"\n    (is (= +max+ (max))))\n\n  (testing \"null and max are distinct\"\n    (is (not= (null) (max)))))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; UUIDRfc4122 backwards compatibility alias\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(deftest check-backwards-compat-alias\n  (testing \"UUIDRfc4122 refers to the same protocol interface as UUIDRfc9562\"\n    (is (= (:on-interface UUIDRfc4122) (:on-interface UUIDRfc9562)))))\n"
  },
  {
    "path": "test/clj_uuid/bench.clj",
    "content": "(ns clj-uuid.bench\n  \"Benchmarks for clj-uuid UUID generation and post-generation operations.\n\n  Run:  lein test :only clj-uuid.bench\"\n  (:require [clojure.test :refer :all]\n            [clj-uuid     :as uuid]))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Benchmark Infrastructure\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(def ^:private ^:const +bench-n+ 500000)\n(def ^:private ^:const +warmup+   50000)\n\n(defn- bench-ns\n  \"Run `f` for `n` iterations after warmup. Returns average ns/op.\"\n  ^double [^long n f]\n  (dotimes [_ +warmup+] (f))\n  (let [start (System/nanoTime)]\n    (dotimes [_ n] (f))\n    (double (/ (- (System/nanoTime) start) n))))\n\n(defn- bench-print\n  \"Benchmark `f` and print a formatted result line. Returns map with label and ns.\"\n  [label f]\n  (let [ns-val (bench-ns +bench-n+ f)]\n    (println (format \"  %-34s  %8.1f ns\" label ns-val))\n    {:label label :ns ns-val}))\n\n(defn- print-md-table\n  \"Print results as a markdown table.\"\n  [header-label results]\n  (println)\n  (println (format \"| %-34s | %14s |\" header-label \"ns/op\"))\n  (println (format \"|%s|%s:|\" (apply str (repeat 36 \"-\")) (apply str (repeat 16 \"-\"))))\n  (doseq [{:keys [label ns]} results]\n    (println (format \"| %-34s | %14.1f   |\" label ns))))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; 1. UUID Generation (Pure Construction)\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(deftest bench-uuid-generation\n  (testing \"UUID Generation (Pure Construction)\"\n    (println)\n    (println \"=== 1. UUID Generation (Pure Construction) ===\")\n    (println)\n    (let [ns-uuid   uuid/+namespace-dns+\n          test-name \"www.example.com\"\n          results\n          [(bench-print \"v1 (time-based)\"            #(uuid/v1))\n           (bench-print \"v3 (MD5, namespace)\"        #(uuid/v3 ns-uuid test-name))\n           (bench-print \"v4 (random)\"                #(uuid/v4))\n           (bench-print \"v5 (SHA1, namespace)\"       #(uuid/v5 ns-uuid test-name))\n           (bench-print \"v6 (time-based, sorted)\"    #(uuid/v6))\n           (bench-print \"v7 (unix time, crypto)\"     #(uuid/v7))\n           (bench-print \"v7nc (unix time, fast)\"     #(uuid/v7nc))\n           (bench-print \"v8 (custom)\"                #(uuid/v8 0x123456789ABCDEF -1))]]\n      (println)\n      (print-md-table \"UUID Version\" results)\n\n      ;; Verify correctness\n      (is (= 1 (uuid/get-version (uuid/v1))))\n      (is (= 3 (uuid/get-version (uuid/v3 ns-uuid test-name))))\n      (is (= 4 (uuid/get-version (uuid/v4))))\n      (is (= 5 (uuid/get-version (uuid/v5 ns-uuid test-name))))\n      (is (= 6 (uuid/get-version (uuid/v6))))\n      (is (= 7 (uuid/get-version (uuid/v7))))\n      (is (= 7 (uuid/get-version (uuid/v7nc))))\n      (is (= 8 (uuid/get-version (uuid/v8 0x123456789ABCDEF -1))))\n      ;; v3/v5 are deterministic\n      (is (= (uuid/v3 ns-uuid test-name) (uuid/v3 ns-uuid test-name)))\n      (is (= (uuid/v5 ns-uuid test-name) (uuid/v5 ns-uuid test-name))))))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; 2. Post-Generation Operations\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(deftest bench-post-generation\n  (testing \"Post-Generation Operations\"\n    (println)\n    (println \"=== 2. Post-Generation Operations ===\")\n    (println)\n    (let [test-uuid (java.util.UUID/randomUUID)\n          results\n          [(bench-print \"to-byte-array\"  #(uuid/to-byte-array test-uuid))\n           (bench-print \"to-hex-string\"  #(uuid/to-hex-string test-uuid))\n           (bench-print \"to-string\"      #(uuid/to-string test-uuid))\n           (bench-print \"to-urn-string\"  #(uuid/to-urn-string test-uuid))\n           (bench-print \"get-version\"    #(uuid/get-version test-uuid))\n           (bench-print \"get-node-id\"    #(uuid/get-node-id test-uuid))]]\n      (println)\n      (print-md-table \"Operation\" results))))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; 3. Combined: Generate + Serialize\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(deftest bench-combined\n  (testing \"Combined: Generate + Serialize\"\n    (println)\n    (println \"=== 3. Combined: Generate + Serialize ===\")\n    (println)\n    (let [ns-uuid   uuid/+namespace-dns+\n          test-name \"www.example.com\"\n          results\n          [(bench-print \"v1 + to-byte-array\"\n             #(uuid/to-byte-array (uuid/v1)))\n           (bench-print \"v3 + to-byte-array\"\n             #(uuid/to-byte-array (uuid/v3 ns-uuid test-name)))\n           (bench-print \"v3 + to-hex-string\"\n             #(uuid/to-hex-string (uuid/v3 ns-uuid test-name)))\n           (bench-print \"v4 + to-byte-array\"\n             #(uuid/to-byte-array (uuid/v4)))\n           (bench-print \"v4 + to-hex-string\"\n             #(uuid/to-hex-string (uuid/v4)))\n           (bench-print \"v5 + to-byte-array\"\n             #(uuid/to-byte-array (uuid/v5 ns-uuid test-name)))\n           (bench-print \"v5 + to-hex-string\"\n             #(uuid/to-hex-string (uuid/v5 ns-uuid test-name)))\n           (bench-print \"v7 + to-byte-array\"\n             #(uuid/to-byte-array (uuid/v7)))]]\n      (println)\n      (print-md-table \"Operation\" results))))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; 4. Absolute Throughput\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(deftest bench-throughput\n  (testing \"Absolute Throughput (ops/sec)\"\n    (println)\n    (println \"=== 4. Absolute Throughput ===\")\n    (println)\n    (let [ns-uuid   uuid/+namespace-dns+\n          test-name \"www.example.com\"\n          versions  [[\"v1 (time-based)\"         #(uuid/v1)]\n                     [\"v3 (MD5, namespace)\"      #(uuid/v3 ns-uuid test-name)]\n                     [\"v4 (random)\"              #(uuid/v4)]\n                     [\"v5 (SHA1, namespace)\"     #(uuid/v5 ns-uuid test-name)]\n                     [\"v6 (time-based, sorted)\"  #(uuid/v6)]\n                     [\"v7 (unix time, crypto)\"   #(uuid/v7)]\n                     [\"v8 (custom)\"              #(uuid/v8 0x123 0x456)]]]\n      (println (format \"  %-34s  %18s\" \"UUID Version\" \"ops/s\"))\n      (println (format \"  %-34s  %18s\" (apply str (repeat 34 \"-\")) (apply str (repeat 18 \"-\"))))\n      (doseq [[label f] versions]\n        (let [ns-val (bench-ns +bench-n+ f)\n              ops    (long (/ 1e9 ns-val))]\n          (println (format \"  %-34s  %,18d\" label ops)))))))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; 5. v3/v5 Detailed Breakdown\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(deftest bench-v3-v5-detailed\n  (testing \"v3/v5 Detailed Breakdown\"\n    (println)\n    (println \"=== 5. v3/v5 Detailed Breakdown ===\")\n    (println)\n    (let [ns-uuid   uuid/+namespace-dns+\n          test-name \"www.example.com\"]\n\n      (println \"--- v3 (MD5) ---\")\n      (bench-print \"v3 generation\"\n        #(uuid/v3 ns-uuid test-name))\n      (let [v3-uuid (uuid/v3 ns-uuid test-name)]\n        (bench-print \"v3 + to-byte-array\"\n          #(uuid/to-byte-array v3-uuid))\n        (bench-print \"v3 + to-hex-string\"\n          #(uuid/to-hex-string v3-uuid))\n        (bench-print \"v3 + to-string\"\n          #(uuid/to-string v3-uuid)))\n\n      (println)\n      (println \"--- v5 (SHA1) ---\")\n      (bench-print \"v5 generation\"\n        #(uuid/v5 ns-uuid test-name))\n      (let [v5-uuid (uuid/v5 ns-uuid test-name)]\n        (bench-print \"v5 + to-byte-array\"\n          #(uuid/to-byte-array v5-uuid))\n        (bench-print \"v5 + to-hex-string\"\n          #(uuid/to-hex-string v5-uuid))\n        (bench-print \"v5 + to-string\"\n          #(uuid/to-string v5-uuid)))\n\n      ;; Correctness\n      (is (= 3 (uuid/get-version (uuid/v3 ns-uuid test-name))))\n      (is (= 5 (uuid/get-version (uuid/v5 ns-uuid test-name)))))))\n"
  },
  {
    "path": "test/clj_uuid/bitmop_test.clj",
    "content": "(ns clj-uuid.bitmop-test\n  (:require\n    [clojure.test    :refer :all]\n    [clj-uuid.bitmop :as b :refer :all])\n  (:import [java.nio ByteBuffer]\n           [java.util UUID]))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; 1. Correctness -- Bitwise Primitives\n;;\n;; Tests for mask, ldb, dpb, bit-count, byte casts, byte reassembly,\n;; and hex conversion.\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n\n(deftest check-bit-mask-operators\n  (testing \"bit-mask construction...\"\n    (is (= (mask 0 0)                       0))\n    (is (= (mask 0 1)                       0))\n    (is (= (mask 1 0)                       1))\n    (is (= (mask 2 0)                       3))\n    (is (= (mask 4 0)                      15))\n    (is (= (mask 8 0)                     255))\n    (is (= (mask 16 0)                  65535))\n    (is (= (mask 7 0)                     127))\n    (is (= (mask 8 8)                   65280))\n    (is (= (mask 8 4)                    4080))\n    (is (= (mask 64 0)                     -1))\n    (is (= (mask 63 1)                     -2))\n    (is (= (mask 60 4)                    -16))\n    (is (= (mask 32 0)             4294967295))\n    (is (= (mask 32 16)       281474976645120))\n    (is (= (mask 32 32)           -4294967296))\n    (is (= (mask 3 60)    8070450532247928832))\n    (is (= (mask 3 61)   -2305843009213693952))\n    (is (= (mask 4 60)   -1152921504606846976))\n    (is (= (mask 8  48)     71776119061217280))\n    (is (= (mask 16 48)      -281474976710656))\n    (is (= 3     (mask 2  0) (bit-or (mask 1  1) (mask 1 0))))\n    (is (= 15    (mask 4  0) (bit-or (mask 2  2) (mask 2 0))))\n    (is (= 15    (mask 4  0) (bit-or (mask 1  3) (mask 3 0))))\n    (is (= 255   (mask 8  0) (bit-or (mask 4  4) (mask 4 0))))\n    (is (= 255   (mask 8  0) (bit-or (mask 2  6) (mask 6 0))))\n    (is (= 255   (mask 8  0) (bit-or (mask 1  7) (mask 7 0))))\n    (is (= 65535 (mask 16 0) (bit-or (mask 8  8) (mask 8 0))))\n    (is (= 65535 (mask 16 0) (bit-or (mask 15 1) (mask 1 0))))\n    (is (= 65535 (mask 16 0) (bit-or (mask 5 11) (mask 11 0)))))\n  (testing \"bit-mask width computation...\"\n    (is (= 3    (mask-width  (mask 3 7))))\n    (is (= 3    (mask-width  (mask 3 0))))\n    (is (= 12   (mask-width  (mask 12 13))))\n    (is (= 30   (mask-width  (mask 30 32))))\n    (is (= 31   (mask-width  (mask 31 32))))\n    (is (= 32   (mask-width  (mask 32 0))))\n    (is (= 31   (mask-width  (mask 31 32))))\n    (is (= 62   (mask-width  (mask 62 0))))\n    (is (= 48   (mask-width  (mask 48 15))))\n    (is (= 64   (mask-width  (mask 64 0))))\n    (is (= 60   (mask-width  (mask 60 4))))\n    (is (= 31   (mask-width  (mask 31 33))))\n    (is (= 1    (mask-width  (mask 1  63)))))\n  (testing \"bit-mask offset computation...\"\n    (is (= 7    (mask-offset (mask 3 7))))\n    (is (= 0    (mask-offset (mask 3 0))))\n    (is (= 32   (mask-offset (mask 3 32))))\n    (is (= 0    (mask-offset (mask 0 0))))\n    (is (= 0    (mask-offset (mask 64 0))))\n    (is (= 63   (mask-offset (mask 1 63))))\n    (is (= 1    (mask-offset (mask 63 1))))))\n\n\n(deftest check-bitwise-primitives\n  (testing \"ldb...\"\n    (is (= 15 (ldb (mask 4 0)  (mask 32 0))))\n    (is (= 15 (ldb (mask 4 8)  (mask 32 0))))\n    (is (= 12 (ldb (mask 4 0)  (mask 32 2))))\n    (is (= -1 (ldb (mask 64 0) (mask 64 0))))\n    (is (= 0x7fffffffffffffff (ldb (mask 63 1) (mask 64 0))))\n    (is (= 0x0fffffffffffffff (ldb (mask 60 4) (mask 64 0))))\n    (is (= 1  (ldb (mask 1 63) (mask 64 0))))\n    (is (= 15 (ldb (mask 4 60) (mask 64 0))))\n    (is (= 7  (ldb (mask 4 60) (mask 63 0))))\n    (for [i (range 0 64)]\n      (is (= 1 (ldb (mask 1 i) (mask 64 0)))))\n    (for [i (range 0 61)]\n      (is (= 15 (ldb (mask 4 i) (mask 64 0))))))\n  (testing \"dpb...\"\n    (map #(is (= 0x3 %))\n      (for [i (range 8)]\n        (ldb (mask 4 (* i 4))\n          (dpb (mask 4 (* i 4)) (mask 64 0) 0x3))))\n    (map #(is (= %1 %2))\n      (into [] (map expt2 (range 7)))\n      (for [i (range 7)]\n        (ldb (mask 8 (* i 8))\n          (dpb (mask 8 (* i 8)) (mask 64 0) (bit-shift-left 0x1 i))))))\n  (testing \"bit-count...\"\n    (is (= (bit-count 0x01010101)      4))\n    (is (= (bit-count 0x77773333)     20))\n    (is (= (bit-count (mask 17 6))    17))\n    (is (= (bit-count (mask 32 8))    32))\n    (is (= (bit-count (mask 56 0))    56))\n    (is (= (bit-count (mask 64 0))    64))\n    (is (= (bit-count (mask 63 1))    63))\n    (is (= (bit-count -1)             64))\n    (is (= (bit-count -0xffffffff)    33))\n    (is (= (bit-count  0xffffffff)    32))\n    (is (= (bit-count 0)               0))\n    (is (= (bit-count (- (mask 62 0))) 3))))\n\n\n(deftest check-byte-cast-operators\n  (testing \"byte-cast ops...\"\n    (is (= (sb8 255) -1))\n    (is (= (sb8 127) 127))\n    (is (= (sb8 -128) -128))\n    (is (= (sb8 -254) 2))\n    (is (= (sb64 (mask 63 1)) -2))\n    (is (= (sb64 (mask 62 1)) 9223372036854775806))\n    (is (= (sb64 (mask 62 2)) -4))\n    (is (= (ub4 -1) 15))\n    (is (= (ub4 16) 0))\n    (is (= (ub4 15) 15))\n    (is (= (ub4 7)  7))\n    (is (= (ub56 0x80) 128))\n    (is (= (class (ub56 0x80)) Long))))\n\n\n(deftest check-byte-reassembly-roundtrip\n  (testing \"disassemble/reassemble-bytes...\"\n    (dotimes [_ 256]\n      (let [bytes (for [i (range 8)]\n                    (sb8 (rand-int (mask 8 0))))]\n        (is (= (seq (long->bytes (assemble-bytes bytes))) bytes))))))\n\n\n(deftest check-simple-octet-hex-mapping\n  (testing \"octet-hex mapping...\"\n    (is (= (octet-hex 0xff) \"FF\"))\n    (is (= (octet-hex 0x00) \"00\"))\n    (is (= (octet-hex 0x7a) \"7A\"))\n    (is (= (octet-hex 15)   \"0F\"))\n    (is (= (octet-hex 45)   \"2D\"))\n    (is (= (octet-hex 250)  \"FA\"))\n    (is (= (octet-hex 0x11) \"11\"))))\n\n\n(deftest check-hex-string-conversion\n  (testing \"hex string conversion...\"\n    (is (= (hex 0xff)                              \"00000000000000FF\"))\n    (is (= (hex 0xfff)                             \"0000000000000FFF\"))\n    (is (= (hex 0xefef)                            \"000000000000EFEF\"))\n    (is (= (hex 0xf0e0a01003)                      \"000000F0E0A01003\"))\n    (is (= (hex -1)                                \"FFFFFFFFFFFFFFFF\"))\n    (is (= (hex 256)                               \"0000000000000100\"))\n    (is (= (hex 255)                               \"00000000000000FF\"))\n    (is (= (hex 65536)                             \"0000000000010000\"))\n    (is (= (hex -1)                                \"FFFFFFFFFFFFFFFF\"))))\n\n\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; 3. ByteBuffer-Specific Tests\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n\n(deftest check-buffer-creation\n  (testing \"buffer 0-arity creates zeroed 16-byte buffer...\"\n    (let [buf (buffer)]\n      (is (instance? ByteBuffer buf))\n      (is (= 16 (.capacity buf)))\n      (is (= 0 (.getLong buf 0)))\n      (is (= 0 (.getLong buf 8)))))\n  (testing \"buffer 2-arity stores MSB and LSB...\"\n    (let [msb 0x0123456789ABCDEF\n          lsb (unchecked-long 0xFEDCBA9876543210)\n          ^ByteBuffer buf (buffer msb lsb)]\n      (is (= msb (.getLong buf 0)))\n      (is (= lsb (.getLong buf 8)))))\n  (testing \"buffer-from-bytes copies byte array contents...\"\n    (let [arr (byte-array 16)\n          msb (unchecked-long 0xDEADBEEF01020304)\n          lsb 0x0506070809101112]\n      (doto (ByteBuffer/wrap arr)\n        (.putLong 0 msb)\n        (.putLong 8 lsb))\n      (let [buf (buffer-from-bytes arr)]\n        (is (= msb (.getLong buf 0)))\n        (is (= lsb (.getLong buf 8)))\n        ;; verify it's independent (not sharing backing)\n        (aset-byte arr 0 0)\n        (is (= msb (.getLong buf 0)))))))\n\n\n(deftest check-buffer-typed-access\n  (testing \"put-byte / get-byte roundtrip...\"\n    (let [buf (buffer)]\n      (doseq [i (range 16)]\n        (put-byte buf i (* i 17))\n        (is (= (* i 17) (get-byte buf i))\n          (format \"byte at offset %d\" i)))))\n  (testing \"put-short / get-short roundtrip...\"\n    (let [buf (buffer)]\n      (put-short buf 0  0x0102)\n      (put-short buf 2  0xABCD)\n      (put-short buf 14 0xFFFF)\n      (is (= 0x0102 (get-short buf 0)))\n      (is (= 0xABCD (get-short buf 2)))\n      (is (= 0xFFFF (get-short buf 14)))))\n  (testing \"put-int / get-int roundtrip...\"\n    (let [buf (buffer)]\n      (put-int buf 0  0x01020304)\n      (put-int buf 4  0xDEADBEEF)\n      (put-int buf 12 0xFFFFFFFF)\n      (is (= 0x01020304 (get-int buf 0)))\n      (is (= 0xDEADBEEF (get-int buf 4)))\n      (is (= 0xFFFFFFFF (get-int buf 12)))))\n  (testing \"put-long / get-long roundtrip...\"\n    (let [buf (buffer)]\n      (put-long buf 0 0x0123456789ABCDEF)\n      (put-long buf 8 (unchecked-long 0xFEDCBA9876543210))\n      (is (= 0x0123456789ABCDEF (get-long buf 0)))\n      (is (= (unchecked-long 0xFEDCBA9876543210) (get-long buf 8)))))\n  (testing \"typed access reads byte-level data correctly...\"\n    ;; Write known bytes and verify typed reads\n    (let [buf (buffer 0x0102030405060708 0x090A0B0C0D0E0F10)]\n      (is (= 0x01 (get-byte buf 0)))\n      (is (= 0x08 (get-byte buf 7)))\n      (is (= 0x10 (get-byte buf 15)))\n      (is (= 0x0102 (get-short buf 0)))\n      (is (= 0x0506 (get-short buf 4)))\n      (is (= 0x01020304 (get-int buf 0)))\n      (is (= 0x05060708 (get-int buf 4))))))\n\n\n(deftest check-buffer-word-access\n  (testing \"get-msb / get-lsb...\"\n    (let [msb 0x0123456789ABCDEF\n          lsb (unchecked-long 0xFEDCBA9876543210)\n          buf (buffer msb lsb)]\n      (is (= msb (get-msb buf)))\n      (is (= lsb (get-lsb buf)))))\n  (testing \"set-msb / set-lsb...\"\n    (let [buf (buffer)]\n      (set-msb buf (unchecked-long 0xAAAAAAAAAAAAAAAA))\n      (set-lsb buf 0x5555555555555555)\n      (is (= (unchecked-long 0xAAAAAAAAAAAAAAAA) (get-msb buf)))\n      (is (= 0x5555555555555555 (get-lsb buf)))))\n  (testing \"set-msb / set-lsb are independent...\"\n    (let [buf (buffer 0x1111111111111111 0x2222222222222222)]\n      (set-msb buf (unchecked-long 0xFFFFFFFFFFFFFFFF))\n      (is (= -1 (get-msb buf)))\n      (is (= 0x2222222222222222 (get-lsb buf)))\n      (set-lsb buf 0)\n      (is (= -1 (get-msb buf)))\n      (is (= 0 (get-lsb buf))))))\n\n\n(deftest check-buffer-bit-field-operations\n  (testing \"ldb-buf extracts fields from buffer words...\"\n    (let [buf (buffer 0x0123456789ABCDEF (unchecked-long 0xFEDCBA9876543210))]\n      ;; Extract from MSB (word offset 0)\n      (is (= (b/ldb (b/mask 32 0) 0x0123456789ABCDEF)\n             (ldb-buf buf 0 (b/mask 32 0))))\n      (is (= (b/ldb (b/mask 16 48) 0x0123456789ABCDEF)\n             (ldb-buf buf 0 (b/mask 16 48))))\n      (is (= (b/ldb (b/mask 4 12) 0x0123456789ABCDEF)\n             (ldb-buf buf 0 (b/mask 4 12))))\n      ;; Extract from LSB (word offset 8)\n      (is (= (b/ldb (b/mask 48 0) (unchecked-long 0xFEDCBA9876543210))\n             (ldb-buf buf 8 (b/mask 48 0))))\n      (is (= (b/ldb (b/mask 2 62) (unchecked-long 0xFEDCBA9876543210))\n             (ldb-buf buf 8 (b/mask 2 62))))))\n  (testing \"dpb-buf deposits fields into buffer words...\"\n    (let [buf (buffer -1 -1)]\n      ;; Deposit version bits into MSB\n      (dpb-buf buf 0 (b/mask 4 12) 0x7)\n      (is (= 0x7 (ldb-buf buf 0 (b/mask 4 12))))\n      ;; Deposit variant bits into LSB\n      (dpb-buf buf 8 (b/mask 2 62) 0x2)\n      (is (= 0x2 (ldb-buf buf 8 (b/mask 2 62))))\n      ;; Non-targeted bits are preserved\n      (is (= (b/ldb (b/mask 12 0) -1)\n             (ldb-buf buf 0 (b/mask 12 0))))\n      (is (= (b/ldb (b/mask 48 0) (b/dpb (b/mask 2 62) -1 0x2))\n             (ldb-buf buf 8 (b/mask 48 0))))))\n  (testing \"dpb-buf returns the buffer for chaining...\"\n    (let [buf (buffer)]\n      (is (identical? buf (dpb-buf buf 0 (b/mask 4 12) 0x1))))))\n\n\n(deftest check-buffer-conversion\n  (testing \"buf->bytes produces correct 16-byte array...\"\n    (let [buf (buffer 0x0123456789ABCDEF (unchecked-long 0xFEDCBA9876543210))\n          arr (buf->bytes buf)]\n      (is (= 16 (alength arr)))\n      (is (= 0x0123456789ABCDEF (b/bytes->long arr 0)))\n      (is (= (unchecked-long 0xFEDCBA9876543210) (b/bytes->long arr 8)))))\n  (testing \"buffer-from-bytes -> buf->bytes roundtrip...\"\n    (dotimes [_ 100]\n      (let [arr (byte-array (repeatedly 16 #(unchecked-byte (rand-int 256))))\n            buf (buffer-from-bytes arr)\n            out (buf->bytes buf)]\n        (is (= (seq arr) (seq out))))))\n  (testing \"buf->uuid produces correct UUID...\"\n    (let [msb 0x0123456789ABCDEF\n          lsb (unchecked-long 0xFEDCBA9876543210)\n          buf (buffer msb lsb)\n          uuid (buf->uuid buf)]\n      (is (instance? UUID uuid))\n      (is (= msb (.getMostSignificantBits uuid)))\n      (is (= lsb (.getLeastSignificantBits uuid)))))\n  (testing \"uuid->buf produces correct buffer...\"\n    (let [uuid (UUID/randomUUID)\n          buf  (uuid->buf uuid)]\n      (is (= (.getMostSignificantBits uuid) (get-msb buf)))\n      (is (= (.getLeastSignificantBits uuid) (get-lsb buf)))))\n  (testing \"uuid->buf -> buf->uuid roundtrip...\"\n    (dotimes [_ 100]\n      (let [uuid (UUID/randomUUID)]\n        (is (= uuid (buf->uuid (uuid->buf uuid)))))))\n  (testing \"duplicate creates an independent copy...\"\n    (let [buf  (buffer (unchecked-long 0xAAAAAAAAAAAAAAAA) 0x5555555555555555)\n          copy (duplicate buf)]\n      (is (= (get-msb buf) (get-msb copy)))\n      (is (= (get-lsb buf) (get-lsb copy)))\n      ;; mutating copy doesn't affect original\n      (set-msb copy 0)\n      (is (= (unchecked-long 0xAAAAAAAAAAAAAAAA) (get-msb buf)))\n      (is (= 0 (get-msb copy))))))\n\n\n(deftest check-buffer-hex-and-string\n  (testing \"buf-hex produces correct 32-char hex string...\"\n    (let [buf (buffer 0x0123456789ABCDEF (unchecked-long 0xFEDCBA9876543210))]\n      (is (= \"0123456789ABCDEFFEDCBA9876543210\" (buf-hex buf))))\n    (let [buf (buffer 0 0)]\n      (is (= \"00000000000000000000000000000000\" (buf-hex buf))))\n    (let [buf (buffer -1 -1)]\n      (is (= \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\" (buf-hex buf)))))\n  (testing \"buf-str produces correct canonical UUID string...\"\n    (let [buf (buffer 0x0123456789ABCDEF (unchecked-long 0xFEDCBA9876543210))]\n      (is (= \"01234567-89AB-CDEF-FEDC-BA9876543210\" (buf-str buf))))\n    (let [buf (buffer 0 0)]\n      (is (= \"00000000-0000-0000-0000-000000000000\" (buf-str buf)))))\n  (testing \"buf-str matches UUID.toString for random UUIDs...\"\n    (dotimes [_ 100]\n      (let [uuid (UUID/randomUUID)\n            buf  (uuid->buf uuid)]\n        (is (= (.toUpperCase (.toString uuid)) (buf-str buf))))))\n  (testing \"hex->buf parses hex string correctly...\"\n    (let [hex-str \"0123456789ABCDEFFEDCBA9876543210\"\n          buf     (hex->buf hex-str)]\n      (is (= 0x0123456789ABCDEF (get-msb buf)))\n      (is (= (unchecked-long 0xFEDCBA9876543210) (get-lsb buf)))))\n  (testing \"hex->buf -> buf-hex roundtrip...\"\n    (dotimes [_ 100]\n      (let [uuid (UUID/randomUUID)\n            buf  (uuid->buf uuid)\n            hex1 (buf-hex buf)\n            buf2 (hex->buf hex1)\n            hex2 (buf-hex buf2)]\n        (is (= hex1 hex2)))))\n  (testing \"buf-hex matches bitmop/hex for MSB/LSB...\"\n    (dotimes [_ 50]\n      (let [uuid (UUID/randomUUID)\n            buf  (uuid->buf uuid)\n            msb  (.getMostSignificantBits uuid)\n            lsb  (.getLeastSignificantBits uuid)]\n        (is (= (str (b/hex msb) (b/hex lsb))\n               (buf-hex buf)))))))\n\n\n(deftest check-buffer-comparison\n  (testing \"buf-compare: equal buffers...\"\n    (is (= 0 (buf-compare (buffer 0 0) (buffer 0 0))))\n    (is (= 0 (buf-compare (buffer -1 -1) (buffer -1 -1))))\n    (is (= 0 (buf-compare\n               (buffer 0x0123456789ABCDEF 0)\n               (buffer 0x0123456789ABCDEF 0)))))\n  (testing \"buf-compare: MSB determines order...\"\n    (is (neg? (buf-compare (buffer 0 0) (buffer 1 0))))\n    (is (pos? (buf-compare (buffer 1 0) (buffer 0 0))))\n    ;; unsigned comparison: 0x8... is greater than 0x7... as unsigned\n    (is (pos? (buf-compare\n                (buffer (unchecked-long 0x8000000000000000) 0)\n                (buffer 0x7FFFFFFFFFFFFFFF 0)))))\n  (testing \"buf-compare: LSB breaks ties...\"\n    (is (neg? (buf-compare (buffer 1 0) (buffer 1 1))))\n    (is (pos? (buf-compare (buffer 1 1) (buffer 1 0))))\n    ;; unsigned LSB comparison\n    (is (pos? (buf-compare\n                (buffer 0 (unchecked-long 0x8000000000000000))\n                (buffer 0 0x7FFFFFFFFFFFFFFF)))))\n  (testing \"buf-compare: ordering matches UUID string ordering...\"\n    (dotimes [_ 100]\n      (let [u1  (UUID/randomUUID)\n            u2  (UUID/randomUUID)\n            b1  (uuid->buf u1)\n            b2  (uuid->buf u2)\n            ;; compare canonical uppercase strings lexicographically\n            str-cmp (compare (.toUpperCase (.toString u1))\n                             (.toUpperCase (.toString u2)))\n            buf-cmp (buf-compare b1 b2)]\n        (is (= (Long/signum str-cmp) (Long/signum buf-cmp))\n          (format \"ordering mismatch for %s vs %s\" u1 u2))))))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; 4. Performance -- bitmop Primitives\n;;\n;; Benchmarks the core bitmop operations:\n;;   - long->bytes / bytes->long  (ByteBuffer putLong/getLong)\n;;   - assemble-bytes             (shift-accumulation loop)\n;;   - hex                        (StringBuilder direct append)\n;;   - UUID buffer roundtrip      (uuid->buf / buf->uuid)\n;;   - buf-str vs UUID.toString   (StringBuilder vs JVM native)\n;;\n;; Results are printed to stdout.  No hard timing assertions are made\n;; (too fragile for CI), but correctness under load is verified.\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n\n(def ^:private +bench-iterations+ 100000)\n\n(defn- bench-ns\n  \"Run `f` for `n` iterations after warmup.  Returns average ns/op.\"\n  ^double [^long n f]\n  ;; warmup\n  (dotimes [_ (min n 10000)] (f))\n  ;; timed\n  (let [start (System/nanoTime)]\n    (dotimes [_ n] (f))\n    (double (/ (- (System/nanoTime) start) n))))\n\n(defn- bench-print\n  \"Benchmark `f` and print a formatted result line.  Returns ns/op.\"\n  [label n f]\n  (let [ns-val (bench-ns n f)]\n    (println (format \"  %-30s  %8.1f ns\" label ns-val))\n    ns-val))\n\n\n(deftest check-performance-long-bytes-roundtrip\n  (testing \"long->bytes / bytes->long performance...\"\n    (println)\n    (println \"--- Performance: long<->bytes ---\")\n    (let [test-val (unchecked-long 0xDEADBEEFCAFEBABE)]\n      (bench-print \"long->bytes\" +bench-iterations+\n        #(b/long->bytes test-val))\n      (let [arr (b/long->bytes test-val)]\n        (bench-print \"bytes->long\" +bench-iterations+\n          #(b/bytes->long arr 0)))\n      ;; roundtrip correctness under load\n      (dotimes [_ 10000]\n        (let [v (unchecked-long (long (* (Math/random) Long/MAX_VALUE)))]\n          (is (= v (b/bytes->long (b/long->bytes v) 0))))))))\n\n\n(deftest check-performance-assemble-bytes\n  (testing \"assemble-bytes performance...\"\n    (println)\n    (println \"--- Performance: assemble-bytes ---\")\n    (let [test-bytes (list (byte 0x01) (byte 0x02) (byte 0x03) (byte 0x04)\n                           (byte 0x05) (byte 0x06) (byte 0x07) (byte 0x08))]\n      (bench-print \"assemble-bytes\" +bench-iterations+\n        #(b/assemble-bytes test-bytes))\n      ;; correctness under load\n      (dotimes [_ 10000]\n        (let [bytes (for [_ (range 8)] (b/sb8 (rand-int 256)))\n              result (b/assemble-bytes bytes)]\n          (is (= result (b/bytes->long (byte-array (map unchecked-byte bytes)) 0))))))))\n\n\n(deftest check-performance-hex\n  (testing \"hex conversion performance...\"\n    (println)\n    (println \"--- Performance: hex ---\")\n    (let [test-val (unchecked-long 0xDEADBEEFCAFEBABE)]\n      (bench-print \"hex (long)\" +bench-iterations+\n        #(b/hex test-val))\n      ;; correctness under load\n      (dotimes [_ 10000]\n        (let [v (unchecked-long (long (* (Math/random) Long/MAX_VALUE)))]\n          (is (= 16 (count (b/hex v)))))))))\n\n\n(deftest check-performance-uuid-buffer-roundtrip\n  (testing \"UUID buffer roundtrip performance...\"\n    (println)\n    (println \"--- Performance: UUID buffer roundtrip ---\")\n    (let [msb 0x0123456789ABCDEF\n          lsb (unchecked-long 0xFEDCBA9876543210)\n          uuid (UUID. msb lsb)]\n      (bench-print \"UUID -> byte[] -> UUID\" +bench-iterations+\n        (fn []\n          (let [arr (byte-array 16)]\n            (b/long->bytes (.getMostSignificantBits uuid) arr 0)\n            (b/long->bytes (.getLeastSignificantBits uuid) arr 8)\n            (UUID. (b/bytes->long arr 0) (b/bytes->long arr 8)))))\n      (bench-print \"UUID -> buf -> UUID\" +bench-iterations+\n        #(buf->uuid (uuid->buf uuid)))\n      ;; correctness under load\n      (dotimes [_ 10000]\n        (let [u (UUID/randomUUID)]\n          (is (= u (buf->uuid (uuid->buf u)))))))))\n\n\n(deftest check-performance-buf-str\n  (testing \"buf-str performance...\"\n    (println)\n    (println \"--- Performance: UUID string rendering ---\")\n    (let [uuid (UUID. 0x0123456789ABCDEF (unchecked-long 0xFEDCBA9876543210))\n          buf  (uuid->buf uuid)]\n      (bench-print \"UUID.toString\" +bench-iterations+\n        #(.toString uuid))\n      (bench-print \"buf-str\" +bench-iterations+\n        #(buf-str buf))\n      ;; correctness under load\n      (dotimes [_ 1000]\n        (let [u   (UUID/randomUUID)\n              b   (uuid->buf u)]\n          (is (= (.toUpperCase (.toString u)) (buf-str b))))))))\n"
  },
  {
    "path": "test/clj_uuid/clock_test.clj",
    "content": "(ns clj-uuid.clock-test\n  (:require [clojure.test   :refer :all]\n            [clojure.set]\n            [clj-uuid.clock :refer :all])\n  (:import [clj_uuid.clock State]))\n\n(deftest check-single-threaded\n  (let [iterations 1000000\n        groups     10\n        check      #(mapv (fn [_] (%)) (range iterations))]\n    (testing \"monotonic-time...\"\n      (dotimes [_ groups]\n        (let [result   (check monotonic-time)]\n          (is (= (count result) (count (set result)))))))\n    (testing \"monotonic-unix-time-and-random-counter...\"\n      (dotimes [_ groups]\n        (let [result   (check monotonic-unix-time-and-random-counter)\n              pairs    (mapv #(vector (.millis ^State %) (.seqid ^State %)) result)]\n          (is (= (count pairs) (count (set pairs)))))))))\n\n(deftest check-multi-threaded-monotonic-time\n  (doseq [concur (range 0 9)]\n    (let [extent    1000000\n          agents    (mapv agent (repeat concur nil))\n          working   (mapv #(send-off %\n                            (fn [state]\n                              (repeatedly extent monotonic-time)))\n                      agents)\n          _         (apply await working)\n          answers   (mapv deref working)]\n      (testing (str \"concurrent timestamp uniqueness (\" concur \" threads)...\")\n        (is (= (* concur extent)\n               (count (apply clojure.set/union (map set answers))))))\n      (testing (str \"concurrent monotonic increasing (\" concur \" threads)...\")\n        (is (every? identity\n                    (map #(apply < %) answers)))))))\n\n(deftest check-multi-threaded-monotonic-unix-time-and-random-counter\n  (doseq [concur (range 0 9)]\n    (let [extent  1000000\n          agents  (mapv agent (repeat concur nil))\n          working (mapv #(send-off %\n                           (fn [state]\n                             (repeatedly extent\n                                         monotonic-unix-time-and-random-counter)))\n                         agents)\n          _       (apply await working)\n          answers (mapv deref working)]\n      (testing (str \"concurrent timestamp uniqueness (\" concur \" threads)...\")\n        (is (=\n              (* concur extent)\n              (count (apply clojure.set/union\n                       (map #(set (map (fn [^State s] [(.millis s) (.seqid s)]) %))\n                            answers))))))\n      (testing (str \"concurrent monotonic increasing (\" concur \" threads)...\")\n        (doseq [answer answers]\n          (let [^State first-state (first answer)]\n            (loop [time    (.millis first-state)\n                   counter (.seqid first-state)\n                   more    (rest answer)]\n              (when-let [^State next-state (first more)]\n                (let [next-time    (.millis next-state)\n                      next-counter (.seqid next-state)]\n                  (cond\n                    (< next-time time)\n                    (is false \"time must be increasing\")\n\n                    (and (= next-time time) (<= next-counter counter))\n                    (is false \"counter must be increasing\")\n\n                    :else\n                    (recur next-time next-counter (rest more))))))))))))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Time Conversion Functions\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(deftest check-posix-time-zero-arity\n  (testing \"posix-time with no args returns a number\"\n    (is (number? (posix-time)))))\n\n(deftest check-posix-time-with-arg\n  (testing \"posix-time converts gregorian to POSIX\"\n    (let [greg 131059232331511828\n          pt   (posix-time greg)]\n      (is (number? pt))\n      (is (= (- (quot 131059232331511828 10000) 12219292800000) pt)))))\n\n(deftest check-universal-time-zero-arity\n  (testing \"universal-time returns a number\"\n    (is (number? (universal-time)))))\n\n(deftest check-universal-time-with-arg\n  (testing \"universal-time converts gregorian to universal time\"\n    (let [greg 131059232331511828\n          ut   (universal-time greg)\n          pt   (posix-time greg)]\n      (is (= (+ pt 2208988800) ut)))))\n\n(deftest check-time-conversion-consistency\n  (testing \"posix-time and universal-time differ by epoch offset\"\n    (let [greg (monotonic-time)]\n      (is (= 2208988800 (- (universal-time greg) (posix-time greg)))))))\n"
  },
  {
    "path": "test/clj_uuid/compare_bench.clj",
    "content": "(ns clj-uuid.compare-bench\n  \"Apples-to-apples benchmarks: clj-uuid vs JUG vs uuid-creator vs JDK.\n\n  Run:  lein test :only clj-uuid.compare-bench\"\n  (:require [clojure.test :refer :all]\n            [clj-uuid     :as uuid])\n  (:import [java.util UUID]\n           [com.fasterxml.uuid Generators EthernetAddress]\n           [com.fasterxml.uuid.impl\n            TimeBasedGenerator\n            TimeBasedReorderedGenerator\n            TimeBasedEpochGenerator\n            NameBasedGenerator\n            RandomBasedGenerator]\n           [com.github.f4b6a3.uuid UuidCreator]))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Infrastructure\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(def ^:private ^:const +n+ 500000)\n(def ^:private ^:const +warmup+ 50000)\n\n(defn- bench-ns\n  \"Run f for n iterations after warmup. Returns average ns/op.\"\n  ^double [^long n f]\n  (dotimes [_ +warmup+] (f))\n  (let [start (System/nanoTime)]\n    (dotimes [_ n] (f))\n    (double (/ (- (System/nanoTime) start) n))))\n\n(defn- bench-row\n  \"Benchmark f, return [label ns/op].\"\n  [label f]\n  (let [ns-val (bench-ns +n+ f)]\n    [label ns-val]))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Generators — pre-initialize outside the timing loop\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(def ^:private ^TimeBasedGenerator          jug-v1  (Generators/timeBasedGenerator))\n(def ^:private ^RandomBasedGenerator        jug-v4  (Generators/randomBasedGenerator))\n(def ^:private ^NameBasedGenerator          jug-v5  (Generators/nameBasedGenerator))\n(def ^:private ^TimeBasedReorderedGenerator jug-v6  (Generators/timeBasedReorderedGenerator))\n(def ^:private ^TimeBasedEpochGenerator     jug-v7  (Generators/timeBasedEpochGenerator))\n\n(def ^:private ^UUID jug-ns-dns\n  (UUID/fromString \"6ba7b810-9dad-11d1-80b4-00c04fd430c8\"))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Print helpers\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(defn- print-table-header []\n  (println)\n  (println (format \"| %-20s | %14s | %14s | %14s | %14s |\"\n             \"Operation\" \"clj-uuid\" \"JUG 5.2\" \"uuid-creator\" \"JDK\"))\n  (println (format \"|%s|%s:|%s:|%s:|%s:|\"\n             (apply str (repeat 22 \"-\"))\n             (apply str (repeat 15 \"-\"))\n             (apply str (repeat 15 \"-\"))\n             (apply str (repeat 15 \"-\"))\n             (apply str (repeat 15 \"-\")))))\n\n(defn- fmt-ns [v]\n  (if v (format \"%10.1f ns\" v) (format \"%14s\" \"--\")))\n\n(defn- print-row [label clj-ns jug-ns uc-ns jdk-ns]\n  (println (format \"| %-20s | %14s | %14s | %14s | %14s |\"\n             label (fmt-ns clj-ns) (fmt-ns jug-ns) (fmt-ns uc-ns) (fmt-ns jdk-ns))))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Benchmarks\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(deftest bench-comparison\n  (testing \"Apples-to-apples UUID library comparison\"\n    (print-table-header)\n\n    ;; v1\n    (let [[_ clj]  (bench-row \"v1\" #(uuid/v1))\n          [_ jug]  (bench-row \"v1\" #(.generate jug-v1))\n          [_ uc]   (bench-row \"v1\" #(UuidCreator/getTimeBased))]\n      (print-row \"v1 (time-based)\" clj jug uc nil))\n\n    ;; v4\n    (let [[_ clj]  (bench-row \"v4\" #(uuid/v4))\n          [_ jug]  (bench-row \"v4\" #(.generate jug-v4))\n          [_ uc]   (bench-row \"v4\" #(UuidCreator/getRandomBased))\n          [_ jdk]  (bench-row \"v4\" #(UUID/randomUUID))]\n      (print-row \"v4 (random)\" clj jug uc jdk))\n\n    ;; v5\n    (let [[_ clj]  (bench-row \"v5\" #(uuid/v5 uuid/+namespace-dns+ \"www.example.com\"))\n          [_ jug]  (bench-row \"v5\" #(.generate jug-v5 \"www.example.com\"))\n          [_ uc]   (bench-row \"v5\" #(UuidCreator/getNameBasedSha1 jug-ns-dns \"www.example.com\"))]\n      (print-row \"v5 (SHA1)\" clj jug uc nil))\n\n    ;; v6\n    (let [[_ clj]  (bench-row \"v6\" #(uuid/v6))\n          [_ jug]  (bench-row \"v6\" #(.generate jug-v6))\n          [_ uc]   (bench-row \"v6\" #(UuidCreator/getTimeOrdered))]\n      (print-row \"v6 (time-ordered)\" clj jug uc nil))\n\n    ;; v7\n    (let [[_ clj]  (bench-row \"v7\" #(uuid/v7))\n          [_ jug]  (bench-row \"v7\" #(.generate jug-v7))\n          [_ uc]   (bench-row \"v7\" #(UuidCreator/getTimeOrderedEpoch))]\n      (print-row \"v7 (unix epoch)\" clj jug uc nil))\n\n    ;; v7nc\n    (let [[_ clj]  (bench-row \"v7nc\" #(uuid/v7nc))\n          [_ jug]  (bench-row \"v7nc\" #(.generate jug-v7))]\n      (print-row \"v7nc (fast epoch)\" clj jug nil nil))\n\n    ;; to-string\n    (let [u (uuid/v4)]\n      (let [[_ clj] (bench-row \"str\" #(uuid/to-string u))\n            [_ jdk] (bench-row \"str\" #(.toString u))]\n        (print-row \"to-string\" clj nil nil jdk)))\n\n    ;; to-byte-array\n    (let [u (uuid/v4)]\n      (let [[_ clj] (bench-row \"bytes\" #(uuid/to-byte-array u))]\n        (print-row \"to-byte-array\" clj nil nil nil)))\n\n    (println)\n\n    ;; Correctness checks\n    (is (= 1 (.version (.generate jug-v1))))\n    (is (= 4 (.version (.generate jug-v4))))\n    (is (= 5 (.version (.generate jug-v5 \"test\"))))\n    (is (= 6 (.version (.generate jug-v6))))\n    (is (= 7 (.version (.generate jug-v7))))\n    (is (= 1 (.version (UuidCreator/getTimeBased))))\n    (is (= 4 (.version (UuidCreator/getRandomBased))))\n    (is (= 6 (.version (UuidCreator/getTimeOrdered))))\n    (is (= 7 (.version (UuidCreator/getTimeOrderedEpoch))))))\n"
  },
  {
    "path": "test/clj_uuid/core_test.clj",
    "content": "(ns clj-uuid.core-test\n  \"Tests that exercise the clj-uuid.core namespace directly.\n  Mirrors api-test but requires from clj-uuid.core instead of clj-uuid.\"\n  (:refer-clojure :exclude [uuid? max])\n  (:require [clojure.test    :refer :all]\n            [clojure.string  :as str]\n            [clj-uuid.core   :refer :all :exclude [= > <]]\n            [clj-uuid.core   :as core]\n            [clj-uuid.clock  :as clock])\n  (:import\n   (java.lang IllegalArgumentException)\n   (java.net  URI URL)\n   (java.util Date UUID)))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Protocol Tests\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(deftest check-null-uuid-protocol\n  (let [tmpid +null+]\n    (is (= (get-word-high tmpid)       0))\n    (is (= (get-word-low tmpid)        0))\n    (is (= (null? tmpid)           true))\n    (is (= (seq (to-byte-array tmpid)) [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]))\n    (is (= (hash-code tmpid)       0))\n    (is (= (get-version tmpid)         0))\n    (is (= (to-string tmpid)       \"00000000-0000-0000-0000-000000000000\"))\n    (is (= (to-urn-string tmpid)\n           \"urn:uuid:00000000-0000-0000-0000-000000000000\"))\n    (is (= (get-time-low tmpid)       0))\n    (is (= (get-time-mid tmpid)       0))\n    (is (= (get-time-high tmpid)      0))\n    (is (= (get-clk-low tmpid)        0))\n    (is (= (get-clk-high tmpid)       0))\n    (is (= (get-node-id tmpid)        0))\n    (is (= (get-timestamp tmpid)      nil))\n    (is (= (get-unix-time tmpid)      nil))))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Constructor Tests\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(deftest check-v0-null-constructor\n  (is (= +null+ (null)))\n  (is (= +null+ (v0))))\n\n(deftest check-max-constructor\n  (is (= +max+ (max)))\n  (is (not= (null) (max))))\n\n(deftest check-v1-constructor\n  (testing \"v1 produces a valid version-1 UUID\"\n    (let [u (v1)]\n      (is (instance? UUID u))\n      (is (= 1 (get-version u)))\n      (is (= 2 (get-variant u))))))\n\n(deftest check-v1-uniqueness\n  (testing \"v1 UUIDs are unique\"\n    (let [uuids (repeatedly 10000 v1)]\n      (is (= 10000 (count (set uuids)))))))\n\n(deftest check-v3-constructor\n  (testing \"v3 produces deterministic UUID\"\n    (let [u1 (v3 +namespace-dns+ \"example.com\")\n          u2 (v3 +namespace-dns+ \"example.com\")]\n      (is (= u1 u2))\n      (is (= 3 (get-version u1)))\n      (is (= 2 (get-variant u1)))))\n\n  (testing \"different inputs produce different UUIDs\"\n    (is (not= (v3 +namespace-dns+ \"a\")\n              (v3 +namespace-dns+ \"b\")))))\n\n(deftest check-v4-constructor\n  (testing \"v4 zero-arity produces random UUID with correct bits\"\n    (dotimes [_ 1000]\n      (let [u (v4)]\n        (is (= 4 (get-version u)))\n        (is (= 2 (get-variant u))))))\n\n  (testing \"v4 two-arity stamps version and variant\"\n    (is (= 4 (get-version (v4 0 0))))\n    (is (= 2 (get-variant (v4 0 0))))\n    (is (= 4 (get-version (v4 -1 -1))))\n    (is (= 2 (get-variant (v4 -1 -1))))))\n\n(deftest check-v5-constructor\n  (testing \"v5 produces deterministic UUID\"\n    (let [u1 (v5 +namespace-dns+ \"example.com\")\n          u2 (v5 +namespace-dns+ \"example.com\")]\n      (is (= u1 u2))\n      (is (= 5 (get-version u1)))\n      (is (= 2 (get-variant u1)))))\n\n  (testing \"v3 and v5 produce different results for same input\"\n    (is (not= (v3 +namespace-dns+ \"example.com\")\n              (v5 +namespace-dns+ \"example.com\")))))\n\n(deftest check-v6-constructor\n  (testing \"v6 produces a valid version-6 UUID\"\n    (let [u (v6)]\n      (is (instance? UUID u))\n      (is (= 6 (get-version u)))\n      (is (= 2 (get-variant u))))))\n\n(deftest check-v6-uniqueness\n  (testing \"v6 UUIDs are unique\"\n    (let [uuids (repeatedly 10000 v6)]\n      (is (= 10000 (count (set uuids)))))))\n\n(deftest check-v7-constructor\n  (testing \"v7 produces valid version-7 UUID\"\n    (let [u (v7)]\n      (is (instance? UUID u))\n      (is (= 7 (get-version u)))\n      (is (= 2 (get-variant u))))))\n\n(deftest check-v7-uniqueness\n  (testing \"v7 UUIDs are unique\"\n    (let [uuids (repeatedly 10000 v7)]\n      (is (= 10000 (count (set uuids)))))))\n\n(deftest check-v8-constructor\n  (testing \"v8 stamps version=8 and variant=2\"\n    (is (= 8 (get-version (v8 0 0))))\n    (is (= 2 (get-variant (v8 0 0))))\n    (is (= 8 (get-version (v8 -1 -1))))\n    (is (= 2 (get-variant (v8 -1 -1))))))\n\n(deftest check-squuid-constructor\n  (testing \"squuid returns a v4 UUID\"\n    (let [s (squuid)]\n      (is (uuid? s))\n      (is (= 4 (get-version s)))\n      (is (= 2 (get-variant s)))))\n\n  (testing \"squuids are unique\"\n    (let [uuids (repeatedly 1000 squuid)]\n      (is (= 1000 (count (set uuids)))))))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Predicates and Coercion\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(deftest check-uuid?\n  (is (true?  (uuid? (v4))))\n  (is (true?  (uuid? +null+)))\n  (is (true?  (uuid? +max+)))\n  (is (false? (uuid? \"not-a-uuid\")))\n  (is (false? (uuid? 42)))\n  (is (false? (uuid? nil))))\n\n(deftest check-null?-max?\n  (is (true?  (null? +null+)))\n  (is (false? (null? +max+)))\n  (is (true?  (max? +max+)))\n  (is (false? (max? +null+))))\n\n(deftest check-string-predicates\n  (is (uuid-string?     (to-string     (v4))))\n  (is (uuid-urn-string? (to-urn-string (v4))))\n  (is (not (uuid-string? \"garbage\")))\n  (is (not (uuid-urn-string? \"garbage\")))\n  (is (not (uuid-string? nil)))\n  (is (not (uuid-urn-string? nil)))\n  (is (not (uuid-vec? nil))))\n\n(deftest check-uuidable?\n  (is (true?  (uuidable? (v4))))\n  (is (true?  (uuidable? \"6ba7b810-9dad-11d1-80b4-00c04fd430c8\")))\n  (is (true?  (uuidable? \"urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8\")))\n  (is (true?  (uuidable? (byte-array 16))))\n  (is (false? (uuidable? (byte-array 15))))\n  (is (false? (uuidable? \"not-a-uuid\")))\n  (is (false? (uuidable? nil)))\n  (is (false? (uuidable? 42))))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; as-uuid coercion\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(deftest check-as-uuid-string\n  (let [u (as-uuid \"6ba7b810-9dad-11d1-80b4-00c04fd430c8\")]\n    (is (= +namespace-dns+ u))))\n\n(deftest check-as-uuid-urn-string\n  (let [u (as-uuid \"urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8\")]\n    (is (= +namespace-dns+ u))))\n\n(deftest check-as-uuid-byte-array\n  (let [u  (v4)\n        ba (to-byte-array u)]\n    (is (= u (as-uuid ba)))))\n\n(deftest check-as-uuid-uri\n  (let [uri (URI/create \"urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8\")]\n    (is (= +namespace-dns+ (as-uuid uri)))))\n\n(deftest check-as-uuid-identity\n  (let [u (v4)]\n    (is (identical? u (as-uuid u)))))\n\n(deftest check-as-uuid-errors\n  (is (thrown? IllegalArgumentException (as-uuid nil)))\n  (is (thrown? IllegalArgumentException (as-uuid \"bad\")))\n  (is (thrown? IllegalArgumentException (as-uuid \"\"))))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; as-byte-array\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(deftest check-as-byte-array-types\n  (testing \"byte array passthrough\"\n    (let [ba (byte-array [1 2 3])]\n      (is (identical? ba (as-byte-array ba)))))\n\n  (testing \"String produces UTF-8 bytes\"\n    (let [ba (as-byte-array \"hello\")]\n      (is (= (seq (.getBytes \"hello\" \"UTF-8\")) (seq ba)))))\n\n  (testing \"URL produces bytes\"\n    (let [ba (as-byte-array (URL. \"http://example.com\"))]\n      (is (pos? (alength ^bytes ba)))))\n\n  (testing \"Object produces serialized bytes\"\n    (let [ba (as-byte-array (Long. 42))]\n      (is (pos? (alength ^bytes ba)))))\n\n  (testing \"nil throws\"\n    (is (thrown? IllegalArgumentException (as-byte-array nil)))))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Serialization\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(deftest check-to-string\n  (is (= \"00000000-0000-0000-0000-000000000000\" (to-string +null+)))\n  (is (= \"ffffffff-ffff-ffff-ffff-ffffffffffff\" (to-string +max+))))\n\n(deftest check-to-urn-string\n  (is (= \"urn:uuid:00000000-0000-0000-0000-000000000000\" (to-urn-string +null+)))\n  (is (= \"urn:uuid:ffffffff-ffff-ffff-ffff-ffffffffffff\" (to-urn-string +max+))))\n\n(deftest check-to-hex-string\n  (let [u (v4)\n        h (to-hex-string u)]\n    (is (= 32 (count h)))\n    (is (re-matches #\"[0-9A-Fa-f]{32}\" h)))\n  (is (= \"00000000000000000000000000000000\" (to-hex-string +null+)))\n  (is (= \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\" (to-hex-string +max+))))\n\n(deftest check-to-uri\n  (let [u   (v4)\n        uri (to-uri u)]\n    (is (instance? URI uri))\n    (is (= u (as-uuid uri)))))\n\n(deftest check-to-byte-array-roundtrip\n  (let [u  (v4)\n        ba (to-byte-array u)]\n    (is (= 16 (alength ^bytes ba)))\n    (is (= u (as-uuid ba)))))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Time accessors\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(deftest check-get-timestamp\n  (testing \"v1 has a timestamp\"\n    (is (some? (get-timestamp (v1)))))\n  (testing \"v6 has a timestamp\"\n    (is (some? (get-timestamp (v6)))))\n  (testing \"v7 has a timestamp\"\n    (is (some? (get-timestamp (v7)))))\n  (testing \"non-time-based return nil\"\n    (is (nil? (get-timestamp (v3 +namespace-dns+ \"x\"))))\n    (is (nil? (get-timestamp (v4))))\n    (is (nil? (get-timestamp (v5 +namespace-dns+ \"x\"))))\n    (is (nil? (get-timestamp (v8 0 0))))))\n\n(deftest check-get-unix-time\n  (testing \"v1 returns current POSIX millis\"\n    (let [before (System/currentTimeMillis)\n          ut     (get-unix-time (v1))\n          after  (System/currentTimeMillis)]\n      (is (some? ut))\n      (is (<= before ut after))))\n  (testing \"v6 returns current POSIX millis\"\n    (let [before (System/currentTimeMillis)\n          ut     (get-unix-time (v6))\n          after  (System/currentTimeMillis)]\n      (is (some? ut))\n      (is (<= before ut after))))\n  (testing \"v7 returns current POSIX millis\"\n    (let [before (System/currentTimeMillis)\n          ut     (get-unix-time (v7))\n          after  (System/currentTimeMillis)]\n      (is (some? ut))\n      (is (<= before ut after))))\n  (testing \"non-time-based return nil\"\n    (is (nil? (get-unix-time (v3 +namespace-dns+ \"x\"))))\n    (is (nil? (get-unix-time (v4))))\n    (is (nil? (get-unix-time (v5 +namespace-dns+ \"x\"))))\n    (is (nil? (get-unix-time (v8 0 0))))))\n\n(deftest check-get-instant\n  (testing \"v1 returns a Date\"\n    (let [inst (get-instant (v1))]\n      (is (instance? Date inst))))\n  (testing \"v6 returns a Date\"\n    (let [inst (get-instant (v6))]\n      (is (instance? Date inst))))\n  (testing \"v7 returns a Date\"\n    (let [inst (get-instant (v7))]\n      (is (instance? Date inst))))\n  (testing \"non-time-based return nil\"\n    (is (nil? (get-instant (v4))))\n    (is (nil? (get-instant +null+)))\n    (is (nil? (get-instant +max+)))))\n\n(deftest check-get-clk-seq\n  (testing \"v1 returns a clock sequence\"\n    (let [cs (get-clk-seq (v1))]\n      (is (some? cs))\n      (is (integer? cs))))\n  (testing \"v6 returns a clock sequence\"\n    (let [cs (get-clk-seq (v6))]\n      (is (some? cs))\n      (is (<= 0 cs 0x3FFF))))\n  (testing \"non-gregorian return nil\"\n    (is (nil? (get-clk-seq (v4))))\n    (is (nil? (get-clk-seq (v7))))))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Comparison operators\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(deftest check-multi-arity-comparisons\n  (testing \"single-arg always returns true\"\n    (let [u (v4)]\n      (is (core/= u))\n      (is (core/< u))\n      (is (core/> u))))\n\n  (testing \"two-arg = works\"\n    (let [u (v3 +namespace-dns+ \"same\")]\n      (is (core/= u u))\n      (is (not (core/= u (v4))))))\n\n  (testing \"three-arg =\"\n    (let [u (v3 +namespace-dns+ \"same\")]\n      (is (core/= u u u))\n      (is (not (core/= u u (v4))))))\n\n  (testing \"multi-arg < with ordered UUIDs\"\n    (let [a (v4 0 0)\n          b (v4 0x3000000000000000 0)\n          c (v4 0x5000000000000000 0)]\n      (is (core/< a b c))\n      (is (not (core/< a c b)))))\n\n  (testing \"multi-arg > with ordered UUIDs\"\n    (let [a (v4 0 0)\n          b (v4 0x3000000000000000 0)\n          c (v4 0x5000000000000000 0)]\n      (is (core/> c b a))\n      (is (not (core/> c a b)))))\n\n  (testing \"< and > with equal elements returns false\"\n    (let [u (v4)]\n      (is (not (core/< u u)))\n      (is (not (core/> u u))))))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Field extraction\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(deftest check-field-extraction\n  (let [u (v1)]\n    (is (integer? (get-word-high u)))\n    (is (integer? (get-word-low u)))\n    (is (integer? (get-time-low u)))\n    (is (integer? (get-time-mid u)))\n    (is (integer? (get-time-high u)))\n    (is (integer? (get-clk-low u)))\n    (is (integer? (get-clk-high u)))\n    (is (integer? (get-node-id u)))\n    (is (integer? (hash-code u)))\n    (is (integer? (get-variant u)))))\n\n(deftest check-get-version-all-types\n  (is (= 0  (get-version +null+)))\n  (is (= 1  (get-version (v1))))\n  (is (= 3  (get-version (v3 +namespace-dns+ \"x\"))))\n  (is (= 4  (get-version (v4))))\n  (is (= 5  (get-version (v5 +namespace-dns+ \"x\"))))\n  (is (= 6  (get-version (v6))))\n  (is (= 7  (get-version (v7))))\n  (is (= 8  (get-version (v8 0 0))))\n  (is (= 15 (get-version +max+))))\n\n(deftest check-get-variant-all-types\n  (is (= 0 (get-variant +null+)))\n  (is (= 2 (get-variant (v1))))\n  (is (= 2 (get-variant (v3 +namespace-dns+ \"x\"))))\n  (is (= 2 (get-variant (v4))))\n  (is (= 2 (get-variant (v5 +namespace-dns+ \"x\"))))\n  (is (= 2 (get-variant (v6))))\n  (is (= 2 (get-variant (v7))))\n  (is (= 2 (get-variant (v8 0 0))))\n  (is (= 7 (get-variant +max+))))\n\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Backward compat alias\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n(deftest check-rfc4122-alias\n  (is (= (:on-interface UUIDRfc4122) (:on-interface UUIDRfc9562))))\n"
  },
  {
    "path": "test/clj_uuid/node_test.clj",
    "content": "(ns clj-uuid.node-test\n  (:require [clojure.test   :refer :all]\n            [clj-uuid.node  :refer :all]))\n\n\n(deftest check-node-id\n  (testing \"existance and type of node id...\")\n  (is (= (node-id) (node-id)))\n  (is (coll? (node-id)))\n  (is (= 6 (count (node-id))))\n  (is (every? number? (node-id)))\n  (is (= 1 (bit-and 0x01 @+node-id+)))\n  (is (instance? Long @+node-id+)))\n"
  },
  {
    "path": "test/clj_uuid/random_test.clj",
    "content": "(ns clj-uuid.random-test\n  (:refer-clojure :exclude [bytes long])\n  (:require [clojure.test    :refer :all]\n            [clj-uuid.random :refer :all]))\n\n(deftest check-bytes\n  (testing \"returns byte array of requested length\"\n    (doseq [n [1 4 8 16 32]]\n      (let [bs (bytes n)]\n        (is (= (Class/forName \"[B\") (class bs)))\n        (is (= n (alength ^bytes bs))))))\n\n  (testing \"two calls return different bytes\"\n    (let [a (seq (bytes 16))\n          b (seq (bytes 16))]\n      (is (not= a b)\n          \"extremely unlikely to produce identical 128-bit sequences\"))))\n\n(deftest check-long-zero-arity\n  (testing \"returns a long\"\n    (is (instance? Long (long))))\n\n  (testing \"two calls return different values\"\n    (let [vals (repeatedly 100 long)]\n      (is (< 90 (count (set vals)))\n          \"should produce mostly distinct values\"))))\n\n(deftest check-long-n-bytes\n  (testing \"single byte produces value in signed byte range [-128, 127]\"\n    ;; bytes() returns signed Java bytes; the reduce uses (+ (bit-shift-left n 8) b)\n    ;; with initial accumulator 0, so a single byte gives [-128, 127]\n    (dotimes [_ 1000]\n      (let [v (long 1)]\n        (is (<= -128 v 127)))))\n\n  (testing \"two bytes produces value in signed 2-byte range\"\n    ;; reduce folds: b0*256 + b1 where b0,b1 in [-128,127]\n    ;; min: -128*256 + (-128) = -32896\n    ;; max: 127*256 + 127 = 32639\n    (dotimes [_ 1000]\n      (let [v (long 2)]\n        (is (<= -32896 v 32639))))))\n\n(deftest check-eight-bits\n  (testing \"returns values in [0, 255]\"\n    (dotimes [_ 10000]\n      (let [v (eight-bits)]\n        (is (<= 0 v 255))))))\n\n(deftest check-ten-bits\n  (testing \"returns values in [0, 1023]\"\n    (dotimes [_ 10000]\n      (let [v (ten-bits)]\n        (is (<= 0 v 1023))))))\n\n(deftest check-eleven-bits\n  (testing \"returns values in [0, 2047]\"\n    (dotimes [_ 10000]\n      (let [v (eleven-bits)]\n        (is (<= 0 v 2047))))))\n\n(deftest check-twelve-bits\n  (testing \"returns values in [0, 4095]\"\n    (dotimes [_ 10000]\n      (let [v (twelve-bits)]\n        (is (<= 0 v 4095))))))\n\n(deftest check-bit-functions-distribution\n  (testing \"N-bit functions use full range (statistical)\"\n    ;; Generate enough samples to statistically confirm the high bit is used.\n    ;; With 10000 samples, P(all < half-range) is vanishingly small.\n    (let [n       10000\n          eights  (repeatedly n eight-bits)\n          tens    (repeatedly n ten-bits)\n          elevens (repeatedly n eleven-bits)\n          twelves (repeatedly n twelve-bits)]\n      (is (some #(> % 127) eights)  \"eight-bits should use bit 7\")\n      (is (some #(> % 511) tens)    \"ten-bits should use bit 9\")\n      (is (some #(> % 1023) elevens) \"eleven-bits should use bit 10\")\n      (is (some #(> % 2047) twelves) \"twelve-bits should use bit 11\"))))\n"
  },
  {
    "path": "test/clj_uuid/util_test.clj",
    "content": "(ns clj-uuid.util-test\n  (:require [clojure.test  :refer :all]\n            [clj-uuid.util :refer :all]))\n\n(deftest check-returning\n  (testing \"returns first value, executes side effects\"\n    (let [side-effect (atom nil)]\n      (is (= 42 (returning 42\n                  (reset! side-effect :done))))\n      (is (= :done @side-effect))))\n\n  (testing \"returns first value with no side effects\"\n    (is (= :hello (returning :hello))))\n\n  (testing \"multiple side effects\"\n    (let [log (atom [])]\n      (is (= \"result\"\n             (returning \"result\"\n               (swap! log conj :a)\n               (swap! log conj :b))))\n      (is (= [:a :b] @log)))))\n\n(deftest check-java6?\n  (testing \"current JVM is not Java 6\"\n    ;; We're running on JDK 25, so java6? should be false\n    (is (false? (java6?)))))\n\n(deftest check-compile-if\n  (testing \"compile-if with truthy expression\"\n    (is (= :then (compile-if true :then :else))))\n\n  (testing \"compile-if with falsy expression\"\n    (is (= :else (compile-if false :then :else))))\n\n  (testing \"compile-if with exception-throwing expression\"\n    (is (= :else (compile-if (throw (Exception. \"boom\")) :then :else)))))\n\n(deftest check-with-timing\n  (testing \"returns [result elapsed-ms] pair\"\n    (let [[result ms] (with-timing (+ 1 2))]\n      (is (= 3 result))\n      (is (number? ms))\n      (is (>= ms 0.0))))\n\n  (testing \"measures non-trivial time\"\n    (let [[result ms] (with-timing (Thread/sleep 10) :done)]\n      (is (= :done result))\n      (is (>= ms 5.0) \"sleep 10ms should measure at least 5ms\"))))\n\n(deftest check-with-temp-file\n  (testing \"creates and deletes temp file\"\n    (let [path (atom nil)]\n      (with-temp-file f\n        (reset! path (.getAbsolutePath f))\n        (is (.exists f))\n        (spit f \"test content\")\n        (is (= \"test content\" (slurp f))))\n      (is (not (.exists (java.io.File. @path)))\n          \"temp file should be deleted\")))\n\n  (testing \"cleans up on exception\"\n    (let [path (atom nil)]\n      (try\n        (with-temp-file f\n          (reset! path (.getAbsolutePath f))\n          (throw (Exception. \"test\")))\n        (catch Exception _))\n      (is (not (.exists (java.io.File. @path)))\n          \"temp file should be deleted even on exception\"))))\n\n(defn ^:dynamic test-fn-for-wrap [x] (* x 2))\n\n(deftest check-wrap-fn\n  (testing \"wrap-fn wraps a function\"\n    (let [original (var-get #'test-fn-for-wrap)]\n      (wrap-fn test-fn-for-wrap [a] {:wrapped a})\n      (is (= {:wrapped 5} (test-fn-for-wrap 5)))\n      ;; Restore original\n      (alter-var-root #'test-fn-for-wrap (constantly original)))))\n\n(deftest check-lines-of-file\n  (testing \"reads lines from a temp file\"\n    (with-temp-file f\n      (spit f \"line1\\nline2\\nline3\")\n      (let [lines (doall (lines-of-file (.getAbsolutePath f)))]\n        (is (= [\"line1\" \"line2\" \"line3\"] lines))))))\n"
  },
  {
    "path": "test/clj_uuid/v1_test.clj",
    "content": "(ns clj-uuid.v1-test\n  \"Time based UUIDs tests\"\n  (:require [clojure.test   :refer :all]\n            [clojure.set]\n            [clj-uuid :as uuid :refer [v1 get-timestamp]]\n            [clj-uuid.clock :as clock]))\n\n(deftest check-v1-single-threaded\n  (let [iterations 1000000\n        groups     10]\n    (testing \"single-thread v1 uuid uniqueness...\"\n      (dotimes [_ groups]\n        (let [result (repeatedly iterations v1)]\n          (is (= (count result) (count (set result)))))))))\n\n(deftest check-v1-concurrency\n  (doseq [concur (range 2 9)]\n    (let [extent    1000000\n          agents    (map agent (repeat concur nil))\n          working   (map #(send-off %\n                            (fn [state]\n                              (repeatedly extent v1)))\n                      agents)\n          _         (apply await working)\n          answers   (map deref working)]\n      (testing (str \"concurrent v1 uuid uniqueness (\" concur \" threads)...\")\n        (is (= (* concur extent)\n               (count (apply clojure.set/union (map set answers))))))\n      (testing (str \"concurrent v1 monotonic increasing (\" concur \" threads)...\")\n        (is (every? identity\n              (map #(apply < (map get-timestamp %)) answers)))))))\n\n(deftest check-get-timestamp\n  (testing \"timestamp round-trip through v1 UUID\"\n    (dotimes [_ 100000]\n      (let [before (clock/monotonic-time)\n            u      (v1)\n            after  (clock/monotonic-time)]\n        (is (<= before (uuid/get-timestamp u) after))))))\n"
  },
  {
    "path": "test/clj_uuid/v3_test.clj",
    "content": "(ns clj-uuid.v3-test\n  (:refer-clojure :exclude [uuid? max])\n  (:require [clojure.test   :refer :all]\n            [clj-uuid       :refer :all :exclude [> < =]]))\n\n\n(deftest check-v3-special-cases\n  (testing \"v3 special case correctness...\"\n    (is (=\n          (v3 +null+ \"\")\n          #uuid \"4ae71336-e44b-39bf-b9d2-752e234818a5\"))\n    (is (=\n          (v3 +namespace-x500+ \"\")\n          #uuid \"7AAF118C-F174-3EBA-9EC5-680CD791A020\"))\n    (is (=\n          (v3 +namespace-oid+ \"\")\n          #uuid \"596B79DC-00DD-3991-A72F-D3696C38C64F\"))\n    (is (=\n          (v3 +namespace-dns+ \"\")\n          #uuid \"C87EE674-4DDC-3EFE-A74E-DFE25DA5D7B3\"))\n    (is (=\n          (v3 +namespace-url+ \"\")\n          #uuid \"14CDB9B4-DE01-3FAA-AFF5-65BC2F771745\"))))\n\n\n(def +v3-null-ns-cases+\n  '((\" !\\\"#$%&'()*+,-./0123456789\" #uuid \"84527A03-63CA-381A-8AFB-CF4244EF61FE\")\n    (\"!\\\"#$%&'()*+,-./0123456789:\" #uuid \"50D816D1-EEBA-3CA5-9C84-2C1C81EA53EF\")\n    (\"\\\"#$%&'()*+,-./0123456789:;\" #uuid \"A52D645C-B81C-3DD9-8AC7-E3B9E27B7399\")\n    (\"#$%&'()*+,-./0123456789:;<\" #uuid \"2F73C64B-D58B-3714-93A0-5208599BDD84\")\n    (\"$%&'()*+,-./0123456789:;<=\" #uuid \"3624A1E8-15D2-35CD-90E3-A482CF6ED426\")\n    (\"%&'()*+,-./0123456789:;<=>\" #uuid \"B75CCFA3-6E9E-301A-A7E7-80DF0EFB5E11\")\n    (\"&'()*+,-./0123456789:;<=>?\" #uuid \"CC1CA3BD-9FEA-348E-8133-857306B90520\")\n    (\"'()*+,-./0123456789:;<=>?@\" #uuid \"A7C27CC9-4F2D-3155-88AF-2E10A000A929\")\n    (\"()*+,-./0123456789:;<=>?@A\" #uuid \"A9B01A6B-6ECB-3754-A397-7C92BCB34233\")\n    (\")*+,-./0123456789:;<=>?@AB\" #uuid \"31FB5B5C-0CAC-3C90-B6CD-9443645F4FD7\")\n    (\"*+,-./0123456789:;<=>?@ABC\" #uuid \"47F741D2-E7E8-3D96-86D7-C955CDE87E0D\")\n    (\"+,-./0123456789:;<=>?@ABCD\" #uuid \"8EFFE6B8-1B60-35C7-BE1E-6D67A3FF5D55\")\n    (\",-./0123456789:;<=>?@ABCDE\" #uuid \"6FE5CED9-30CF-3D2A-92A0-9D0AFB1A857C\")\n    (\"-./0123456789:;<=>?@ABCDEF\" #uuid \"F9AF2E93-0DF6-3C2E-BEE9-137ED731385D\")\n    (\"./0123456789:;<=>?@ABCDEFG\" #uuid \"F5053601-F75F-39AB-8FB7-AD3A4919953A\")\n    (\"/0123456789:;<=>?@ABCDEFGH\" #uuid \"E3219C41-1396-32E5-9A03-8BED1F9F3BCC\")\n    (\"0123456789:;<=>?@ABCDEFGHI\" #uuid \"94486C0C-5882-3490-9B5C-FDA8823BCD9C\")\n    (\"123456789:;<=>?@ABCDEFGHIJ\" #uuid \"ABCB5CCC-7BCA-3388-B8A9-CA8888672F1B\")\n    (\"23456789:;<=>?@ABCDEFGHIJK\" #uuid \"96C62C75-1B95-3A99-A68B-C0A98AF6652F\")\n    (\"3456789:;<=>?@ABCDEFGHIJKL\" #uuid \"F93BE46D-0C6F-34E0-94EA-E7390A3BFAAD\")\n    (\"456789:;<=>?@ABCDEFGHIJKLM\" #uuid \"8F558F64-472C-341E-B49E-A6743F54CC16\")\n    (\"56789:;<=>?@ABCDEFGHIJKLMN\" #uuid \"2F4B6958-3FB4-3FD4-952A-861A7919A25C\")\n    (\"6789:;<=>?@ABCDEFGHIJKLMNO\" #uuid \"FC83A94A-75AF-3E47-A633-10E784D5E311\")\n    (\"789:;<=>?@ABCDEFGHIJKLMNOP\" #uuid \"9DA1321F-1A84-3FAB-A494-307C0E37938D\")\n    (\"89:;<=>?@ABCDEFGHIJKLMNOPQ\" #uuid \"FC9CED61-35EF-3386-BF8E-31F9DA844323\")\n    (\"9:;<=>?@ABCDEFGHIJKLMNOPQR\" #uuid \"80E91EB9-0298-30C8-B582-750262D42D4B\")\n    (\":;<=>?@ABCDEFGHIJKLMNOPQRS\" #uuid \"2862A3CE-0115-39F9-A08F-4F26445C7C07\")\n    (\";<=>?@ABCDEFGHIJKLMNOPQRST\" #uuid \"94CDB337-4C2D-3AAD-BDE4-A895060CC460\")\n    (\"<=>?@ABCDEFGHIJKLMNOPQRSTU\" #uuid \"55F086BC-9EB0-3F2E-B0BC-F0BF637475D4\")\n    (\"=>?@ABCDEFGHIJKLMNOPQRSTUV\" #uuid \"9F6FC7D5-7353-306D-BCDA-37B166A48755\")\n    (\">?@ABCDEFGHIJKLMNOPQRSTUVW\" #uuid \"E5DA63AF-8285-300E-A518-2F553A2BBC7D\")\n    (\"?@ABCDEFGHIJKLMNOPQRSTUVWX\" #uuid \"54962C09-F4CC-3EAC-B2A8-F4CF6E53C86D\")\n    (\"@ABCDEFGHIJKLMNOPQRSTUVWXY\" #uuid \"D0CA9015-8176-3490-A119-1FBBA7833F7C\")\n    (\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\" #uuid \"1F1723EB-AEB7-32C6-9221-B43CF93434AE\")\n    (\"BCDEFGHIJKLMNOPQRSTUVWXYZ[\" #uuid \"990A8C1A-01A9-3088-B275-A0EDCF171118\")\n    (\"CDEFGHIJKLMNOPQRSTUVWXYZ[\\\\\" #uuid \"E54DC0F1-8DAC-3372-8938-4C77BBF4A795\")\n    (\"DEFGHIJKLMNOPQRSTUVWXYZ[\\\\]\" #uuid \"DACA530A-D409-3DB5-AC3E-16FAC891EB8B\")\n    (\"EFGHIJKLMNOPQRSTUVWXYZ[\\\\]^\" #uuid \"EC762B89-AE25-34DD-B267-77BA166D4C39\")\n    (\"FGHIJKLMNOPQRSTUVWXYZ[\\\\]^_\" #uuid \"D99667DF-7B0A-335D-8889-31D54CC1D0C0\")\n    (\"GHIJKLMNOPQRSTUVWXYZ[\\\\]^_`\" #uuid \"E1BD4B67-B324-3D93-B3AD-F2F7F5BC346C\")\n    (\"HIJKLMNOPQRSTUVWXYZ[\\\\]^_`a\" #uuid \"9BA6966F-5425-3816-B53A-CAEDBB979028\")\n    (\"IJKLMNOPQRSTUVWXYZ[\\\\]^_`ab\" #uuid \"E25019D1-332E-376B-BA06-5EA4EBF8FC8A\")\n    (\"JKLMNOPQRSTUVWXYZ[\\\\]^_`abc\" #uuid \"B3BC1638-4A04-3B4C-9191-82D1D70356CF\")\n    (\"KLMNOPQRSTUVWXYZ[\\\\]^_`abcd\" #uuid \"2F528BEC-A02E-3844-9267-B45FE9E7A860\")\n    (\"LMNOPQRSTUVWXYZ[\\\\]^_`abcde\" #uuid \"6B13CD75-382B-334C-B511-797C9305DB8C\")\n    (\"MNOPQRSTUVWXYZ[\\\\]^_`abcdef\" #uuid \"CFE5D94D-6634-3011-B616-9D634DCC7533\")\n    (\"NOPQRSTUVWXYZ[\\\\]^_`abcdefg\" #uuid \"7D2E3761-8E9C-3828-96E6-854F4F678C81\")\n    (\"OPQRSTUVWXYZ[\\\\]^_`abcdefgh\" #uuid \"FE71897C-B88F-36CA-9765-757A82E24AE4\")\n    (\"PQRSTUVWXYZ[\\\\]^_`abcdefghi\" #uuid \"6101A664-0DB3-30DD-B04D-F8B6BA0EA255\")\n    (\"QRSTUVWXYZ[\\\\]^_`abcdefghij\" #uuid \"EB769B0A-F62A-3EA3-BA7D-191471D4A016\")\n    (\"RSTUVWXYZ[\\\\]^_`abcdefghijk\" #uuid \"628CB7F4-CC8E-34C1-A905-44D3558C247B\")\n    (\"STUVWXYZ[\\\\]^_`abcdefghijkl\" #uuid \"1AE38A2F-EDF5-3BC4-AD63-E005EF35077E\")\n    (\"TUVWXYZ[\\\\]^_`abcdefghijklm\" #uuid \"24C25E2E-CF08-3216-8BBC-521C4BD61AFC\")\n    (\"UVWXYZ[\\\\]^_`abcdefghijklmn\" #uuid \"E023C41B-3A85-3AB3-A18C-A87FFC84CF53\")\n    (\"VWXYZ[\\\\]^_`abcdefghijklmno\" #uuid \"27B13D02-E89E-3E30-8ABB-A43F8A8858FD\")\n    (\"WXYZ[\\\\]^_`abcdefghijklmnop\" #uuid \"5DC9BA7C-30FC-3476-BBC3-FD45898C24AF\")\n    (\"XYZ[\\\\]^_`abcdefghijklmnopq\" #uuid \"BF707BBE-53B0-3E29-BF53-BFE88A1BAE5D\")\n    (\"YZ[\\\\]^_`abcdefghijklmnopqr\" #uuid \"B8837DD6-6BF0-3D9F-BDE4-D2D6AFF011F0\")\n    (\"Z[\\\\]^_`abcdefghijklmnopqrs\" #uuid \"A88482D3-07EB-3FFF-B030-7D35B4E372F1\")\n    (\"[\\\\]^_`abcdefghijklmnopqrst\" #uuid \"06FA4DAE-2EC9-3E9F-A01C-1DEC8F009F47\")\n    (\"\\\\]^_`abcdefghijklmnopqrstu\" #uuid \"33B53814-8A07-3AAB-85BB-0897254CF7D3\")\n    (\"]^_`abcdefghijklmnopqrstuv\" #uuid \"75543166-1164-3C52-9E18-688690CF9750\")\n    (\"^_`abcdefghijklmnopqrstuvw\" #uuid \"F5D74A6C-A216-310B-9568-652A0640E277\")\n    (\"_`abcdefghijklmnopqrstuvwx\" #uuid \"21D2CD4B-5CEC-3C0C-ABF4-87A256F37745\")\n    (\"`abcdefghijklmnopqrstuvwxy\" #uuid \"C520DDB7-E9E5-3D05-9157-F2157DEB08CE\")\n    (\"abcdefghijklmnopqrstuvwxyz\" #uuid \"6B95E2CC-5E76-365C-9C53-5DDAD84E612A\")\n    (\"bcdefghijklmnopqrstuvwxyz{\" #uuid \"DEDE6550-14B9-3213-9660-661C46879AC1\")\n    (\"cdefghijklmnopqrstuvwxyz{|\" #uuid \"4DC61324-36A9-3305-97FA-04F8461A8656\")\n    (\"defghijklmnopqrstuvwxyz{|}\" #uuid \"ED828E85-BB8D-327B-92AD-366F29E9C804\")\n    (\"efghijklmnopqrstuvwxyz{|}~\" #uuid \"925484B7-F24E-35FA-B607-6625301C99E9\")\n    (\"fghijklmnopqrstuvwxyz{|}~ \" #uuid \"3EDFBE37-E082-3C35-97EB-9547B53E8E49\")\n    (\"ghijklmnopqrstuvwxyz{|}~ !\" #uuid \"8A18A7D7-3C2B-3594-8C1C-9DE815BD26AD\")\n    (\"hijklmnopqrstuvwxyz{|}~ !\\\"\" #uuid \"C1834810-8486-32CD-9EEC-90FFDCF84D28\")\n    (\"ijklmnopqrstuvwxyz{|}~ !\\\"#\" #uuid \"42CFD52A-8177-3F5C-899A-586FB8B86BB4\")\n    (\"jklmnopqrstuvwxyz{|}~ !\\\"#$\" #uuid \"7535FABD-FA47-3569-B74D-D1FE338503FB\")\n    (\"klmnopqrstuvwxyz{|}~ !\\\"#$%\" #uuid \"2EEA92DB-5A9F-3469-9CA9-AC7391EBD520\")\n    (\"lmnopqrstuvwxyz{|}~ !\\\"#$%&\" #uuid \"8A13DB2B-ACC9-3A40-AF19-B283691239D9\")\n    (\"mnopqrstuvwxyz{|}~ !\\\"#$%&'\" #uuid \"AFF4E386-6231-3E2A-88F1-3FE63D467059\")\n    (\"nopqrstuvwxyz{|}~ !\\\"#$%&'(\" #uuid \"E81B7969-464A-3B48-AC6A-C780732B94B3\")\n    (\"opqrstuvwxyz{|}~ !\\\"#$%&'()\" #uuid \"316E4D11-F765-32E4-97B9-D3704000BD57\")\n    (\"pqrstuvwxyz{|}~ !\\\"#$%&'()*\" #uuid \"3BF51E5F-6940-3591-96AC-0322900FB4DE\")\n    (\"qrstuvwxyz{|}~ !\\\"#$%&'()*+\" #uuid \"8DB58107-A4C3-3560-A914-7547B57A0565\")\n    (\"rstuvwxyz{|}~ !\\\"#$%&'()*+,\" #uuid \"037874F2-EFCA-3DAB-9AD3-411B46D4C185\")\n    (\"stuvwxyz{|}~ !\\\"#$%&'()*+,-\" #uuid \"B3F2E765-46DE-3082-ABFF-5B65801BF1E7\")\n    (\"tuvwxyz{|}~ !\\\"#$%&'()*+,-.\" #uuid \"4FD026E5-5478-3DD5-AF5A-EAE806EEF62D\")\n    (\"uvwxyz{|}~ !\\\"#$%&'()*+,-./\" #uuid \"3142B451-58AC-3055-9D0D-9948A1F3706C\")\n    (\"vwxyz{|}~ !\\\"#$%&'()*+,-./0\" #uuid \"741E5817-5E0F-31D8-8FAE-3AF54EB27365\")\n    (\"wxyz{|}~ !\\\"#$%&'()*+,-./01\" #uuid \"A983541C-66E6-33E6-99C0-9D7F7750899B\")\n    (\"xyz{|}~ !\\\"#$%&'()*+,-./012\" #uuid \"56F776F7-7F8C-3A05-84B8-E6FD416C4940\")\n    (\"yz{|}~ !\\\"#$%&'()*+,-./0123\" #uuid \"4B0029B8-A2CE-30D8-9147-99DC8AC92BAC\")\n    (\"z{|}~ !\\\"#$%&'()*+,-./01234\" #uuid \"91EB3CE3-9F35-36CB-AA35-F40E96960E4E\")\n    (\"{|}~ !\\\"#$%&'()*+,-./012345\" #uuid \"B89FD471-22CA-3D4A-B255-14479084F964\")\n    (\"|}~ !\\\"#$%&'()*+,-./0123456\" #uuid \"4E07B5E6-66EB-370B-A710-97064AE6D845\")\n    (\"}~ !\\\"#$%&'()*+,-./01234567\" #uuid \"F23EFB3D-C9BF-3198-ACC6-38C646818FFF\")\n    (\"~ !\\\"#$%&'()*+,-./012345678\" #uuid \"8099A277-2EE2-3A97-AAF1-7D186DEEBBDC\")\n    ))\n\n\n(deftest check-v3-null-ns-cases\n  (testing \"v3 null-ns case-based correctness...\"\n    (doseq [case +v3-null-ns-cases+]\n      (is (= (second case) (v3 +null+ (first case)))))))\n\n\n(def +v3-dns-ns-cases+\n  '((\" !\\\"#$%&'()*+,-./0123456789\" #uuid \"8502CBB1-B406-39A3-AC93-00AE0DC70F89\")\n    (\"!\\\"#$%&'()*+,-./0123456789:\" #uuid \"5CD1F6D6-BDE7-3951-B13A-A09645DC80B4\")\n    (\"\\\"#$%&'()*+,-./0123456789:;\" #uuid \"3E5E99E8-0EFB-3F3F-B8A6-873B8EF8F95B\")\n    (\"#$%&'()*+,-./0123456789:;<\" #uuid \"C75A5D34-955A-3D4F-B8F6-ED670CEFD20E\")\n    (\"$%&'()*+,-./0123456789:;<=\" #uuid \"9062C80A-709E-3890-BA62-E01A7A9F5BE6\")\n    (\"%&'()*+,-./0123456789:;<=>\" #uuid \"92168DE8-02D8-3E43-BF5F-BB96F9081EEF\")\n    (\"&'()*+,-./0123456789:;<=>?\" #uuid \"5AE75650-AA07-3116-94B5-651E17E890B7\")\n    (\"'()*+,-./0123456789:;<=>?@\" #uuid \"60F0E242-6A03-3710-BC32-E673CD132FB8\")\n    (\"()*+,-./0123456789:;<=>?@A\" #uuid \"6B04570A-F602-3669-AC1D-1FE799A3B5F6\")\n    (\")*+,-./0123456789:;<=>?@AB\" #uuid \"FA527A0F-C8F0-3608-8351-4D006D8E4F62\")\n    (\"*+,-./0123456789:;<=>?@ABC\" #uuid \"72375C7F-1B61-3851-A4C6-D65839931A36\")\n    (\"+,-./0123456789:;<=>?@ABCD\" #uuid \"9315034D-29BB-39C9-B29C-2AA2C4921EC8\")\n    (\",-./0123456789:;<=>?@ABCDE\" #uuid \"C61EE942-70D4-3F61-B411-5D71667081C4\")\n    (\"-./0123456789:;<=>?@ABCDEF\" #uuid \"929650E9-EAFB-3AC2-9945-95B254699094\")\n    (\"./0123456789:;<=>?@ABCDEFG\" #uuid \"3751476F-2EAE-3CE1-954E-7CBFA8B46061\")\n    (\"/0123456789:;<=>?@ABCDEFGH\" #uuid \"2910586F-51A0-353E-A5C3-C40F0C14F410\")\n    (\"0123456789:;<=>?@ABCDEFGHI\" #uuid \"B91DF409-A8CB-351A-AC0B-24E4A6A7FD28\")\n    (\"123456789:;<=>?@ABCDEFGHIJ\" #uuid \"2A9784FF-AA2E-3974-86BF-B37F0E60F50B\")\n    (\"23456789:;<=>?@ABCDEFGHIJK\" #uuid \"A91A7B75-6674-30AB-94FF-ED6F93728BEA\")\n    (\"3456789:;<=>?@ABCDEFGHIJKL\" #uuid \"932F664F-3289-3527-9D52-0EA2C0A205AB\")\n    (\"456789:;<=>?@ABCDEFGHIJKLM\" #uuid \"FF6A35C9-0BD7-314C-BF4C-DABF76F8BBF9\")\n    (\"56789:;<=>?@ABCDEFGHIJKLMN\" #uuid \"AA5AD585-6B5D-3303-BBCD-EB493EC61DE6\")\n    (\"6789:;<=>?@ABCDEFGHIJKLMNO\" #uuid \"E88EC15E-AC84-3295-868F-9CAB7FC1D15B\")\n    (\"789:;<=>?@ABCDEFGHIJKLMNOP\" #uuid \"36AD17D3-9EB5-3222-B944-DF80AD71CE8C\")\n    (\"89:;<=>?@ABCDEFGHIJKLMNOPQ\" #uuid \"75477B3F-47CC-3EC8-ABD2-5D8C2B700C00\")\n    (\"9:;<=>?@ABCDEFGHIJKLMNOPQR\" #uuid \"B76D9FDC-C337-34C2-9EA2-95BF83BB4FF3\")\n    (\":;<=>?@ABCDEFGHIJKLMNOPQRS\" #uuid \"481DD83F-9686-39F9-AA46-FE893E69EF78\")\n    (\";<=>?@ABCDEFGHIJKLMNOPQRST\" #uuid \"763F4C35-D29D-3223-98EC-1ED581A3D4B9\")\n    (\"<=>?@ABCDEFGHIJKLMNOPQRSTU\" #uuid \"DC2C9ECD-B365-3D76-A989-2964B7AB10E0\")\n    (\"=>?@ABCDEFGHIJKLMNOPQRSTUV\" #uuid \"20BC5EB3-B6BD-322D-97C2-FCE1F65271BB\")\n    (\">?@ABCDEFGHIJKLMNOPQRSTUVW\" #uuid \"8A6E735D-D1EB-33E1-88BB-F0E30A369318\")\n    (\"?@ABCDEFGHIJKLMNOPQRSTUVWX\" #uuid \"0EB2F01D-560A-3616-BCC3-2C0E10612EA5\")\n    (\"@ABCDEFGHIJKLMNOPQRSTUVWXY\" #uuid \"C3B2FCB2-1CE3-33AF-98DC-824DAA7A5327\")\n    (\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\" #uuid \"DBAE940B-391B-3655-B21F-2AE528FAD04C\")\n    (\"BCDEFGHIJKLMNOPQRSTUVWXYZ[\" #uuid \"08B4ED9D-791A-369F-BBF7-F4FCEBE803F5\")\n    (\"CDEFGHIJKLMNOPQRSTUVWXYZ[\\\\\" #uuid \"907267C2-5EB6-36DC-9104-E9B036075927\")\n    (\"DEFGHIJKLMNOPQRSTUVWXYZ[\\\\]\" #uuid \"F9F89EBA-AA31-3353-8016-BE7E24D5FEA5\")\n    (\"EFGHIJKLMNOPQRSTUVWXYZ[\\\\]^\" #uuid \"A8A80596-3613-39DF-82D1-D5B8C1789ED3\")\n    (\"FGHIJKLMNOPQRSTUVWXYZ[\\\\]^_\" #uuid \"0DAFC143-7019-30AA-999B-21C8EFDE44C8\")\n    (\"GHIJKLMNOPQRSTUVWXYZ[\\\\]^_`\" #uuid \"BDE827C3-2DB7-39D2-8361-17C5177C3A9B\")\n    (\"HIJKLMNOPQRSTUVWXYZ[\\\\]^_`a\" #uuid \"D47F238E-AEC0-3D16-A68F-557FE161D6F4\")\n    (\"IJKLMNOPQRSTUVWXYZ[\\\\]^_`ab\" #uuid \"737E81D8-B110-3333-8BAA-9F215028E353\")\n    (\"JKLMNOPQRSTUVWXYZ[\\\\]^_`abc\" #uuid \"26C803EF-6B0D-387E-BB11-DFC748546F92\")\n    (\"KLMNOPQRSTUVWXYZ[\\\\]^_`abcd\" #uuid \"BBAA20C9-5428-31AC-99C7-4C5959E77F5F\")\n    (\"LMNOPQRSTUVWXYZ[\\\\]^_`abcde\" #uuid \"C7655287-1D3A-392A-B29D-DECB40F34D60\")\n    (\"MNOPQRSTUVWXYZ[\\\\]^_`abcdef\" #uuid \"0295F24F-EE5E-3D05-BCA3-56BD9960CFD2\")\n    (\"NOPQRSTUVWXYZ[\\\\]^_`abcdefg\" #uuid \"911D25F2-D390-31CA-ACFF-6E6FBA5B7DDD\")\n    (\"OPQRSTUVWXYZ[\\\\]^_`abcdefgh\" #uuid \"528A84FD-9E97-303A-92E7-51645F93525F\")\n    (\"PQRSTUVWXYZ[\\\\]^_`abcdefghi\" #uuid \"AB4FB6D1-4F74-3331-98EF-C27E87008D07\")\n    (\"QRSTUVWXYZ[\\\\]^_`abcdefghij\" #uuid \"23DA9F4B-5218-3C3E-AE38-1A4F760E5C93\")\n    (\"RSTUVWXYZ[\\\\]^_`abcdefghijk\" #uuid \"98A14203-0B09-3095-83BC-0FFB9A4684C4\")\n    (\"STUVWXYZ[\\\\]^_`abcdefghijkl\" #uuid \"CA10A029-E06A-364E-A0ED-B7AA4F24D207\")\n    (\"TUVWXYZ[\\\\]^_`abcdefghijklm\" #uuid \"2C95761B-FBD7-33E2-936A-13D8D0C48F58\")\n    (\"UVWXYZ[\\\\]^_`abcdefghijklmn\" #uuid \"E3C6A320-23A7-353E-8E06-C363EC783A86\")\n    (\"VWXYZ[\\\\]^_`abcdefghijklmno\" #uuid \"32EFCA32-AD04-3CB2-BA66-E8509FC1C743\")\n    (\"WXYZ[\\\\]^_`abcdefghijklmnop\" #uuid \"9203D568-7AE8-3F1E-BD83-AA72C1F47495\")\n    (\"XYZ[\\\\]^_`abcdefghijklmnopq\" #uuid \"6860513A-1DCF-3B63-AC85-E684406A2F61\")\n    (\"YZ[\\\\]^_`abcdefghijklmnopqr\" #uuid \"564B821A-DEAC-3A72-89BC-5659B8883FB8\")\n    (\"Z[\\\\]^_`abcdefghijklmnopqrs\" #uuid \"6988DFAF-7A52-3F4B-AE03-BFE348977A37\")\n    (\"[\\\\]^_`abcdefghijklmnopqrst\" #uuid \"CF62DC30-B276-39F5-9FFD-AA571936C5FD\")\n    (\"\\\\]^_`abcdefghijklmnopqrstu\" #uuid \"8715D8EC-89BB-395F-A393-95EFF3396E25\")\n    (\"]^_`abcdefghijklmnopqrstuv\" #uuid \"C66A5CB0-3695-31F8-8C41-D061DB8B76FD\")\n    (\"^_`abcdefghijklmnopqrstuvw\" #uuid \"0045436E-446F-3A24-86A2-5D3547DFFA18\")\n    (\"_`abcdefghijklmnopqrstuvwx\" #uuid \"5E24D6DF-AF96-3F19-8A71-89EEF9F19083\")\n    (\"`abcdefghijklmnopqrstuvwxy\" #uuid \"4D0B435F-C0F9-3329-BDCB-F3FC3AABEDD4\")\n    (\"abcdefghijklmnopqrstuvwxyz\" #uuid \"E7684C6A-B70E-3531-9426-3BC6E033B0FE\")\n    (\"bcdefghijklmnopqrstuvwxyz{\" #uuid \"486F569D-7C28-33C2-8B16-4227BD39E3D3\")\n    (\"cdefghijklmnopqrstuvwxyz{|\" #uuid \"DAE05C81-A7FD-3BE3-824C-789FD9F57A64\")\n    (\"defghijklmnopqrstuvwxyz{|}\" #uuid \"15F225A9-BF75-352A-BEBA-03BDEDCA0C56\")\n    (\"efghijklmnopqrstuvwxyz{|}~\" #uuid \"F27B144E-D8A9-3D01-923D-E81296D994D4\")\n    (\"fghijklmnopqrstuvwxyz{|}~ \" #uuid \"040C3AF4-3765-3383-BD52-9258CE747EE4\")\n    (\"ghijklmnopqrstuvwxyz{|}~ !\" #uuid \"1751D35C-113B-399C-B8EC-B40D0ADD30BE\")\n    (\"hijklmnopqrstuvwxyz{|}~ !\\\"\" #uuid \"CD19EAB7-86F6-3DEB-8BDB-A382B8939580\")\n    (\"ijklmnopqrstuvwxyz{|}~ !\\\"#\" #uuid \"C6AAFEEA-0794-3BA2-BBB0-C019DEBEA642\")\n    (\"jklmnopqrstuvwxyz{|}~ !\\\"#$\" #uuid \"E566FDE3-FB60-347F-8A61-CE4E8314C7D8\")\n    (\"klmnopqrstuvwxyz{|}~ !\\\"#$%\" #uuid \"3E44EBAC-F311-3801-B576-3D570247E085\")\n    (\"lmnopqrstuvwxyz{|}~ !\\\"#$%&\" #uuid \"7C3E1262-380A-3970-ACC2-8C67C95AB416\")\n    (\"mnopqrstuvwxyz{|}~ !\\\"#$%&'\" #uuid \"8C802F36-4223-3A16-A002-7CF4333CA2BC\")\n    (\"nopqrstuvwxyz{|}~ !\\\"#$%&'(\" #uuid \"68E9670E-DDB7-3235-9E22-BDE736C58160\")\n    (\"opqrstuvwxyz{|}~ !\\\"#$%&'()\" #uuid \"619A2D6F-8DE7-389E-92C9-DCE56B0CF5F4\")\n    (\"pqrstuvwxyz{|}~ !\\\"#$%&'()*\" #uuid \"F5D251CF-76C2-3C0F-BBEB-13AE71B90EDD\")\n    (\"qrstuvwxyz{|}~ !\\\"#$%&'()*+\" #uuid \"71AE2AA0-47C1-307A-9BE7-73B6BFEE0AE6\")\n    (\"rstuvwxyz{|}~ !\\\"#$%&'()*+,\" #uuid \"0BB601E4-94D6-3AD0-8BFC-28CDA8AAD2CD\")\n    (\"stuvwxyz{|}~ !\\\"#$%&'()*+,-\" #uuid \"CABDBD7F-54AE-37F5-B7C8-DFE9219133CE\")\n    (\"tuvwxyz{|}~ !\\\"#$%&'()*+,-.\" #uuid \"FEE30B3E-FAF2-3465-AC90-17D6BEC041FF\")\n    (\"uvwxyz{|}~ !\\\"#$%&'()*+,-./\" #uuid \"D37DD9FB-6DD9-362B-9BAA-E3A67E7C3A15\")\n    (\"vwxyz{|}~ !\\\"#$%&'()*+,-./0\" #uuid \"365BED8E-5E7C-3704-AD7B-4A5B91767D2E\")\n    (\"wxyz{|}~ !\\\"#$%&'()*+,-./01\" #uuid \"0C99C105-BAC3-3D4B-B4F5-04251CF48B7B\")\n    (\"xyz{|}~ !\\\"#$%&'()*+,-./012\" #uuid \"E06D9F72-813B-3F3E-A096-E4C7FC05BD84\")\n    (\"yz{|}~ !\\\"#$%&'()*+,-./0123\" #uuid \"16DF5C3B-9E1D-3CE9-A8F4-165B7067756C\")\n    (\"z{|}~ !\\\"#$%&'()*+,-./01234\" #uuid \"D3196C68-D1A0-3CE5-9DA7-4F360C0E528B\")\n    (\"{|}~ !\\\"#$%&'()*+,-./012345\" #uuid \"F9EA7DC9-F790-3EBC-B970-FE944FC25078\")\n    (\"|}~ !\\\"#$%&'()*+,-./0123456\" #uuid \"786245E9-B956-3774-BD77-3DD581271B30\")\n    (\"}~ !\\\"#$%&'()*+,-./01234567\" #uuid \"3BAC4AC0-3FD1-371F-AC81-5BA1AB950E18\")\n    (\"~ !\\\"#$%&'()*+,-./012345678\" #uuid \"6EC555CD-9DFF-3783-B556-2D8DD55A5CD0\")\n    ))\n\n\n(deftest check-v3-dns-ns-cases\n  (testing \"v3 dns-ns case-based correctness...\"\n    (doseq [case +v3-dns-ns-cases+]\n      (is (= (second case) (v3 +namespace-dns+ (first case)))))))\n\n\n(def +v3-oid-ns-cases+\n  '((\" !\\\"#$%&'()*+,-./0123456789\" #uuid \"43D9B705-E75C-31EB-A5AE-89D03DEA6C8A\")\n    (\"!\\\"#$%&'()*+,-./0123456789:\" #uuid \"D425D486-816F-310F-9675-D9F0F5568AAD\")\n    (\"\\\"#$%&'()*+,-./0123456789:;\" #uuid \"411A971C-E960-3B93-B02D-40E492EAD382\")\n    (\"#$%&'()*+,-./0123456789:;<\" #uuid \"4DF246BF-DBE6-337E-BC7F-A2C18B8F9264\")\n    (\"$%&'()*+,-./0123456789:;<=\" #uuid \"D72384E9-DF60-3B90-A18B-CA71ADBBEFA1\")\n    (\"%&'()*+,-./0123456789:;<=>\" #uuid \"6CB6E4D1-F590-329D-9CB3-11B985B81333\")\n    (\"&'()*+,-./0123456789:;<=>?\" #uuid \"C2C9252E-6018-3704-A0EB-786BEE2C949B\")\n    (\"'()*+,-./0123456789:;<=>?@\" #uuid \"F162EFDE-3FDC-31A0-8BBD-281E3911DB83\")\n    (\"()*+,-./0123456789:;<=>?@A\" #uuid \"4A4327AA-B253-3A36-9D51-FD149EF61FFC\")\n    (\")*+,-./0123456789:;<=>?@AB\" #uuid \"E6D5600D-6965-3AFD-946F-BC3E1E3E51D3\")\n    (\"*+,-./0123456789:;<=>?@ABC\" #uuid \"36A30022-28CD-3AFE-87F1-B84974ECF06D\")\n    (\"+,-./0123456789:;<=>?@ABCD\" #uuid \"B9E15BA0-1574-3AA2-8B85-AD7D264F861F\")\n    (\",-./0123456789:;<=>?@ABCDE\" #uuid \"4047ABD8-DAB4-318A-90F7-423759DC796F\")\n    (\"-./0123456789:;<=>?@ABCDEF\" #uuid \"86E64E13-7028-39BD-80FB-912D77416CC3\")\n    (\"./0123456789:;<=>?@ABCDEFG\" #uuid \"75FDCE21-970F-3046-8D8A-693FB255746B\")\n    (\"/0123456789:;<=>?@ABCDEFGH\" #uuid \"52A2192D-BD14-334D-B9B4-2756FADC303B\")\n    (\"0123456789:;<=>?@ABCDEFGHI\" #uuid \"3AC1FF81-E7F2-3F2B-A4BB-0CF77AC9878B\")\n    (\"123456789:;<=>?@ABCDEFGHIJ\" #uuid \"0AE96CC9-7371-3ACF-8D78-ACF5FD1E42F6\")\n    (\"23456789:;<=>?@ABCDEFGHIJK\" #uuid \"223AC51D-323A-3889-B3AB-5733CC79479A\")\n    (\"3456789:;<=>?@ABCDEFGHIJKL\" #uuid \"A9288FC0-599A-3C05-9EFC-96DB4D59451B\")\n    (\"456789:;<=>?@ABCDEFGHIJKLM\" #uuid \"EE795374-5D2F-38C4-B0DC-BD2E72E03FEB\")\n    (\"56789:;<=>?@ABCDEFGHIJKLMN\" #uuid \"80E415B6-32DF-350B-8AF2-388EEB0AE788\")\n    (\"6789:;<=>?@ABCDEFGHIJKLMNO\" #uuid \"BD6755C9-5565-3ADD-8B37-F53284B1DBD5\")\n    (\"789:;<=>?@ABCDEFGHIJKLMNOP\" #uuid \"30CFFF63-A342-30E4-9692-846588A5702B\")\n    (\"89:;<=>?@ABCDEFGHIJKLMNOPQ\" #uuid \"B419E181-2D73-3619-B809-FCC0B518EE68\")\n    (\"9:;<=>?@ABCDEFGHIJKLMNOPQR\" #uuid \"C795BEAB-5B07-3D8C-ACC2-374CBE19669F\")\n    (\":;<=>?@ABCDEFGHIJKLMNOPQRS\" #uuid \"21FAADF5-3A76-34B4-B835-A80D9E269A91\")\n    (\";<=>?@ABCDEFGHIJKLMNOPQRST\" #uuid \"EF0A7F62-8C69-30B2-B66B-E480C7BC71FE\")\n    (\"<=>?@ABCDEFGHIJKLMNOPQRSTU\" #uuid \"159FC9E2-5A10-3C8E-8DC1-D8D9C0CB7706\")\n    (\"=>?@ABCDEFGHIJKLMNOPQRSTUV\" #uuid \"F6882739-0246-3AF0-AB7C-267644CEA4DD\")\n    (\">?@ABCDEFGHIJKLMNOPQRSTUVW\" #uuid \"C004A348-6266-3D52-B3BB-ADE1F48A9D49\")\n    (\"?@ABCDEFGHIJKLMNOPQRSTUVWX\" #uuid \"681545F9-D596-34EF-9F10-C6D8F87087F1\")\n    (\"@ABCDEFGHIJKLMNOPQRSTUVWXY\" #uuid \"9C78D8DD-918F-331A-A9C4-69CE5C2505F0\")\n    (\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\" #uuid \"1AE24819-DE5A-327D-89FE-2745E611B9F3\")\n    (\"BCDEFGHIJKLMNOPQRSTUVWXYZ[\" #uuid \"E6ACEB11-DEEB-36D7-A281-1E3C9F653C2B\")\n    (\"CDEFGHIJKLMNOPQRSTUVWXYZ[\\\\\" #uuid \"71300878-7997-3AB1-BE58-4A1879169575\")\n    (\"DEFGHIJKLMNOPQRSTUVWXYZ[\\\\]\" #uuid \"F3E984D7-CACF-302F-8E30-616634DEC171\")\n    (\"EFGHIJKLMNOPQRSTUVWXYZ[\\\\]^\" #uuid \"9DABDA54-3905-3443-BFE4-3680CB5D4CB6\")\n    (\"FGHIJKLMNOPQRSTUVWXYZ[\\\\]^_\" #uuid \"BB9F5584-4772-3D83-9AA2-7808B78E346E\")\n    (\"GHIJKLMNOPQRSTUVWXYZ[\\\\]^_`\" #uuid \"B9160282-CEBB-3AD3-A52F-4DC60393798D\")\n    (\"HIJKLMNOPQRSTUVWXYZ[\\\\]^_`a\" #uuid \"89BB630C-4C3C-317F-BA91-D3E12DF00FF7\")\n    (\"IJKLMNOPQRSTUVWXYZ[\\\\]^_`ab\" #uuid \"4A9C2A72-F9D6-3650-8721-FC8E0EF635FB\")\n    (\"JKLMNOPQRSTUVWXYZ[\\\\]^_`abc\" #uuid \"F3DABB7C-2C7F-3AE5-9214-D85BF57910CB\")\n    (\"KLMNOPQRSTUVWXYZ[\\\\]^_`abcd\" #uuid \"671A4498-CE67-314C-B50F-06212DCF5AC4\")\n    (\"LMNOPQRSTUVWXYZ[\\\\]^_`abcde\" #uuid \"3FC4800A-A5C3-3454-A407-2D874993D0A8\")\n    (\"MNOPQRSTUVWXYZ[\\\\]^_`abcdef\" #uuid \"862A6E34-653C-3D90-9BC4-DF5F875F4F49\")\n    (\"NOPQRSTUVWXYZ[\\\\]^_`abcdefg\" #uuid \"13423AE6-E6C4-3F4A-A94D-E9A5B5DD7707\")\n    (\"OPQRSTUVWXYZ[\\\\]^_`abcdefgh\" #uuid \"24F418E9-C5BA-3A82-8492-334ADFD63CD1\")\n    (\"PQRSTUVWXYZ[\\\\]^_`abcdefghi\" #uuid \"A1B3F1E1-E25F-3AE9-88C8-1BF76FB82CA7\")\n    (\"QRSTUVWXYZ[\\\\]^_`abcdefghij\" #uuid \"D84E1825-DD1A-3147-8275-1A6CF04E60EC\")\n    (\"RSTUVWXYZ[\\\\]^_`abcdefghijk\" #uuid \"9B293E2C-6A27-3A79-82FF-C225846296CD\")\n    (\"STUVWXYZ[\\\\]^_`abcdefghijkl\" #uuid \"F17A6EC8-F42E-3523-ADDC-51AB5F08EF2B\")\n    (\"TUVWXYZ[\\\\]^_`abcdefghijklm\" #uuid \"7C17D37D-49D1-3815-8F3D-4F2950B3D863\")\n    (\"UVWXYZ[\\\\]^_`abcdefghijklmn\" #uuid \"71E14392-3F2A-3EC9-9476-027B4D7F9EDA\")\n    (\"VWXYZ[\\\\]^_`abcdefghijklmno\" #uuid \"7103789B-4358-3BF3-B7E9-0B3C203E7552\")\n    (\"WXYZ[\\\\]^_`abcdefghijklmnop\" #uuid \"7C95A201-3F6F-36CF-9DBB-E1BCCD9D9FD2\")\n    (\"XYZ[\\\\]^_`abcdefghijklmnopq\" #uuid \"A05E1B2E-63BC-38D9-9333-56E6337C14ED\")\n    (\"YZ[\\\\]^_`abcdefghijklmnopqr\" #uuid \"34515391-27CF-3202-9AF8-624095EC7D7F\")\n    (\"Z[\\\\]^_`abcdefghijklmnopqrs\" #uuid \"FA32549C-6874-3DAC-B69B-AE22C3EF2411\")\n    (\"[\\\\]^_`abcdefghijklmnopqrst\" #uuid \"E6C8FC6A-240B-382C-9FDD-7856BCFF4EA1\")\n    (\"\\\\]^_`abcdefghijklmnopqrstu\" #uuid \"2C6677D4-BDD9-3A9C-9755-5F6F06D53A54\")\n    (\"]^_`abcdefghijklmnopqrstuv\" #uuid \"EA5349C6-5861-3C7F-9A6F-ED4F5FE37AE9\")\n    (\"^_`abcdefghijklmnopqrstuvw\" #uuid \"F93457EF-D9AD-3151-91A4-57BE63AEAC4A\")\n    (\"_`abcdefghijklmnopqrstuvwx\" #uuid \"A29821DC-23A0-3CB9-88FC-2F5C4B4EDE24\")\n    (\"`abcdefghijklmnopqrstuvwxy\" #uuid \"AB8D5F5D-D180-34B3-B320-DE0FA700664F\")\n    (\"abcdefghijklmnopqrstuvwxyz\" #uuid \"0C491E79-D2B7-3A30-B9C4-BE9515E6E0E2\")\n    (\"bcdefghijklmnopqrstuvwxyz{\" #uuid \"E2D1EFD6-229C-3868-BBF1-5143CF5E3649\")\n    (\"cdefghijklmnopqrstuvwxyz{|\" #uuid \"F8BAE8BC-E1A4-3D42-8015-AF897E3AA1E4\")\n    (\"defghijklmnopqrstuvwxyz{|}\" #uuid \"AF0061CD-2B25-3ECC-BFD4-8707FC33E3F4\")\n    (\"efghijklmnopqrstuvwxyz{|}~\" #uuid \"AE4EBA8B-95F9-32CF-A37F-0A202D4D746E\")\n    (\"fghijklmnopqrstuvwxyz{|}~ \" #uuid \"AF3A5813-EB8C-3DA2-9BDA-866C2D255DB6\")\n    (\"ghijklmnopqrstuvwxyz{|}~ !\" #uuid \"D547E557-7542-3241-A56D-D5B9A44D4BFF\")\n    (\"hijklmnopqrstuvwxyz{|}~ !\\\"\" #uuid \"FA78A373-D9B9-3EBF-8699-642816516351\")\n    (\"ijklmnopqrstuvwxyz{|}~ !\\\"#\" #uuid \"57D1E4B6-BE59-3692-BD09-07C62A4570B6\")\n    (\"jklmnopqrstuvwxyz{|}~ !\\\"#$\" #uuid \"B7946A08-1F5A-3EA4-8040-422179089B5E\")\n    (\"klmnopqrstuvwxyz{|}~ !\\\"#$%\" #uuid \"BB50DA00-95FE-37D8-A9B4-847555CFA047\")\n    (\"lmnopqrstuvwxyz{|}~ !\\\"#$%&\" #uuid \"54DEC298-B336-3690-BA29-182C6B358BE7\")\n    (\"mnopqrstuvwxyz{|}~ !\\\"#$%&'\" #uuid \"1181FADE-BC28-3BA1-9594-61848F97CD74\")\n    (\"nopqrstuvwxyz{|}~ !\\\"#$%&'(\" #uuid \"8BB47B9F-237D-313D-9B71-A897646ACF43\")\n    (\"opqrstuvwxyz{|}~ !\\\"#$%&'()\" #uuid \"2E548DFD-1A9D-3EBF-AB39-41DC1530F39D\")\n    (\"pqrstuvwxyz{|}~ !\\\"#$%&'()*\" #uuid \"4082F972-90D3-3011-A16E-D3ADAB93A1C9\")\n    (\"qrstuvwxyz{|}~ !\\\"#$%&'()*+\" #uuid \"181BACA8-4476-377E-AC33-739E1B49CDFA\")\n    (\"rstuvwxyz{|}~ !\\\"#$%&'()*+,\" #uuid \"FB6E8638-AA96-3C2A-A621-2319E9604BA4\")\n    (\"stuvwxyz{|}~ !\\\"#$%&'()*+,-\" #uuid \"C30943D9-FD02-3922-AD5E-3911F0B460F8\")\n    (\"tuvwxyz{|}~ !\\\"#$%&'()*+,-.\" #uuid \"80F5F58A-4C81-3E25-BC67-681F523F5A47\")\n    (\"uvwxyz{|}~ !\\\"#$%&'()*+,-./\" #uuid \"1656D4B3-F6C4-3774-AF81-7BEEE3C64A8A\")\n    (\"vwxyz{|}~ !\\\"#$%&'()*+,-./0\" #uuid \"05DA3CB1-6634-3BEE-A275-E5D672F2B303\")\n    (\"wxyz{|}~ !\\\"#$%&'()*+,-./01\" #uuid \"6CA9378F-0A4F-3F79-9D07-76D37D080F4C\")\n    (\"xyz{|}~ !\\\"#$%&'()*+,-./012\" #uuid \"795D525B-B8AB-36EC-9069-C0B108434526\")\n    (\"yz{|}~ !\\\"#$%&'()*+,-./0123\" #uuid \"55DD78E1-5ECB-3E9E-9D52-90C0D0D4F9B0\")\n    (\"z{|}~ !\\\"#$%&'()*+,-./01234\" #uuid \"DF4A937F-5E7C-372B-8CAD-96778829C4D0\")\n    (\"{|}~ !\\\"#$%&'()*+,-./012345\" #uuid \"5AC9C9D3-446A-3D44-81C0-B3BA2D5F72D9\")\n    (\"|}~ !\\\"#$%&'()*+,-./0123456\" #uuid \"D5A24A2C-A19F-314F-A2D1-4DEAFB6DF09A\")\n    (\"}~ !\\\"#$%&'()*+,-./01234567\" #uuid \"0BE200A8-CCF3-39E6-B784-28ABCF933676\")\n    (\"~ !\\\"#$%&'()*+,-./012345678\" #uuid \"B1BD83C9-B045-3416-A411-2091009AA351\")\n    ))\n\n\n(deftest check-v3-oid-ns-cases\n  (testing \"v3 oid-ns case-based correctness...\"\n    (doseq [case +v3-oid-ns-cases+]\n      (is (= (second case) (v3 +namespace-oid+ (first case)))))))\n"
  },
  {
    "path": "test/clj_uuid/v4_test.clj",
    "content": "(ns clj-uuid.v4-test\n  \"Random UUIDs tests\"\n  (:refer-clojure :exclude [uuid? max])\n  (:require [clojure.test :refer :all]\n            [clj-uuid     :refer :all :exclude [> < =]]))\n\n(deftest check-v4-special-cases\n  (testing \"v4 special case correctness...\"\n    (is (= (v4  0  0)  #uuid \"00000000-0000-4000-8000-000000000000\"))\n    (is (= (v4  0  1)  #uuid \"00000000-0000-4000-8000-000000000001\"))\n    (is (= (v4  0 -1)  #uuid \"00000000-0000-4000-bfff-ffffffffffff\"))\n    (is (= (v4 -1  0)  #uuid \"ffffffff-ffff-4fff-8000-000000000000\"))\n    (is (= (v4 -1 -1)  #uuid \"ffffffff-ffff-4fff-bfff-ffffffffffff\"))))\n"
  },
  {
    "path": "test/clj_uuid/v5_test.clj",
    "content": "(ns clj-uuid.v5-test\n  (:refer-clojure :exclude [uuid? max])\n  (:require [clojure.test   :refer :all]\n            [clj-uuid       :refer :all :exclude [> < =]]))\n\n\n\n(deftest check-v5-special-cases\n  (testing \"v5 special case correctness...\"\n    (is (=\n          (v5 +null+ \"\")\n          #uuid \"E129F27C-5103-5C5C-844B-CDF0A15E160D\"))\n    (is (=\n          (v5 +namespace-x500+ \"\")\n          #uuid \"B4BDF874-8C03-5BD8-8FD7-5E409DFD82C0\"))\n    (is (=\n          (v5 +namespace-oid+ \"\")\n          #uuid \"0A68EB57-C88A-5F34-9E9D-27F85E68AF4F\"))\n    (is (=\n          (v5 +namespace-dns+ \"\")\n          #uuid \"4EBD0208-8328-5D69-8C44-EC50939C0967\"))\n    (is (=\n          (v5 +namespace-url+ \"\")\n          #uuid \"1B4DB7EB-4057-5DDF-91E0-36DEC72071F5\"))))\n\n(def +v5-null-ns-cases+\n  '((\" !\\\"#$%&'()*+,-./0123456789\" #uuid \"242E6E8E-7545-5A07-A02F-326EC30CB6B6\")\n    (\"!\\\"#$%&'()*+,-./0123456789:\" #uuid \"41F22F8C-6251-523B-B46D-E13DB8EA92AB\")\n    (\"\\\"#$%&'()*+,-./0123456789:;\" #uuid \"D8F25381-4007-57D5-85ED-34F8F5C2879B\")\n    (\"#$%&'()*+,-./0123456789:;<\" #uuid \"45846189-7511-535D-9F94-8E0BD4E32383\")\n    (\"$%&'()*+,-./0123456789:;<=\" #uuid \"5E0E00BE-97CA-5270-BAE1-826A1528126E\")\n    (\"%&'()*+,-./0123456789:;<=>\" #uuid \"00715EE8-3D82-5605-B403-CC58B2F4C71A\")\n    (\"&'()*+,-./0123456789:;<=>?\" #uuid \"15D19A8D-76E1-58D2-B5DE-1E4A5CC3B515\")\n    (\"'()*+,-./0123456789:;<=>?@\" #uuid \"474DBC21-26B2-5B08-A76B-F06E331B93DD\")\n    (\"()*+,-./0123456789:;<=>?@A\" #uuid \"65B54688-43AD-54DC-B052-B612E09B8AD6\")\n    (\")*+,-./0123456789:;<=>?@AB\" #uuid \"20CCA61F-4F55-5420-9CD0-30B1D166FE5B\")\n    (\"*+,-./0123456789:;<=>?@ABC\" #uuid \"D9C06A76-8189-583B-B3E9-FFC143531914\")\n    (\"+,-./0123456789:;<=>?@ABCD\" #uuid \"014FAF6F-5246-5007-B5CB-E0EFC331D3B0\")\n    (\",-./0123456789:;<=>?@ABCDE\" #uuid \"D87E9933-09B4-5DA5-B980-7CC65E6B471B\")\n    (\"-./0123456789:;<=>?@ABCDEF\" #uuid \"31E0B629-9781-5E59-B7AF-04D2D88660AF\")\n    (\"./0123456789:;<=>?@ABCDEFG\" #uuid \"CCED497C-35AF-5FE4-A6C2-61A0572FDA59\")\n    (\"/0123456789:;<=>?@ABCDEFGH\" #uuid \"C993482E-33E9-5CC8-9E51-8EE46B3FE152\")\n    (\"0123456789:;<=>?@ABCDEFGHI\" #uuid \"0F6BDD65-B698-5762-AD0E-AB35B5D73885\")\n    (\"123456789:;<=>?@ABCDEFGHIJ\" #uuid \"AA1D4298-9A26-5AB9-B0F2-E1D7AF6CF813\")\n    (\"23456789:;<=>?@ABCDEFGHIJK\" #uuid \"27F508C3-7402-57F8-B17B-0D81C0D7F062\")\n    (\"3456789:;<=>?@ABCDEFGHIJKL\" #uuid \"6EC8BBC6-987E-52E3-A948-EE3DBF3D0D4A\")\n    (\"456789:;<=>?@ABCDEFGHIJKLM\" #uuid \"25DFBD80-01B3-5540-AEBA-22E627A48899\")\n    (\"56789:;<=>?@ABCDEFGHIJKLMN\" #uuid \"FFF7A94C-F5F2-51FF-9D5B-55B388600BE6\")\n    (\"6789:;<=>?@ABCDEFGHIJKLMNO\" #uuid \"B4FD5C57-0AE3-5D8F-ADAC-1E8E8CB60C27\")\n    (\"789:;<=>?@ABCDEFGHIJKLMNOP\" #uuid \"0E1880FB-CB2E-588B-9CFD-6B451E447E50\")\n    (\"89:;<=>?@ABCDEFGHIJKLMNOPQ\" #uuid \"5040D88C-1881-599D-A954-A2CBCAFFC758\")\n    (\"9:;<=>?@ABCDEFGHIJKLMNOPQR\" #uuid \"77EEC4CC-5AD9-54AA-91D6-952336D771FE\")\n    (\":;<=>?@ABCDEFGHIJKLMNOPQRS\" #uuid \"30310096-BD69-5B19-AF68-FFBC854A06F6\")\n    (\";<=>?@ABCDEFGHIJKLMNOPQRST\" #uuid \"D9A83C73-1B93-5E59-9BF3-7FD6707085B8\")\n    (\"<=>?@ABCDEFGHIJKLMNOPQRSTU\" #uuid \"5BC33DA2-F6B3-5CF7-822C-1289C81DE1A1\")\n    (\"=>?@ABCDEFGHIJKLMNOPQRSTUV\" #uuid \"31D4E146-67ED-50C4-BCC6-BB3C74CDDAAC\")\n    (\">?@ABCDEFGHIJKLMNOPQRSTUVW\" #uuid \"F3939252-7456-5360-B34D-E327B823957F\")\n    (\"?@ABCDEFGHIJKLMNOPQRSTUVWX\" #uuid \"D518FB94-0083-5933-BEE1-4D21694188F2\")\n    (\"@ABCDEFGHIJKLMNOPQRSTUVWXY\" #uuid \"6852364E-017E-5D10-B4F9-63FE7DCF6D85\")\n    (\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\" #uuid \"009442DE-7929-5001-9022-0D340553A9D6\")\n    (\"BCDEFGHIJKLMNOPQRSTUVWXYZ[\" #uuid \"58860D2D-09C9-5B46-B330-2E0867C7EB7A\")\n    (\"CDEFGHIJKLMNOPQRSTUVWXYZ[\\\\\" #uuid \"3D6024D9-75E7-5BBF-90DB-097939462E63\")\n    (\"DEFGHIJKLMNOPQRSTUVWXYZ[\\\\]\" #uuid \"F400AE6B-B384-5DD3-8D3C-BCEC42E64F9F\")\n    (\"EFGHIJKLMNOPQRSTUVWXYZ[\\\\]^\" #uuid \"7C466264-9005-558E-8F8B-844868A27041\")\n    (\"FGHIJKLMNOPQRSTUVWXYZ[\\\\]^_\" #uuid \"96F0E71A-AEC5-5F2D-82BD-A38CB763589B\")\n    (\"GHIJKLMNOPQRSTUVWXYZ[\\\\]^_`\" #uuid \"B2133431-BC91-5C9B-868D-7F182215CF59\")\n    (\"HIJKLMNOPQRSTUVWXYZ[\\\\]^_`a\" #uuid \"70572482-055E-5013-8755-EF77D56E31CF\")\n    (\"IJKLMNOPQRSTUVWXYZ[\\\\]^_`ab\" #uuid \"F4A88F92-5D12-5495-A4A3-0933441B535A\")\n    (\"JKLMNOPQRSTUVWXYZ[\\\\]^_`abc\" #uuid \"F5FC6436-BB13-5C2E-8BBC-349F5BBCF126\")\n    (\"KLMNOPQRSTUVWXYZ[\\\\]^_`abcd\" #uuid \"C77E9DA8-0B0C-5DBE-8B1C-85E7BA4C631E\")\n    (\"LMNOPQRSTUVWXYZ[\\\\]^_`abcde\" #uuid \"2C3EF189-369C-5FE6-ABE8-D071246957B6\")\n    (\"MNOPQRSTUVWXYZ[\\\\]^_`abcdef\" #uuid \"BF42EC1C-0234-5226-9618-9538F89A98FF\")\n    (\"NOPQRSTUVWXYZ[\\\\]^_`abcdefg\" #uuid \"39056E38-A0B0-5194-B16E-D6F75AFA93AE\")\n    (\"OPQRSTUVWXYZ[\\\\]^_`abcdefgh\" #uuid \"17C8A690-3261-5EA5-9DE1-FF05B956E56B\")\n    (\"PQRSTUVWXYZ[\\\\]^_`abcdefghi\" #uuid \"763D44CE-E4EF-5B63-A5EC-6BD6ACB860B8\")\n    (\"QRSTUVWXYZ[\\\\]^_`abcdefghij\" #uuid \"880D1D2E-3912-51C8-A7EF-A2954B96D6D8\")\n    (\"RSTUVWXYZ[\\\\]^_`abcdefghijk\" #uuid \"DDB08918-D45E-52D2-9999-B4C5925C67B7\")\n    (\"STUVWXYZ[\\\\]^_`abcdefghijkl\" #uuid \"C9770255-BAFC-5974-9F23-B17C119F7FF3\")\n    (\"TUVWXYZ[\\\\]^_`abcdefghijklm\" #uuid \"58128319-128B-54FF-B202-33A2A271B380\")\n    (\"UVWXYZ[\\\\]^_`abcdefghijklmn\" #uuid \"7D1628F8-615E-593E-B56C-DDC5BCDDC45C\")\n    (\"VWXYZ[\\\\]^_`abcdefghijklmno\" #uuid \"1359497D-5D7F-5288-A021-88F071979ACC\")\n    (\"WXYZ[\\\\]^_`abcdefghijklmnop\" #uuid \"097BB556-5D10-5915-AB34-136DFBEDA005\")\n    (\"XYZ[\\\\]^_`abcdefghijklmnopq\" #uuid \"85AB2C59-868D-52B2-8D28-A04ADF32C456\")\n    (\"YZ[\\\\]^_`abcdefghijklmnopqr\" #uuid \"430C7305-D1F8-592D-BCB8-7345F0577B51\")\n    (\"Z[\\\\]^_`abcdefghijklmnopqrs\" #uuid \"AD411859-3F9D-5CEF-8891-2D91453BF02B\")\n    (\"[\\\\]^_`abcdefghijklmnopqrst\" #uuid \"AE01E30C-B5DF-5A40-AD98-C2E2E5F00505\")\n    (\"\\\\]^_`abcdefghijklmnopqrstu\" #uuid \"D306C4AD-7215-5331-895C-D3B123AB07F8\")\n    (\"]^_`abcdefghijklmnopqrstuv\" #uuid \"9670F138-C67F-5A3B-8421-3DB6D3E1E271\")\n    (\"^_`abcdefghijklmnopqrstuvw\" #uuid \"E246E515-EE87-5E71-9766-FE5CC691F2B6\")\n    (\"_`abcdefghijklmnopqrstuvwx\" #uuid \"CA8B9A8A-C953-58C2-8CBC-B9D5C08B7082\")\n    (\"`abcdefghijklmnopqrstuvwxy\" #uuid \"72A55C81-7771-573C-A968-D9C2E99349F6\")\n    (\"abcdefghijklmnopqrstuvwxyz\" #uuid \"15EF97D2-2E8B-5705-B040-13073A8403C6\")\n    (\"bcdefghijklmnopqrstuvwxyz{\" #uuid \"2FBC6E63-876F-5B40-9740-0194EAFF582A\")\n    (\"cdefghijklmnopqrstuvwxyz{|\" #uuid \"DA8F3757-7272-5E61-AB62-AA925CA23FEE\")\n    (\"defghijklmnopqrstuvwxyz{|}\" #uuid \"0D3D2034-3451-5F68-90AD-1C6C278DEC4D\")\n    (\"efghijklmnopqrstuvwxyz{|}~\" #uuid \"5E81B26E-6EF6-57ED-9BD7-21B6BC153AED\")\n    (\"fghijklmnopqrstuvwxyz{|}~ \" #uuid \"083EE855-E5E0-5ED3-8E76-93BA065FF370\")\n    (\"ghijklmnopqrstuvwxyz{|}~ !\" #uuid \"8B2746D3-EDCB-5AC5-9A06-6DA96E4D135C\")\n    (\"hijklmnopqrstuvwxyz{|}~ !\\\"\" #uuid \"EC9932CD-6FBA-53C9-B3F5-6D41312DA6A3\")\n    (\"ijklmnopqrstuvwxyz{|}~ !\\\"#\" #uuid \"2D587B17-4476-5EFF-BF0E-1B3D567DC402\")\n    (\"jklmnopqrstuvwxyz{|}~ !\\\"#$\" #uuid \"D1682F44-2F08-58D6-BD7D-210C91B87111\")\n    (\"klmnopqrstuvwxyz{|}~ !\\\"#$%\" #uuid \"1EE16A30-3B2B-5AB7-8E1D-EFF3A5E4C7E8\")\n    (\"lmnopqrstuvwxyz{|}~ !\\\"#$%&\" #uuid \"CD66FFE0-37D2-55F6-8049-81F3AD4A881E\")\n    (\"mnopqrstuvwxyz{|}~ !\\\"#$%&'\" #uuid \"63638AF4-3E7C-5A7D-82E7-DC7FE152C0B7\")\n    (\"nopqrstuvwxyz{|}~ !\\\"#$%&'(\" #uuid \"1CBCA560-CE4A-52F6-B86C-F25CA1EAB1EC\")\n    (\"opqrstuvwxyz{|}~ !\\\"#$%&'()\" #uuid \"ED541D15-90DE-5790-AEAC-AE92696FE339\")\n    (\"pqrstuvwxyz{|}~ !\\\"#$%&'()*\" #uuid \"4DB93134-5B4E-537C-A178-3CE6E2EAB2F6\")\n    (\"qrstuvwxyz{|}~ !\\\"#$%&'()*+\" #uuid \"6402FA45-D31A-5E79-8CDA-F0B5F5BD88DD\")\n    (\"rstuvwxyz{|}~ !\\\"#$%&'()*+,\" #uuid \"063A63DF-A01A-5A67-9BB9-B3BF4E42131B\")\n    (\"stuvwxyz{|}~ !\\\"#$%&'()*+,-\" #uuid \"61DD21C6-2DB9-5C41-9602-577CCF4B7C8B\")\n    (\"tuvwxyz{|}~ !\\\"#$%&'()*+,-.\" #uuid \"6799784F-3507-5450-9274-D9BA10AFC752\")\n    (\"uvwxyz{|}~ !\\\"#$%&'()*+,-./\" #uuid \"30A6284C-6269-5D2E-98E3-7A87D84F51F1\")\n    (\"vwxyz{|}~ !\\\"#$%&'()*+,-./0\" #uuid \"18777242-8DF3-53AE-B695-FDCAF7E1E458\")\n    (\"wxyz{|}~ !\\\"#$%&'()*+,-./01\" #uuid \"ED8BA679-1BC9-5EB4-9EED-DD717809FEC2\")\n    (\"xyz{|}~ !\\\"#$%&'()*+,-./012\" #uuid \"CE96C5BE-70EE-5594-9A5B-8C96A456A6D9\")\n    (\"yz{|}~ !\\\"#$%&'()*+,-./0123\" #uuid \"5C884C16-E0B7-5A26-A32A-6DB49B501A1A\")\n    (\"z{|}~ !\\\"#$%&'()*+,-./01234\" #uuid \"7C0EBA71-82F0-5904-B745-75541AE65312\")\n    (\"{|}~ !\\\"#$%&'()*+,-./012345\" #uuid \"37CDD9D8-A94F-5BB5-AA57-97A92ACA22FC\")\n    (\"|}~ !\\\"#$%&'()*+,-./0123456\" #uuid \"BB23D8C2-29F0-5EC5-BF50-B7092FA62204\")\n    (\"}~ !\\\"#$%&'()*+,-./01234567\" #uuid \"AD3AD027-A2ED-5F09-B581-78AD87D86A7C\")\n    (\"~ !\\\"#$%&'()*+,-./012345678\" #uuid \"093B7461-98EF-55DC-8616-890210247499\")\n    ))\n\n\n(deftest check-v5-null-ns-cases\n  (testing \"v5 null-ns case-based correctness...\"\n    (doseq [case +v5-null-ns-cases+]\n      (is (= (second case) (v5 +null+ (first case)))))))\n\n\n\n(def +v5-dns-ns-cases+\n  '((\" !\\\"#$%&'()*+,-./0123456789\" #uuid \"20936B0A-AB47-5EBD-9788-7F379130910E\")\n    (\"!\\\"#$%&'()*+,-./0123456789:\" #uuid \"06454276-F2D4-5F4C-9A62-E9471E2D1EA4\")\n    (\"\\\"#$%&'()*+,-./0123456789:;\" #uuid \"AD979D13-7728-5FB1-8799-52D2B973DC7E\")\n    (\"#$%&'()*+,-./0123456789:;<\" #uuid \"E0A54D87-993D-510D-BB56-6660B266330F\")\n    (\"$%&'()*+,-./0123456789:;<=\" #uuid \"7F9C48C3-4145-5EDE-BE28-03EDD13C2FAB\")\n    (\"%&'()*+,-./0123456789:;<=>\" #uuid \"A9AAE61F-D1A3-5F61-BE26-FED829E8AB6D\")\n    (\"&'()*+,-./0123456789:;<=>?\" #uuid \"CF2DBC66-F8A6-50ED-B00A-9A6A6206CA8D\")\n    (\"'()*+,-./0123456789:;<=>?@\" #uuid \"84107B8C-C5EB-54B4-9ACE-B607F24BBB0F\")\n    (\"()*+,-./0123456789:;<=>?@A\" #uuid \"1D5E2031-445A-53F7-B088-4E20C41249ED\")\n    (\")*+,-./0123456789:;<=>?@AB\" #uuid \"CAB0515F-1641-56BA-9042-967CC0243D7E\")\n    (\"*+,-./0123456789:;<=>?@ABC\" #uuid \"7548EB9D-7A15-5C6A-BE64-D51BD5FD9EC8\")\n    (\"+,-./0123456789:;<=>?@ABCD\" #uuid \"73DF2DFA-3F14-557A-84FB-3C3011EC902E\")\n    (\",-./0123456789:;<=>?@ABCDE\" #uuid \"49DEDE7F-121B-5697-B478-16EBC77A2C1F\")\n    (\"-./0123456789:;<=>?@ABCDEF\" #uuid \"D4089686-20D4-5A75-9058-95C3289C9A91\")\n    (\"./0123456789:;<=>?@ABCDEFG\" #uuid \"E6312674-9157-5749-9A6E-760667886FD6\")\n    (\"/0123456789:;<=>?@ABCDEFGH\" #uuid \"E4C7BB57-9085-56DA-ADCA-4A742650EEDA\")\n    (\"0123456789:;<=>?@ABCDEFGHI\" #uuid \"C4863E91-D99C-5BFE-B44B-5E0D58EBE9B1\")\n    (\"123456789:;<=>?@ABCDEFGHIJ\" #uuid \"7A635616-E871-5962-821C-7F7FDA74627A\")\n    (\"23456789:;<=>?@ABCDEFGHIJK\" #uuid \"3F9F12F2-520F-522A-801C-C0EFA4078A1C\")\n    (\"3456789:;<=>?@ABCDEFGHIJKL\" #uuid \"820886F4-5CA7-595B-B484-FF40FC94D5CD\")\n    (\"456789:;<=>?@ABCDEFGHIJKLM\" #uuid \"436BA120-F191-54FE-9532-176DDBFFBA20\")\n    (\"56789:;<=>?@ABCDEFGHIJKLMN\" #uuid \"4054BBB1-FD3A-5D38-BA77-C6F5620904D9\")\n    (\"6789:;<=>?@ABCDEFGHIJKLMNO\" #uuid \"F9E7C39E-802E-53B3-B7CE-F84C02BDB3A8\")\n    (\"789:;<=>?@ABCDEFGHIJKLMNOP\" #uuid \"E620E967-540D-5D2A-A361-6E7F5B4DB83B\")\n    (\"89:;<=>?@ABCDEFGHIJKLMNOPQ\" #uuid \"2FCD4A7A-E98E-5D97-90CC-03DB0575EF80\")\n    (\"9:;<=>?@ABCDEFGHIJKLMNOPQR\" #uuid \"2442A8C4-DC2A-5A15-A65F-E3101E98E5CC\")\n    (\":;<=>?@ABCDEFGHIJKLMNOPQRS\" #uuid \"7C9CD2DF-338A-5F77-B9C2-4346854E55AF\")\n    (\";<=>?@ABCDEFGHIJKLMNOPQRST\" #uuid \"C8B122B0-C58A-5F38-84F7-4D5CDCE21CAA\")\n    (\"<=>?@ABCDEFGHIJKLMNOPQRSTU\" #uuid \"59176B9E-7ADC-5CC3-BC48-033A4D5DF013\")\n    (\"=>?@ABCDEFGHIJKLMNOPQRSTUV\" #uuid \"8BC00B22-EEF0-57A3-85D1-4ED9B3B28B8C\")\n    (\">?@ABCDEFGHIJKLMNOPQRSTUVW\" #uuid \"6E712F40-0361-53E0-9045-AD363F9C4333\")\n    (\"?@ABCDEFGHIJKLMNOPQRSTUVWX\" #uuid \"55AC4EE7-4E09-5257-9847-7F2DBE57C45B\")\n    (\"@ABCDEFGHIJKLMNOPQRSTUVWXY\" #uuid \"430C2AE3-8037-5CD7-A6C6-66A4E8AFC2AF\")\n    (\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\" #uuid \"8C31F75B-F02A-555C-9235-21C2CF0BA6FF\")\n    (\"BCDEFGHIJKLMNOPQRSTUVWXYZ[\" #uuid \"360A5E98-3C9D-5D1E-ACC9-65B7CE3CE70D\")\n    (\"CDEFGHIJKLMNOPQRSTUVWXYZ[\\\\\" #uuid \"4BC8DE4D-B04D-5D09-B6C3-93E69D774A34\")\n    (\"DEFGHIJKLMNOPQRSTUVWXYZ[\\\\]\" #uuid \"95990338-4A46-5875-AA9F-127F3F78B97E\")\n    (\"EFGHIJKLMNOPQRSTUVWXYZ[\\\\]^\" #uuid \"5079A2EE-3786-5E24-8253-3A045B856228\")\n    (\"FGHIJKLMNOPQRSTUVWXYZ[\\\\]^_\" #uuid \"C9C5363D-6470-5A55-8A58-6B3ADA8F61AC\")\n    (\"GHIJKLMNOPQRSTUVWXYZ[\\\\]^_`\" #uuid \"A0D07537-22DC-5DC1-A1FE-35F892AA7A9A\")\n    (\"HIJKLMNOPQRSTUVWXYZ[\\\\]^_`a\" #uuid \"A8FE82DA-8CE2-5266-970D-9D593A59606C\")\n    (\"IJKLMNOPQRSTUVWXYZ[\\\\]^_`ab\" #uuid \"05C970D7-9C81-5CE7-87C3-27008C8862D1\")\n    (\"JKLMNOPQRSTUVWXYZ[\\\\]^_`abc\" #uuid \"3F32768E-31FF-5E45-9DF4-61F4961144E0\")\n    (\"KLMNOPQRSTUVWXYZ[\\\\]^_`abcd\" #uuid \"927713A3-5D2C-562E-B288-B78ABDFAC527\")\n    (\"LMNOPQRSTUVWXYZ[\\\\]^_`abcde\" #uuid \"7FBF943F-6E9D-5B07-A2DA-B8A68FB256F7\")\n    (\"MNOPQRSTUVWXYZ[\\\\]^_`abcdef\" #uuid \"19D04CF8-537E-562C-8ED5-F9568C444F33\")\n    (\"NOPQRSTUVWXYZ[\\\\]^_`abcdefg\" #uuid \"2EAB5AE8-B9E2-5F3D-B66B-D45C929B4BBC\")\n    (\"OPQRSTUVWXYZ[\\\\]^_`abcdefgh\" #uuid \"4A489F5C-1E9F-5441-B49B-8018442346CC\")\n    (\"PQRSTUVWXYZ[\\\\]^_`abcdefghi\" #uuid \"B8DA5FD0-F067-57D0-A3CB-7BC7168BFDAB\")\n    (\"QRSTUVWXYZ[\\\\]^_`abcdefghij\" #uuid \"BF6C0099-7DBA-5198-88BF-B2A8E540A3CE\")\n    (\"RSTUVWXYZ[\\\\]^_`abcdefghijk\" #uuid \"49F92AD5-E5BD-5DE2-B1C2-167774882BC0\")\n    (\"STUVWXYZ[\\\\]^_`abcdefghijkl\" #uuid \"2862D585-D6E6-5994-98C7-736E5A0B8D77\")\n    (\"TUVWXYZ[\\\\]^_`abcdefghijklm\" #uuid \"BA036CCB-4051-5ED7-9602-76134092DAA5\")\n    (\"UVWXYZ[\\\\]^_`abcdefghijklmn\" #uuid \"AB6C1DE0-5BD7-53E3-B507-2F19972F8CA7\")\n    (\"VWXYZ[\\\\]^_`abcdefghijklmno\" #uuid \"3962BFC1-ADF7-57EF-AA6F-ECD29F1BE434\")\n    (\"WXYZ[\\\\]^_`abcdefghijklmnop\" #uuid \"93515E40-497D-583D-A4EC-2BE08089533A\")\n    (\"XYZ[\\\\]^_`abcdefghijklmnopq\" #uuid \"194AD9B4-04CF-51A3-8D2D-3AEAED62B84D\")\n    (\"YZ[\\\\]^_`abcdefghijklmnopqr\" #uuid \"C19D95E9-08C0-5E8D-93C3-FEE78F781408\")\n    (\"Z[\\\\]^_`abcdefghijklmnopqrs\" #uuid \"462415ED-8D55-5894-AEE0-A3F38A985FB1\")\n    (\"[\\\\]^_`abcdefghijklmnopqrst\" #uuid \"F0EF3EAA-3B12-5AE7-87E1-F2BA988B59CF\")\n    (\"\\\\]^_`abcdefghijklmnopqrstu\" #uuid \"859212C2-6DE4-5593-8986-5163D3D7851D\")\n    (\"]^_`abcdefghijklmnopqrstuv\" #uuid \"BFCFB5EC-0CE3-58FC-9BB3-1B3EB3B4FD98\")\n    (\"^_`abcdefghijklmnopqrstuvw\" #uuid \"01724DA7-DCAE-569B-8D14-D81F9A37295E\")\n    (\"_`abcdefghijklmnopqrstuvwx\" #uuid \"52443FBF-2C97-5DB2-BF13-AE9526B617D1\")\n    (\"`abcdefghijklmnopqrstuvwxy\" #uuid \"FF0EC0B6-CECB-517F-87A0-194759C2DFC4\")\n    (\"abcdefghijklmnopqrstuvwxyz\" #uuid \"E1CDA567-F00A-578F-B4EC-F248BD2743B2\")\n    (\"bcdefghijklmnopqrstuvwxyz{\" #uuid \"1B9A7485-0653-5110-8557-7EB635C0FD62\")\n    (\"cdefghijklmnopqrstuvwxyz{|\" #uuid \"EFFF805A-741C-5B3E-A5BC-5E0FCBBAC60A\")\n    (\"defghijklmnopqrstuvwxyz{|}\" #uuid \"A1F0CDFB-6C7F-5F8F-BBFC-8ACAB78F287F\")\n    (\"efghijklmnopqrstuvwxyz{|}~\" #uuid \"2153125C-E5C1-5805-A4A5-51923A40D57B\")\n    (\"fghijklmnopqrstuvwxyz{|}~ \" #uuid \"AE92DD4A-6B17-591C-A404-33548F8E0D08\")\n    (\"ghijklmnopqrstuvwxyz{|}~ !\" #uuid \"7D9703EA-F876-51AF-869A-ED3485EF40FA\")\n    (\"hijklmnopqrstuvwxyz{|}~ !\\\"\" #uuid \"00AA4363-CDAA-5A3F-8F00-C685EDFE1455\")\n    (\"ijklmnopqrstuvwxyz{|}~ !\\\"#\" #uuid \"19E4C188-E0B5-5770-B878-86227B76B26E\")\n    (\"jklmnopqrstuvwxyz{|}~ !\\\"#$\" #uuid \"E539E727-3605-5DEC-96CF-2F4FC633F57D\")\n    (\"klmnopqrstuvwxyz{|}~ !\\\"#$%\" #uuid \"EA16CBB8-B495-5113-8DC1-11ACBA333C2C\")\n    (\"lmnopqrstuvwxyz{|}~ !\\\"#$%&\" #uuid \"A2A8234B-874E-5C87-846A-0558FCF8C898\")\n    (\"mnopqrstuvwxyz{|}~ !\\\"#$%&'\" #uuid \"E9B76262-6370-5C36-BD09-627F0EC78E7E\")\n    (\"nopqrstuvwxyz{|}~ !\\\"#$%&'(\" #uuid \"6505BF7B-C096-5DDE-83D1-68BE3D450CC8\")\n    (\"opqrstuvwxyz{|}~ !\\\"#$%&'()\" #uuid \"2DAD12B6-17EA-5556-AEDF-B34FC0418BBD\")\n    (\"pqrstuvwxyz{|}~ !\\\"#$%&'()*\" #uuid \"797F9A21-4F7C-556C-8BB8-95337F4F47EF\")\n    (\"qrstuvwxyz{|}~ !\\\"#$%&'()*+\" #uuid \"D3674C30-0DA6-5F4D-9F36-C19C07E5B707\")\n    (\"rstuvwxyz{|}~ !\\\"#$%&'()*+,\" #uuid \"1F7BB665-4D61-59CF-8D4D-F3E203C99464\")\n    (\"stuvwxyz{|}~ !\\\"#$%&'()*+,-\" #uuid \"C3DC70CC-6B5E-53FE-B0D6-54131AD96063\")\n    (\"tuvwxyz{|}~ !\\\"#$%&'()*+,-.\" #uuid \"DE2F3C19-9075-5873-873C-94965089CFA7\")\n    (\"uvwxyz{|}~ !\\\"#$%&'()*+,-./\" #uuid \"1308A9AE-0A07-5DBD-8F78-EB5C6C1BB7DE\")\n    (\"vwxyz{|}~ !\\\"#$%&'()*+,-./0\" #uuid \"90A57D98-EB6A-52E9-92AA-6F1377741632\")\n    (\"wxyz{|}~ !\\\"#$%&'()*+,-./01\" #uuid \"A9216C3B-DFDD-561C-96B0-60EC57DF2176\")\n    (\"xyz{|}~ !\\\"#$%&'()*+,-./012\" #uuid \"7DCDFFF0-A0E0-5CE5-989D-61A73D67C4E8\")\n    (\"yz{|}~ !\\\"#$%&'()*+,-./0123\" #uuid \"7EA67B17-A917-5E1B-8807-818DC9B4A9E6\")\n    (\"z{|}~ !\\\"#$%&'()*+,-./01234\" #uuid \"E7BC2E14-9029-5BBF-8367-10437778EE67\")\n    (\"{|}~ !\\\"#$%&'()*+,-./012345\" #uuid \"2EB1112A-6E8D-55A7-B712-93B109E53CAF\")\n    (\"|}~ !\\\"#$%&'()*+,-./0123456\" #uuid \"5783E9F5-4723-503F-8800-9BF782817DC4\")\n    (\"}~ !\\\"#$%&'()*+,-./01234567\" #uuid \"CA765530-6B64-5791-AFD7-8138A5D1AB00\")\n    (\"~ !\\\"#$%&'()*+,-./012345678\" #uuid \"59B8A01C-BE09-50A6-802F-C93B1D6A5C8E\")\n    ))\n\n\n(deftest check-v5-dns-ns-cases\n  (testing \"v5 dns-ns case-based correctness...\"\n    (doseq [case +v5-dns-ns-cases+]\n      (is (= (second case) (v5 +namespace-dns+ (first case)))))))\n\n\n(def +v5-oid-ns-cases+\n  '((\" !\\\"#$%&'()*+,-./0123456789\" #uuid \"71D9EA92-356D-5940-B0A9-951BD32DDBAE\")\n    (\"!\\\"#$%&'()*+,-./0123456789:\" #uuid \"F3DDBCEB-D3AB-5B85-83E4-8B89B504FBED\")\n    (\"\\\"#$%&'()*+,-./0123456789:;\" #uuid \"C0C2E013-BE36-558E-9E9B-6D19BDEC4147\")\n    (\"#$%&'()*+,-./0123456789:;<\" #uuid \"8AE9B168-73AC-5788-AA22-7002D8D39921\")\n    (\"$%&'()*+,-./0123456789:;<=\" #uuid \"28A1EA4F-2FEE-5A36-9460-6DAEDB3FF36B\")\n    (\"%&'()*+,-./0123456789:;<=>\" #uuid \"C26A66CB-E2C0-59AE-A65A-A027DA13677D\")\n    (\"&'()*+,-./0123456789:;<=>?\" #uuid \"AE2B437A-0DA2-5988-883B-BEF432C63A43\")\n    (\"'()*+,-./0123456789:;<=>?@\" #uuid \"49AF28B5-F7F7-5720-840D-94A052236422\")\n    (\"()*+,-./0123456789:;<=>?@A\" #uuid \"390456C5-FB1B-52CB-B922-D9EE75F94F80\")\n    (\")*+,-./0123456789:;<=>?@AB\" #uuid \"104297AF-C263-5E38-8792-C2CE39168482\")\n    (\"*+,-./0123456789:;<=>?@ABC\" #uuid \"E6AA9B91-409E-58E1-8BFC-B3A9907F2749\")\n    (\"+,-./0123456789:;<=>?@ABCD\" #uuid \"B4CEB85C-FEB9-564A-AE1D-90273F89CC2B\")\n    (\",-./0123456789:;<=>?@ABCDE\" #uuid \"F245626A-71F8-5F73-A3B7-5DC122E0A768\")\n    (\"-./0123456789:;<=>?@ABCDEF\" #uuid \"85B90BEE-EE31-53BD-804B-61014E55DDE8\")\n    (\"./0123456789:;<=>?@ABCDEFG\" #uuid \"51A2EE70-605E-540D-819C-8F0231764259\")\n    (\"/0123456789:;<=>?@ABCDEFGH\" #uuid \"3A31EB3A-DE8C-520D-ADC9-2048C2B9123F\")\n    (\"0123456789:;<=>?@ABCDEFGHI\" #uuid \"4EB6C362-7709-5F58-AF4B-69BFB0D4D3E6\")\n    (\"123456789:;<=>?@ABCDEFGHIJ\" #uuid \"8EA7FFEC-7357-5073-9E90-9B6A6091BE38\")\n    (\"23456789:;<=>?@ABCDEFGHIJK\" #uuid \"4FEF89F0-0921-5118-A456-EFA5EB9FCFFB\")\n    (\"3456789:;<=>?@ABCDEFGHIJKL\" #uuid \"73C117FF-9E97-5950-8334-6A4777365851\")\n    (\"456789:;<=>?@ABCDEFGHIJKLM\" #uuid \"F3391045-7646-5944-9710-467598E6E3B4\")\n    (\"56789:;<=>?@ABCDEFGHIJKLMN\" #uuid \"0CE3D8DB-7C5E-5CA8-85B1-54C4C4B6D755\")\n    (\"6789:;<=>?@ABCDEFGHIJKLMNO\" #uuid \"8E34E08C-256B-5F08-B7DF-710AF259AE72\")\n    (\"789:;<=>?@ABCDEFGHIJKLMNOP\" #uuid \"DC721C82-30DC-51B8-890B-BA46CEFDAF22\")\n    (\"89:;<=>?@ABCDEFGHIJKLMNOPQ\" #uuid \"A303B3EC-12F5-5E20-B9BD-3AEA01124BB4\")\n    (\"9:;<=>?@ABCDEFGHIJKLMNOPQR\" #uuid \"75FC219A-ABE7-56C2-AD7A-9E91BB0E0504\")\n    (\":;<=>?@ABCDEFGHIJKLMNOPQRS\" #uuid \"F6183650-657C-5BB0-94CE-F9348D8EF981\")\n    (\";<=>?@ABCDEFGHIJKLMNOPQRST\" #uuid \"7B0B3E18-8370-55FD-AC8D-189697A6D008\")\n    (\"<=>?@ABCDEFGHIJKLMNOPQRSTU\" #uuid \"524D3B31-14EC-5906-BB3C-339F40F4B5C6\")\n    (\"=>?@ABCDEFGHIJKLMNOPQRSTUV\" #uuid \"9B3073B9-2786-566D-892F-8B5D0BB0BE2C\")\n    (\">?@ABCDEFGHIJKLMNOPQRSTUVW\" #uuid \"CBE55728-B4B1-5C5A-8A51-395B5236B73E\")\n    (\"?@ABCDEFGHIJKLMNOPQRSTUVWX\" #uuid \"474BDBD0-EEA8-57D8-A0BC-85AC730D2E83\")\n    (\"@ABCDEFGHIJKLMNOPQRSTUVWXY\" #uuid \"F031E945-A302-50ED-BEA1-625535DF0708\")\n    (\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\" #uuid \"D4D4B4F7-CA21-5A38-9A1A-B5952F780839\")\n    (\"BCDEFGHIJKLMNOPQRSTUVWXYZ[\" #uuid \"698B1CC6-4490-5AA6-8685-C4CA9A70B99C\")\n    (\"CDEFGHIJKLMNOPQRSTUVWXYZ[\\\\\" #uuid \"4F5CB0D5-5171-5AF3-86DB-C149DDA86CA0\")\n    (\"DEFGHIJKLMNOPQRSTUVWXYZ[\\\\]\" #uuid \"B1AEA275-F005-5B74-9545-5AD3AE481DA8\")\n    (\"EFGHIJKLMNOPQRSTUVWXYZ[\\\\]^\" #uuid \"3D891BBB-55FE-53EA-AA37-381DBE4B5B8F\")\n    (\"FGHIJKLMNOPQRSTUVWXYZ[\\\\]^_\" #uuid \"DD1DE872-0AE7-5A76-80A8-983D3B8B002D\")\n    (\"GHIJKLMNOPQRSTUVWXYZ[\\\\]^_`\" #uuid \"EE601373-012B-5CDD-9985-E1C1955AEBB1\")\n    (\"HIJKLMNOPQRSTUVWXYZ[\\\\]^_`a\" #uuid \"BE7276B7-7371-5208-AC0D-397C0D89DD84\")\n    (\"IJKLMNOPQRSTUVWXYZ[\\\\]^_`ab\" #uuid \"9D584707-CE26-5AEF-9CCC-E462EA568EE3\")\n    (\"JKLMNOPQRSTUVWXYZ[\\\\]^_`abc\" #uuid \"7B925C14-44FD-553A-A75F-B97369B97AF4\")\n    (\"KLMNOPQRSTUVWXYZ[\\\\]^_`abcd\" #uuid \"C445B204-6E1B-5D47-915F-8651014BD350\")\n    (\"LMNOPQRSTUVWXYZ[\\\\]^_`abcde\" #uuid \"DD7C53C8-D447-58DB-85F9-F8C37165F1B6\")\n    (\"MNOPQRSTUVWXYZ[\\\\]^_`abcdef\" #uuid \"B565C336-E751-5DCB-ABDD-D44C4D3E5576\")\n    (\"NOPQRSTUVWXYZ[\\\\]^_`abcdefg\" #uuid \"D4657BED-4DB4-579C-AF46-91442BEBCD03\")\n    (\"OPQRSTUVWXYZ[\\\\]^_`abcdefgh\" #uuid \"ECD09D93-66BB-590A-81A0-CE998E5A1C4E\")\n    (\"PQRSTUVWXYZ[\\\\]^_`abcdefghi\" #uuid \"665BBED6-C93C-5706-9A53-97346A5A675C\")\n    (\"QRSTUVWXYZ[\\\\]^_`abcdefghij\" #uuid \"9AB63221-3159-59F3-8B50-BCAD5FC4AD22\")\n    (\"RSTUVWXYZ[\\\\]^_`abcdefghijk\" #uuid \"41ACDB12-B0CE-5ED6-966C-35C85612106C\")\n    (\"STUVWXYZ[\\\\]^_`abcdefghijkl\" #uuid \"6F22A8AB-E584-59CC-9FFA-B662E614B29F\")\n    (\"TUVWXYZ[\\\\]^_`abcdefghijklm\" #uuid \"BAC2AFC2-362E-5339-B1EF-D19915309B3E\")\n    (\"UVWXYZ[\\\\]^_`abcdefghijklmn\" #uuid \"1C3CD630-FD8B-5D26-95C8-8C84B2314C63\")\n    (\"VWXYZ[\\\\]^_`abcdefghijklmno\" #uuid \"2453EBB1-5045-5C90-88B6-7B49AFD689F8\")\n    (\"WXYZ[\\\\]^_`abcdefghijklmnop\" #uuid \"DA7E4BB1-8A1B-5E4C-B394-AE369DCABCAF\")\n    (\"XYZ[\\\\]^_`abcdefghijklmnopq\" #uuid \"A2398C09-E200-502F-B0A3-EA9FA95D13E6\")\n    (\"YZ[\\\\]^_`abcdefghijklmnopqr\" #uuid \"9E505244-5804-5938-88C8-8FAF526F39BF\")\n    (\"Z[\\\\]^_`abcdefghijklmnopqrs\" #uuid \"D53E3FA0-EB27-56E9-9FAD-6D62EFEB433C\")\n    (\"[\\\\]^_`abcdefghijklmnopqrst\" #uuid \"E9BFA441-02D4-54B0-AC02-810B5EFD6D6C\")\n    (\"\\\\]^_`abcdefghijklmnopqrstu\" #uuid \"F31AF79E-228C-5194-B845-511FC0E806EA\")\n    (\"]^_`abcdefghijklmnopqrstuv\" #uuid \"45FF0AFD-5D35-5C0D-A7E7-51BD79186BA8\")\n    (\"^_`abcdefghijklmnopqrstuvw\" #uuid \"D0D588D4-7C0D-54B4-8286-7C7B15D62013\")\n    (\"_`abcdefghijklmnopqrstuvwx\" #uuid \"D9593422-69B8-590C-B207-F35C0974D60B\")\n    (\"`abcdefghijklmnopqrstuvwxy\" #uuid \"294448B1-C82C-5FF0-BB48-E97D4F9C88AF\")\n    (\"abcdefghijklmnopqrstuvwxyz\" #uuid \"6C7D893E-A11C-5274-B839-CA68CD47E627\")\n    (\"bcdefghijklmnopqrstuvwxyz{\" #uuid \"23F2DC57-D808-5892-90FD-C7453C8AF511\")\n    (\"cdefghijklmnopqrstuvwxyz{|\" #uuid \"43C0C792-0CDC-5D2E-A332-21243A3BF277\")\n    (\"defghijklmnopqrstuvwxyz{|}\" #uuid \"2CBF26D6-D0B0-5CE8-8CB8-D2E41C45A693\")\n    (\"efghijklmnopqrstuvwxyz{|}~\" #uuid \"5A43F434-1389-567B-8CF2-C6DC2CE12584\")\n    (\"fghijklmnopqrstuvwxyz{|}~ \" #uuid \"53014805-B9A6-5AEE-BCE7-8B625B191B21\")\n    (\"ghijklmnopqrstuvwxyz{|}~ !\" #uuid \"671E3E93-1193-527E-9036-BE959A40D657\")\n    (\"hijklmnopqrstuvwxyz{|}~ !\\\"\" #uuid \"F89DAAC8-2905-5ED9-A4B1-A32FD588C9CC\")\n    (\"ijklmnopqrstuvwxyz{|}~ !\\\"#\" #uuid \"0F0BE36D-B240-5915-8A63-826AE4CC1C60\")\n    (\"jklmnopqrstuvwxyz{|}~ !\\\"#$\" #uuid \"F8C0C1FE-D6D3-531E-B822-DD94B0F3B3D5\")\n    (\"klmnopqrstuvwxyz{|}~ !\\\"#$%\" #uuid \"24581D7C-0AE4-5BE4-9013-71CBC582E25D\")\n    (\"lmnopqrstuvwxyz{|}~ !\\\"#$%&\" #uuid \"DBE82A12-620C-548C-8D24-C432995DD0D6\")\n    (\"mnopqrstuvwxyz{|}~ !\\\"#$%&'\" #uuid \"83480C50-F2EE-5CF1-943E-2C5C4753D39F\")\n    (\"nopqrstuvwxyz{|}~ !\\\"#$%&'(\" #uuid \"61E3F2AE-7EA0-5D75-90BF-C3FB14C5B764\")\n    (\"opqrstuvwxyz{|}~ !\\\"#$%&'()\" #uuid \"95E8012A-8401-5AEE-8C55-C038233AA12D\")\n    (\"pqrstuvwxyz{|}~ !\\\"#$%&'()*\" #uuid \"0A76BB26-CB8F-5B74-A25C-7B14AA1231E3\")\n    (\"qrstuvwxyz{|}~ !\\\"#$%&'()*+\" #uuid \"D7C6DBD5-F976-5535-B447-E9887E9305B4\")\n    (\"rstuvwxyz{|}~ !\\\"#$%&'()*+,\" #uuid \"CFF90D62-C9AE-5D27-B71D-C26937F45B86\")\n    (\"stuvwxyz{|}~ !\\\"#$%&'()*+,-\" #uuid \"FA856CEE-2A0A-5FEF-A58E-E19998333A73\")\n    (\"tuvwxyz{|}~ !\\\"#$%&'()*+,-.\" #uuid \"EA8CC78B-3FED-5926-94CB-C07978EE18DD\")\n    (\"uvwxyz{|}~ !\\\"#$%&'()*+,-./\" #uuid \"8DD82AD7-11EC-520E-A620-42D7F71CDAE2\")\n    (\"vwxyz{|}~ !\\\"#$%&'()*+,-./0\" #uuid \"5835D993-AA8B-57A5-8128-84C57D100CB5\")\n    (\"wxyz{|}~ !\\\"#$%&'()*+,-./01\" #uuid \"B66C29F2-F34A-519F-B459-3EBF5301679F\")\n    (\"xyz{|}~ !\\\"#$%&'()*+,-./012\" #uuid \"9573FC13-FAAD-5BBE-8F3F-801A9B713DB2\")\n    (\"yz{|}~ !\\\"#$%&'()*+,-./0123\" #uuid \"5190E6CA-05CD-5970-86FA-9571C2CBC21D\")\n    (\"z{|}~ !\\\"#$%&'()*+,-./01234\" #uuid \"75A67394-441A-5BC5-AEC9-ADD6DC77DDBA\")\n    (\"{|}~ !\\\"#$%&'()*+,-./012345\" #uuid \"A2F570E1-A297-5F7E-BD15-AC9C76C8B07D\")\n    (\"|}~ !\\\"#$%&'()*+,-./0123456\" #uuid \"46610A2C-7628-5F1B-8C5A-155639D29120\")\n    (\"}~ !\\\"#$%&'()*+,-./01234567\" #uuid \"2127C846-ACF4-5418-8454-F8B7D309E338\")\n    (\"~ !\\\"#$%&'()*+,-./012345678\" #uuid \"9D321B3F-E7E8-53A3-9EA5-466DF23617A9\")\n    ))\n\n\n(deftest check-v5-oid-ns-cases\n  (testing \"v5 oid-ns case-based correctness...\"\n    (doseq [case +v5-oid-ns-cases+]\n      (is (= (second case) (v5 +namespace-oid+ (first case)))))))\n"
  },
  {
    "path": "test/clj_uuid/v6_test.clj",
    "content": "(ns clj-uuid.v6-test\n  \"Time based UUIDs tests\"\n  (:require [clojure.test   :refer :all]\n            [clojure.set]\n            [clj-uuid :as uuid :refer [v6 get-timestamp]]\n            [clj-uuid.clock :as clock]))\n\n(deftest check-v6-single-threaded\n  (let [iterations 1000000\n        groups     10]\n    (testing \"single-thread v6 uuid uniqueness...\"\n      (dotimes [_ groups]\n        (let [result (repeatedly iterations v6)]\n          (is (= (count result) (count (set result)))))))))\n\n(deftest check-v6-concurrency\n  (doseq [concur (range 2 9)]\n    (let [extent    1000000\n          agents    (map agent (repeat concur nil))\n          working   (map #(send-off %\n                            (fn [state]\n                              (repeatedly extent v6)))\n                      agents)\n          _         (apply await working)\n          answers   (map deref working)]\n      (testing (str \"concurrent v6 uuid uniqueness (\" concur \" threads)...\")\n        (is (= (* concur extent)\n               (count (apply clojure.set/union (map set answers))))))\n      (testing (str \"concurrent v6 monotonic increasing (\" concur \" threads)...\")\n        (is (every? identity (map (partial apply uuid/<) answers)))))))\n\n(deftest check-get-timestamp\n  (testing \"timestamp round-trip through v6 UUID\"\n    (dotimes [_ 100000]\n      (let [before (clock/monotonic-time)\n            u      (v6)\n            after  (clock/monotonic-time)]\n        (is (<= before (uuid/get-timestamp u) after))))))\n"
  },
  {
    "path": "test/clj_uuid/v7_test.clj",
    "content": "(ns clj-uuid.v7-test\n  (:require [clojure.test   :refer :all]\n            [clojure.set]\n            [clj-uuid :as uuid :refer [v7]]\n            [clj-uuid.clock :as clock])\n  (:import [clj_uuid.clock State]))\n\n(deftest check-v7-single-threaded\n  (let [iterations 1000000\n        groups     10]\n    (testing \"single-thread v7 uuid uniqueness...\"\n      (dotimes [_ groups]\n        (let [result (repeatedly iterations v7)]\n          (is (= (count result) (count (set result)))))))))\n\n(deftest check-v7-concurrency\n  (doseq [concur    (range 2 9)]\n    (let [extent    1000000\n          agents    (map agent (repeat concur nil))\n          working   (map #(send-off %\n                            (fn [state]\n                              (repeatedly extent v7)))\n                      agents)\n          _         (apply await working)\n          answers   (map deref working)]\n      (testing (str \"concurrent v7 uuid uniqueness (\" concur \" threads)...\")\n        (is (= (* concur extent)\n               (count (apply clojure.set/union (map set answers))))))\n\n      (testing (str \"concurrent v7 monotonic increasing (\" concur \" threads)...\")\n        (is (every? identity\n                    (map (partial apply uuid/<) answers)))))))\n\n(deftest check-get-timestamp\n  (dotimes [_ 1000000]\n    (let [time (.millis ^State (clock/monotonic-unix-time-and-random-counter))]\n      (with-redefs [clock/monotonic-unix-time-and-random-counter (fn [] (clock/->State (rand-int 4095) time))]\n        (is (= time (uuid/get-timestamp (v7)))\n            \"Timestamp should be retrievable from v7 UUID\")))))\n"
  },
  {
    "path": "test/clj_uuid/v7nc_test.clj",
    "content": "(ns clj-uuid.v7nc-test\n  (:require [clojure.test :refer :all]\n            [clojure.set]\n            [clj-uuid :as uuid :refer [v7nc]]))\n\n(deftest check-v7nc-version\n  (testing \"v7nc produces version 7 UUIDs\"\n    (dotimes [_ 100]\n      (is (= 7 (uuid/get-version (v7nc)))))))\n\n(deftest check-v7nc-variant\n  (testing \"v7nc produces variant 2 (RFC 4122) UUIDs\"\n    (dotimes [_ 100]\n      (is (= 2 (.variant (v7nc)))))))\n\n(deftest check-v7nc-single-threaded\n  (let [iterations 1000000\n        groups     10]\n    (testing \"single-thread v7nc uuid uniqueness...\"\n      (dotimes [_ groups]\n        (let [result (repeatedly iterations v7nc)]\n          (is (= (count result) (count (set result)))))))))\n\n(deftest check-v7nc-concurrency\n  (doseq [concur (range 2 9)]\n    (let [extent    1000000\n          agents    (map agent (repeat concur nil))\n          working   (map #(send-off %\n                            (fn [state]\n                              (repeatedly extent v7nc)))\n                      agents)\n          _         (apply await working)\n          answers   (map deref working)]\n      (testing (str \"concurrent v7nc uuid uniqueness (\" concur \" threads)...\")\n        (is (= (* concur extent)\n               (count (apply clojure.set/union (map set answers))))))\n\n      (testing (str \"concurrent v7nc monotonic increasing (\" concur \" threads)...\")\n        (is (every? identity\n                    (map (partial apply uuid/<) answers)))))))\n\n(deftest check-v7nc-timestamp\n  (testing \"v7nc timestamp round-trip\"\n    (dotimes [_ 100000]\n      (let [before (System/currentTimeMillis)\n            u      (v7nc)\n            after  (System/currentTimeMillis)]\n        (is (<= before (uuid/get-unix-time u) after))))))\n"
  },
  {
    "path": "test/clj_uuid/v8_test.clj",
    "content": "(ns clj-uuid.v8-test\n  \"Custom UUIDs tests\"\n  (:refer-clojure :exclude [uuid? max])\n  (:require [clojure.test :refer :all]\n            [clj-uuid     :refer :all :exclude [> < =]]))\n\n(deftest check-v8-special-cases\n  (testing \"v8 custom UUID\"\n    (is (= (v8  0  0)  #uuid \"00000000-0000-8000-8000-000000000000\"))\n    (is (= (v8  0  1)  #uuid \"00000000-0000-8000-8000-000000000001\"))\n    (is (= (v8  0 -1)  #uuid \"00000000-0000-8000-bfff-ffffffffffff\"))\n    (is (= (v8 -1  0)  #uuid \"ffffffff-ffff-8fff-8000-000000000000\"))\n    (is (= (v8 -1 -1)  #uuid \"ffffffff-ffff-8fff-bfff-ffffffffffff\"))))\n"
  }
]