{"id":17723601,"url":"https://github.com/doriantaylor/p5-data-uuid-ncname","last_synced_at":"2025-03-31T13:41:48.496Z","repository":{"id":5790488,"uuid":"7004722","full_name":"doriantaylor/p5-data-uuid-ncname","owner":"doriantaylor","description":"UUID::NCName converts UUID strings to/from valid NCName productions for use in (X|HT)ML.","archived":false,"fork":false,"pushed_at":"2022-10-14T03:52:31.000Z","size":236,"stargazers_count":0,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2023-03-12T10:11:35.616Z","etag":null,"topics":["ncname","perl","uuid"],"latest_commit_sha":null,"homepage":null,"language":"Perl","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/doriantaylor.png","metadata":{"files":{"readme":"README","changelog":"Changes","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-12-04T18:24:27.000Z","updated_at":"2022-10-14T03:52:37.000Z","dependencies_parsed_at":"2023-01-11T16:53:11.175Z","dependency_job_id":null,"html_url":"https://github.com/doriantaylor/p5-data-uuid-ncname","commit_stats":null,"previous_names":[],"tags_count":3,"template":null,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doriantaylor%2Fp5-data-uuid-ncname","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doriantaylor%2Fp5-data-uuid-ncname/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doriantaylor%2Fp5-data-uuid-ncname/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doriantaylor%2Fp5-data-uuid-ncname/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/doriantaylor","download_url":"https://codeload.github.com/doriantaylor/p5-data-uuid-ncname/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246475866,"owners_count":20783741,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ncname","perl","uuid"],"created_at":"2024-10-25T15:43:26.414Z","updated_at":"2025-03-31T13:41:48.476Z","avatar_url":"https://github.com/doriantaylor.png","language":"Perl","funding_links":[],"categories":[],"sub_categories":[],"readme":"NAME\n    Data::UUID::NCName - Make valid NCName tokens which are also UUIDs\n\nVERSION\n    Version 0.07\n\nSYNOPSIS\n        use Data::UUID::NCName qw(:all);\n\n        my $uuid  = '1ff916f3-6ed7-443a-bef5-f4c85f18cd10';\n        my $ncn   = to_ncname($uuid, version =\u003e 1);\n        my $ncn32 = to_ncname($uuid, version =\u003e 1, radix =\u003e 32);\n\n        # $ncn is now \"EH_kW827XQ6719MhfGM0QL\".\n        # $ncn32 is \"ed74rn43o25b255puzbprrtiql\" and case-insensitive.\n\n        # from Test::More, this will output 'ok':\n        is(from_ncname($ncn, version =\u003e 1),\n            $uuid, 'Decoding result matches original');\n\nDESCRIPTION\n    The purpose of this module is to devise an alternative representation of\n    the UUID \u003chttp://tools.ietf.org/html/rfc4122\u003e which conforms to the\n    constraints of various other identifiers such as NCName, and create an\n    isomorphic \u003chttp://en.wikipedia.org/wiki/Isomorphism\u003e mapping between\n    them.\n\nFORMAT DEPRECATION NOTICE\n    After careful consideration, I have decided to change the UUID-NCName\n    format in a minor yet incompatible way. In particular, I have moved the\n    quartet containing the \"variant\"\n    \u003chttps://tools.ietf.org/html/rfc4122#section-4.1.1\u003e to the very end of\n    the identifier, whereas it previously was mixed into the middle\n    somewhere.\n\n    This can be considered an application of Postel's Law\n    \u003chttps://en.wikipedia.org/wiki/Postel%27s_law\u003e, based on the assumption\n    that these identifiers will be generated through other methods, and\n    potentially naïvely. Like the \"version\" field, the \"variant\" field has a\n    limited acceptable range of values. If, for example, one were to attempt\n    to generate a conforming identifier by simply generating a random Base32\n    or Base64 string, it will be difficult to ensure that the \"variant\"\n    field will indeed conform when the identifier is converted to a standard\n    UUID. By moving the \"variant\" field out to the end of the identifier,\n    everything between the \"version\" and \"variant\" bookends can be generated\n    randomly without any further consideration, like so:\n\n        our @B64_ALPHA = ('A'..'Z', 'a'..'z', 0..9, qw(- _));\n\n        sub make_cheapo_b64_uuid_ncname () {\n            my @vals = map { int rand 64 } (1..20); # generate content\n            push @vals, 8 + int rand 4;             # last digit is special\n            'E' . join '', map { $B64_ALPHA[$_] } @vals; # 'E' for UUID V4\n        }\n\n        # voilà:\n        my $cheap = make_cheapo_b64_uuid_ncname;\n        # EPrakcT1o2arqWSOuIMGSK or something\n\n        # as expected, we can decode it (version 1, naturally)\n        my $uu = Data::UUID::NCName::from_ncname($cheap, version =\u003e 1);\n        # 3eb6a471-3d68-4d9a-aaea-5923ae20c192 - UUID is valid\n\n    Furthermore, since the default behaviour is to align the bits of the\n    last byte to the size of the encoding symbol, and since the \"variant\"\n    bits are masked, a compliant RFC4122 UUID will *always* end with \"I\",\n    \"J\", \"K\", or \"L\", in *both* Base32 (case-insensitive) and Base64\n    variants.\n\n    Since I have already released this module prior to this format change, I\n    have added a \"version\" parameter to both \"to_ncname\" and \"from_ncname\".\n    The version currently defaults to 1, the new one, but will issue a\n    warning if not explicitly set. Later I will finally remove the warning\n    with 1 as the default. This should ensure that any code written during\n    the transition produces the correct results.\n\n        Unless you have to support identifiers generated from version 0.04\n        or older, you should be running these functions with \"version =\u003e 1\".\n\nRATIONALE \u0026 METHOD\n    The UUID is a generic identifier which is large enough to be globally\n    unique. This makes it useful as a canonical name for data objects in\n    distributed systems, especially those that cross administrative\n    jurisdictions, such as the World-Wide Web. The representation\n    \u003chttp://tools.ietf.org/html/rfc4122#section-3\u003e, however, of the UUID,\n    precludes it from being used in many places where it would be useful to\n    do so.\n\n    In particular, there are grammars for many types of identifiers which\n    must not begin with a digit. Others are case-insensitive, or prohibited\n    from containing hyphens (present in both the standard notation and\n    Base64URL), or indeed anything outside of \"^[A-Za-z_][0-9A-Za-z_]*$\".\n\n    The hexadecimal notation of the UUID has a 5/8 chance of beginning with\n    a digit, Base64 has a 5/32 chance, and Base32 has a 3/16 chance. As\n    such, the identifier must be modified in such a way as to guarantee\n    beginning with an alphabetic letter (or underscore \"_\", but some\n    grammars even prohibit that, so we omit it as well).\n\n    While it is conceivable to simply add a padding character, there are a\n    few considerations which make it more appealing to derive the initial\n    character from the content of the UUID itself:\n\n    *   UUIDs are large (128-bit) identifiers as it is, and it is\n        undesirable to add meaningless syntax to them if we can avoid doing\n        so.\n\n    *   128 bits is an inconvenient number for aligning to both Base32 (130)\n        and Base64 (132), though 120 divides cleanly into 5, 6 and 8.\n\n    *   The 13th quartet, or higher four bits of the\n        \"time_hi_and_version_field\" of the UUID is constant, as it indicates\n        the UUID's version. If we encode this value using the scheme common\n        to both Base64 and Base32, we get values between \"A\" and \"P\", with\n        the valid subset between \"B\" and \"F\".\n\n    Therefore: extract the UUID's version quartet, shift all subsequent data\n    4 bits to the left, zero-pad to the octet, encode with either\n    *base64url* or *base32*, truncate, and finally prepend the encoded\n    version character. Voilà, one token-safe UUID.\n\nAPPLICATIONS\n    XML IDs\n        The \"ID\" production appears to have been constricted, inadvertently\n        or otherwise, from Name \u003chttp://www.w3.org/TR/xml11/#NT-Name\u003e in\n        both the XML 1.0 and 1.1 specifications, to NCName\n        \u003chttp://www.w3.org/TR/xml-names/#NT-NCName\u003e by XML Schema Part 2\n        \u003chttp://www.w3.org/TR/xmlschema-2/#ID\u003e. This removes the colon\n        character \":\" from the grammar. The net effect is that\n\n            \u003cfoo id=\"urn:uuid:b07caf81-baae-449d-8a2e-48c0f5fa5538\"/\u003e\n\n        while being a *well-formed* ID *and* valid under DTD validation, is\n        *not* valid per XML Schema Part 2 or anything that uses it (e.g.\n        Relax NG).\n\n    RDF blank node identifiers\n        Blank node identifiers in RDF are intended for serialization, to act\n        as a handle so that multiple RDF statements can refer to the same\n        blank node. The RDF abstract syntax specifies\n        \u003chttp://www.w3.org/TR/rdf-concepts/#section-URI-Vocabulary\u003e that the\n        validity constraints of blank node identifiers be delegated to the\n        concrete syntax specifications. The RDF/XML syntax specification\n        \u003chttp://www.w3.org/TR/rdf-syntax-grammar/#rdf-id\u003e lists the blank\n        node identifier as NCName. However, according to the Turtle spec\n        \u003chttp://www.w3.org/TR/turtle/#BNodes\u003e, this is a valid blank node\n        identifier:\n\n            _:42df00ec-30a2-431f-be9e-e3a612b325db\n\n        despite an older version\n        \u003chttp://www.w3.org/TeamSubmission/turtle/#nodeID\u003e listing a\n        production equivalent to the more conservative NCName. NTriples\n        syntax is even more constrained\n        \u003chttp://www.w3.org/TR/rdf-testcases/#ntriples\u003e, given as\n        \"^[A-Za-z][0-9A-Za-z]*$\".\n\n    Generated symbols\n\n            There are only two hard things in computer science: cache\n            invalidation and naming things [and off-by-one errors].\n\n            -- Phil Karlton [extension of unknown origin]\n\n        Suppose you wanted to create a literate programming\n        \u003chttp://en.wikipedia.org/wiki/Literate_programming\u003e system (I do).\n        One of your (my) stipulations is that the symbols get defined in the\n        *prose*, rather than the *code*. However, you (I) still want to be\n        able to validate the code's syntax, and potentially even run the\n        code, without having to commit to naming anything. You are (I am)\n        also interested in creating a global map of classes, datatypes and\n        code fragments, which can be operated on and tested in isolation,\n        ported to other languages, or transplanted into the more\n        conventional packages of programs, libraries and frameworks. The\n        Base32 UUID NCName representation should be adequate for placeholder\n        symbols in just about any programming language, save for those which\n        do not permit identifiers as long as 26 characters (which are\n        extremely scarce).\n\nEXPORT\n    No subroutines are exported by default. Be sure to include at least one\n    of the following in your \"use\" statement:\n\n    :all\n        Import all functions.\n\n    :decode\n        Import decode-only functions.\n\n    :encode\n        Import encode-only functions.\n\n    :32 Import base32-only functions.\n\n    :58 Import base58-only functions.\n\n    :64 Import base64-only functions.\n\nSUBROUTINES\n  to_ncname $UUID [, $RADIX ] [, %PARAMS ]\n    Turn $UUID into an NCName. The UUID can be in the canonical (hyphenated)\n    hexadecimal form, non-hyphenated hexadecimal, Base64 (regular and\n    base64url), or binary. The function returns a legal NCName equivalent to\n    the UUID, in either Base32, Base58, or Base64 (url), given a specified\n    $RADIX of 32, 58, or 64. If the radix is omitted, Base64 is assumed.\n\n    The following keyword parameters are also accepted, and override the\n    positional parameters where applicable:\n\n    radix 32|58|64\n        Either 32 or 64 to explicitly specify Base32, Base58, or Base64\n        output. Defaults to 64.\n\n    version 0|1\n        Version 0 will generate the original version of NCName identifiers,\n        prior to the changes noted above. Version 1 is the new version,\n        which is *not* backwards-compatible. The default, for a transitional\n        period, is to generate version 0, but complain about it. Set the\n        version explicitly (to 1, or to 0 if you need backwards\n        compatibility) to eliminate the warning messages.\n\n    align $FALSY|$TRUTHY\n        Align the last 4 bits to the Base32/Base64 symbol size. You almost\n        certainly want this, so the default is *true*. (Does not apply to\n        Base58.)\n\n  from_ncname $NCNAME [, $FORMAT [, $RADIX] ] [, %PARAMS ]\n    Turn an appropriate $NCNAME back into a UUID, where *appropriate*,\n    unless overridden by $RADIX, is defined beginning with one initial\n    alphabetic letter (A to Z, case-insensitive) followed by either:\n\n    25 Base32 characters, or\n    21 Base64URL characters.\n\n    The function will return \"undef\" immediately if it cannot match either\n    of these patterns. Input past the 21-character mark (for Base64) or\n    25-character mark (for Base32) is ignored.\n\n    This function returns a UUID of type $FORMAT, which if left undefined,\n    must be one of the following:\n\n    str The canonical UUID format, like so:\n        \"33fcc995-5d10-477e-a9b4-c9cc405bbf04\". This is the default.\n\n    hex The same thing, minus the hyphens.\n\n    b64 Base64.\n\n    bin A binary string.\n\n    This function also takes the new keyword-style parameters:\n\n    format\n        As above.\n\n    radix\n        As above.\n\n    version\n        Sets the identifier version. Defaults to version 0 with a warning.\n        See the note about setting an explicit \"version\" parameter in\n        \"to_ncname\".\n\n    align\n        Assume the last few bits are aligned to the symbol, as in\n        \"to_ncname\".\n\n  to_ncname_64 $UUID [, %PARAMS ]\n    Shorthand for Base64 NCNames.\n\n  from_ncname_64 $NCNAME [, $FORMAT | %PARAMS ]\n    Ditto.\n\n  to_ncname_58 $UUID [, %PARAMS ]\n    Shorthand for Base58 NCNames.\n\n  from_ncname_58 $NCNAME [, $FORMAT | %PARAMS ]\n    Ditto.\n\n  to_ncname_32 $UUID [, %PARAMS ]\n    Shorthand for Base32 NCNames.\n\n  from_ncname_32 $NCNAME [, $FORMAT | %PARAMS ]\n    Ditto.\n\nAUTHOR\n    Dorian Taylor, \"\u003cdorian at cpan.org\u003e\"\n\nBUGS\n    Please report bugs/issues/etc in GitHub\n    \u003chttps://github.com/doriantaylor/p5-data-uuid-ncname/issues\u003e.\n\n    *   MetaCPAN\n\n        \u003chttps://metacpan.org/release/Data-UUID-NCName\u003e\n\n    *   GitHub repository (bugs also go here)\n\n        \u003chttps://github.com/doriantaylor/p5-data-uuid-ncname\u003e\n\n    *   AnnoCPAN: Annotated CPAN documentation\n\n        \u003chttp://annocpan.org/dist/Data-UUID-NCName\u003e\n\n    *   CPAN Ratings\n\n        \u003chttp://cpanratings.perl.org/d/Data-UUID-NCName\u003e\n\nSEE ALSO\n    *   UUID::Tiny\n\n    *   Data::UUID\n\n    *   OSSP::uuid\n\n    *   RFC 4122 \u003chttp://tools.ietf.org/html/rfc4122\u003e\n\n    *   RFC 4648 \u003chttp://tools.ietf.org/html/rfc4648\u003e\n\n    *   Namespaces in XML \u003chttp://www.w3.org/TR/xml-names/#NT-NCName\u003e\n        (NCName)\n\n    *   W3C XML Schema Definition Language (XSD) 1.1 Part 2: Datatypes\n        \u003chttp://www.w3.org/TR/xmlschema11-2/#ID\u003e (ID)\n\n    *   RDF/XML Syntax Specification (Revised)\n        \u003chttp://www.w3.org/TR/rdf-syntax-grammar/#rdf-id\u003e\n\n    *   Turtle \u003chttp://www.w3.org/TR/turtle/#BNodes\u003e\n\n    This module lives under the \"Data::\" namespace for the purpose of\n    namespace hygiene. The main module *does not* depend on Data::UUID,\n    howevever the script uuid-ncname *does* depend on UUID::Tiny to generate\n    UUIDs.\n\nLICENSE AND COPYRIGHT\n    Copyright 2012-2018 Dorian Taylor.\n\n    Licensed under the Apache License, Version 2.0 (the \"License\"); you may\n    not use this file except in compliance with the License. You may obtain\n    a copy of the License at \u003chttp://www.apache.org/licenses/LICENSE-2.0\u003e .\n\n    Unless required by applicable law or agreed to in writing, software\n    distributed under the License is distributed on an \"AS IS\" BASIS,\n    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n    See the License for the specific language governing permissions and\n    limitations under the License.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdoriantaylor%2Fp5-data-uuid-ncname","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdoriantaylor%2Fp5-data-uuid-ncname","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdoriantaylor%2Fp5-data-uuid-ncname/lists"}