GithubHelp home page GithubHelp logo

elixir-uuid's Introduction

Elixir UUID

hex.pm version hex.pm downloads travis.ci build status

UUID generator and utilities for Elixir. See RFC 4122.

Note: Renamed from uuid to elixir_uuid as a solution to package name conflicts. Use elixir_uuid going forward.

Installation

The latest version is 1.2.0 and requires Elixir ~> 1.0. New releases may change this minimum compatible version depending on breaking language changes. The changelog lists every available release and its corresponding language version requirement.

Releases are published through hex.pm. Add as a dependency in your mix.exs file:

defp deps do
  [ { :elixir_uuid, "~> 1.2" } ]
end

UUID v1

Generated using a combination of time since the west adopted the gregorian calendar and the node id MAC address.

iex> UUID.uuid1()
"5976423a-ee35-11e3-8569-14109ff1a304"

UUID v3

Generated using the MD5 hash of a name and either a namespace atom or an existing UUID. Valid namespaces are: :dns, :url, :oid, :x500, :nil.

iex> UUID.uuid3(:dns, "my.domain.com")
"03bf0706-b7e9-33b8-aee5-c6142a816478"

iex> UUID.uuid3("5976423a-ee35-11e3-8569-14109ff1a304", "my.domain.com")
"0609d667-944c-3c2d-9d09-18af5c58c8fb"

UUID v4

Generated based on pseudo-random bytes.

iex> UUID.uuid4()
"fcfe5f21-8a08-4c9a-9f97-29d2fd6a27b9"

UUID v5

Generated using the SHA1 hash of a name and either a namespace atom or an existing UUID. Valid namespaces are: :dns, :url, :oid, :x500, :nil.

iex> UUID.uuid5(:dns, "my.domain.com")
"016c25fd-70e0-56fe-9d1a-56e80fa20b82"

iex> UUID.uuid5("fcfe5f21-8a08-4c9a-9f97-29d2fd6a27b9", "my.domain.com")
"b8e85535-761a-586f-9c04-0fb0df2cbe84"

Formatting

All UUID generator functions have an optional format parameter as the last argument.

Possible values: :default, :hex, :urn. Default value is :default and can be omitted.

:default is a standard UUID representation:

iex> UUID.uuid1()
"3c69679f-774b-4fb1-80c1-7b29c6e7d0a0"

iex> UUID.uuid4(:default)
"3c69679f-774b-4fb1-80c1-7b29c6e7d0a0"

iex> UUID.uuid3(:dns, "my.domain.com")
"03bf0706-b7e9-33b8-aee5-c6142a816478"

iex> UUID.uuid5(:dns, "my.domain.com", :default)
"016c25fd-70e0-56fe-9d1a-56e80fa20b82"

:hex is a valid hex string, corresponding to the standard UUID without the - (dash) characters:

iex> UUID.uuid4(:hex)
"19be859d0c1f4a7f95ddced995037350"

iex> UUID.uuid4(:weak, :hex)
"ebeff765ddc843e486c287fb668d5d37"

:urn is a standard UUID representation prefixed with the UUID URN:

iex> UUID.uuid1(:urn)
"urn:uuid:b7483bde-ee35-11e3-8daa-14109ff1a304"

Utility functions

Use UUID.info/1 and UUID.info!/1 to get a keyword list containing information about the given UUID. UUID.info/1 returns a tuple of {:ok, info} for valid cases or {:error, reason} if the argument is not a UUID string. UUID.info!/1 directly returns the info keyword list when successful or raises an ArgumentError for error cases.

iex> UUID.info!("870df8e8-3107-4487-8316-81e089b8c2cf")
[uuid: "870df8e8-3107-4487-8316-81e089b8c2cf",
 binary: <<135, 13, 248, 232, 49, 7, 68, 135, 131, 22, 129, 224, 137, 184, 194, 207>>,
 type: :default,
 version: 4,
 variant: :rfc4122]

iex> UUID.info!("8ea1513df8a14dea9bea6b8f4b5b6e73")
[uuid: "8ea1513df8a14dea9bea6b8f4b5b6e73",
 binary: <<142, 161, 81, 61, 248, 161, 77, 234, 155, 234, 107, 143, 75, 91, 110, 115>>,
 type: :hex,
 version: 4,
 variant: :rfc4122]

iex> UUID.info!("urn:uuid:ef1b1a28-ee34-11e3-8813-14109ff1a304")
[uuid: "urn:uuid:ef1b1a28-ee34-11e3-8813-14109ff1a304",
 binary: <<239, 27, 26, 40, 238, 52, 17, 227, 136, 19, 20, 16, 159, 241, 163, 4>>,
 type: :urn,
 version: 1,
 variant: :rfc4122]

Use UUID.string_to_binary!/1 to convert a valid UUID string to its raw binary equivalent. An ArgumentError is raised if the argument is not a valid UUID string.

iex> UUID.string_to_binary!("870df8e8-3107-4487-8316-81e089b8c2cf")
<<135, 13, 248, 232, 49, 7, 68, 135, 131,
            22, 129, 224, 137, 184, 194, 207>>

iex> UUID.string_to_binary!("8ea1513df8a14dea9bea6b8f4b5b6e73")
<<142, 161, 81, 61, 248, 161, 77, 234, 155,
            234, 107, 143, 75, 91, 110, 115>>


iex> UUID.string_to_binary!("urn:uuid:ef1b1a28-ee34-11e3-8813-14109ff1a304")
<<239, 27, 26, 40, 238, 52, 17, 227, 136,
            19, 20, 16, 159, 241, 163, 4>>

Use UUID.binary_to_string!/2 to convert valid UUID binary data to a String representation, with an optional format similar to the generator functions above. An ArgumentError is raised if the argument is not valid UUID binary data.

iex> UUID.binary_to_string!(<<135, 13, 248, 232, 49, 7, 68, 135, 131,
            22, 129, 224, 137, 184, 194, 207>>)
"870df8e8-3107-4487-8316-81e089b8c2cf"

iex> UUID.binary_to_string!(<<142, 161, 81, 61, 248, 161, 77, 234, 155,
            234, 107, 143, 75, 91, 110, 115>>, :hex)
"8ea1513df8a14dea9bea6b8f4b5b6e73"

iex> UUID.binary_to_string!(<<239, 27, 26, 40, 238, 52, 17, 227, 136,
            19, 20, 16, 159, 241, 163, 4>>, :urn)
"urn:uuid:ef1b1a28-ee34-11e3-8813-14109ff1a304"

Attribution

Some code ported from avtobiff/erlang-uuid.

Some helper functions from rjsamson/hexate.

License

Copyright 2014-2016 Andrei Mihu

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

elixir-uuid's People

Contributors

a-bro avatar alco avatar andykingking avatar bratsche avatar braunse avatar c-rack avatar homanchou avatar jfrolich avatar liveforeverx avatar lowks avatar lukad avatar milmazz avatar rossjones avatar whatyouhide avatar zyro avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

elixir-uuid's Issues

Why doesn't UUID version 5 give expected results?

I'm under the impression that UUID version 5, if given the same parameters, on different machines or different implementations should give back the same uuid.

Here is the ossp-uuid linux utility running on my mac terminal:

$ uuid -v5 ns:OID "hi.bye"
e1cd0925-0852-5171-9e44-5fce3d17ee7d

Here is the uuidutils gem running in ruby irb, as you can see it matches the linux utility.

irb> require 'uuidtools'
irb> UUIDTools::UUID.sha1_create(UUIDTools::UUID_OID_NAMESPACE, "hi.bye").to_s
 => "e1cd0925-0852-5171-9e44-5fce3d17ee7d"

But here is the output using iex:

iex> UUID.uuid5 :oid, "hi.bye"
"cb6215ac-0b53-5366-aa60-52194d5c46da"

I expect the elixir implementation to produce the same results as the linux and ruby implementation.

Crypto warning when compiling

Hi! Thanks for the lib!

I'm getting this when compiling:

==> elixir_uuid
Compiling 1 file (.ex)
warning: :crypto.hash/2 defined in application :crypto is used by the current application but the current application does not depend on :crypto. To fix this, you must do one of:

  1. If :crypto is part of Erlang/Elixir, you must include it under :extra_applications inside "def application" in your mix.exs

  2. If :crypto is a dependency, make sure it is listed under "def deps" in your mix.exs

  3. In case you don't want to add a requirement to :crypto, you may optionally skip this warning by adding [xref: [exclude: [:crypto]]] to your "def project" in mix.exs

Found at 2 locations:
  lib/uuid.ex:589: UUID.namebased_uuid/2
  lib/uuid.ex:593: UUID.namebased_uuid/2

warning: :crypto.strong_rand_bytes/1 defined in application :crypto is used by the current application but the current application does not depend on :crypto. To fix this, you must do one of:

  1. If :crypto is part of Erlang/Elixir, you must include it under :extra_applications inside "def application" in your mix.exs

  2. If :crypto is a dependency, make sure it is listed under "def deps" in your mix.exs

  3. In case you don't want to add a requirement to :crypto, you may optionally skip this warning by adding [xref: [exclude: [:crypto]]] to your "def project" in mix.exs

Found at 3 locations:
  lib/uuid.ex:383: UUID.uuid4/1
  lib/uuid.ex:560: UUID.uuid1_clockseq/0
  lib/uuid.ex:583: UUID.uuid1_node/1

Generated elixir_uuid app

Here are my versions:

Erlang/OTP 24 [erts-12.0.1] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [jit]

Interactive Elixir (1.12.0) - press Ctrl+C to exit (type h() ENTER for help)

but I also tested this on 1.11-OTP 22 and we get the same warning.

Would you welcome a PR that fixed the warning? I'll create one, feel free to merge if you'd like!

Thanks for the library!

UUID.info parses invalid uuid as valid

It seems that UUID.info/1 parses every numeric string with length 16 as uuid.

elixir-uuid version 1.2.1:

UUID.info("0000000000000000")
{:ok,
 [
   uuid: "0000000000000000",
   binary: "0000000000000000",
   type: :raw,
   version: 3,
   variant: :reserved_ncs
 ]}

In elixir-uuid version 1.2.0 behaviour is different and numeric string is parsed correctly.

UUID.info("0000000000000000")
{:error, "Invalid argument; Not a valid UUID: 0000000000000000"}

I was using UUID.info/1 to detect if arbitary string is uuid.
From README:

UUID.info/1 returns a tuple of {:ok, info} for valid cases or {:error, reason} if the argument is not a UUID string.

could not find an app file at "_build/prod/lib/uuid/ebin/uuid.app"

When compiled at the first time I met this error

Unchecked dependencies for environment prod:
* uuid (Hex package)
  could not find an app file at "_build/prod/lib/uuid/ebin/uuid.app". This may happen if the dependency was not yet compiled, or you specified the wrong application name in your deps, or the dependency indeed has no app file (then you can pass app: false as option)
** (Mix) Can't continue due to errors on dependencies

Rerun the compile will get a warning but everything goes right

warning: redefining module UUID (current version loaded from /Users/tristan/Coding/Teambition/private-manager/_build/prod/lib/elixir_uuid/ebin/Elixir.UUID.beam)
  lib/uuid.ex:1

What happened?

elixir version: 1.6.6
uuid version: 1.2

Add a note about the rename in the 1.1 documentation

It's unclear to new (or old) users that the library has been renamed to elixir_uuid. If you just google "elixir uuid", this page comes up as the first result:

https://hexdocs.pm/uuid/readme.html

which is the link to 1.1.8 of the library, the release just before the rename. On that page there's no indication of the rename, and no indication that there's any version later than 1.1.8.

Would it be possible to add a note to the readme for that version and make a 1.1.9 release so it shows up in hexdocs?

Error upon doing exrm release

Hello,

I'm trying to make make a release with exrm, which works (if you include :uuid in the main app mix.exs file under applications: [:uuid, ...]

However when I start my phoenix app I get the following error:

$ ./rel/webapp/bin/webapp console
{"Kernel pid terminated",application_controller,"{application_start_failure,uuid,{bad_return,{{'Elixir.UUID',start,[normal,[]]},{'EXIT',{undef,[{'Elixir.UUID',start,[normal,[]],[]},{application_master,start_it_old,4,[{file,\"application_master.erl\"},{line,273}]}]}}}}}"}

Any ideas?

Non-unique values for UUID.uuid4/0

An app I work on is using UUID.uuid4/0 to generate secret keys. We noticed some duplicate values in the db (yeah, I know, we should have a unique index on there).

I spun up a test to create several records and I'm seeing the same UUID on all of them. The docs say "this version uses pseudo-random bytes generated by the crypto module". Is it expected that repeat calls would not yield unique values?

Interestingly enough, if I call this function in a loop in an iex console I get different values... but it appears that records inserted in prod mode sometimes get duplicate values. Any help appreciated.

UUID.uuid1 fails on docker for mac beta

The current implementation only matches hwaddr of [0, 0, 0, 0, 0, 0] specifically; however, many other "empty" hwaddr addresses can be listed, especially with the docker for mac beta. This also causes problems with toniq on the docker for mac platform: joakimk/toniq#19

Docker for mac response to inet:getifaddrs()

{:ok,
 [{'lo',
   [flags: [:up, :loopback, :running], hwaddr: [0, 0, 0, 0, 0, 0],
    addr: {127, 0, 0, 1}, netmask: {255, 0, 0, 0},
    addr: {0, 0, 0, 0, 0, 0, 0, 1},
    netmask: {65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535}]},
  {'sit0', [flags: [], hwaddr: [0, 0, 0, 0]]},
  {'ip6tnl0',
   [flags: [], hwaddr: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]},
  {'ip6gre0',
   [flags: [], hwaddr: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]},
  {'eth0',
   [flags: [:up, :broadcast, :running, :multicast],
    hwaddr: [2, 63, 172, 57, 0, 2], addr: {172, 17, 0, 2},
    netmask: {255, 255, 0, 0}, broadaddr: {172, 17, 0, 2},
    addr: {65152, 0, 0, 0, 66, 44287, 65041, 2},
    netmask: {65535, 65535, 65535, 65535, 0, 0, 0, 0}]}]}

string_to_slug and vice versa

Would be nice to make the new :slug feature available in its own function, e.g.
UUID.string_to_slug!("870df8e8-3107-4487-8316-81e089b8c2cf")
and
UUID.slug_to_string!("<some slug>")

Readme should be updated accordingly.

uuid1/0 is slow because it gets the MAC address every time

Benchmarks suggest that uuid1/0 is slower than its counterparts by an order of magnitute of 100.

benchmark name     iterations   average time 
uuid5 dns             1000000   1.46 µs/op
uuid3 dns             1000000   1.51 µs/op
uuid4                 1000000   2.04 µs/op
uuid1                   10000   179.36 µs/op

Benchmarked why uuid1 is much slower than its counterparts:

benchmark name  iterations   average time 
uuid1_time        10000000   0.13 µs/op
uuid1_clockseq    10000000   0.78 µs/op
uuid1_node           10000   184.41 µs/op
uuid1                10000   192.78 µs/op

It's all :inet.getifaddrs/0's fault. I was thinking that we can easily cache this, by using ETS for OTP < 21.2 and persistent_term for OTP >= 21.2. This means getting the MAC address when the uuid application starts and then using that. This also means that if the address changes on the fly, it wouldn't get picked up. Are we fine with this? If so, I'll send a PR. Let me know your thoughts @zyro! 💟

UUID.valid?/2

It'd be handy for this library to provide some basic validation functions for uuids, too.

Might hack this together shortly, wanted to leave this here to remind myself in case I don't get around to it soon or somebody else want to take a stab at it.

I'm thinking it could support :version and :format opts––the format one to verify that the uuid is of a particular format, not to hint at the format of the argument for parsing purposes.

uuid1 issue on osx ?

Hello,

First thanks a lot for your library.

I'm trying to use elixir-uuid for a phoenix project. In fact, I'm using the coherence authentication lib which uses the uuid lib.
On a windows machine, no problem. But on a mac I get an error :
Invalid argument; Expected: <<clock_seq::14>>, <<node::48>> when trying to call the UUID.uuid1.
Is this linked to osx or something ?
Seems to be source of the problem :

def uuid1(_, _, _) do
    raise ArgumentError, message:
    "Invalid argument; Expected: <<clock_seq::14>>, <<node::48>>"
end

Sorry I'm starting with elixir/phoenix/... so I'm learning and I might be the cause of the problem :-)

What is this state of this project?

I see the maintainer is not responding to issues or PRs for like two years.

Are there any plans to keep maintinaing this @zyro?

Or is there anybody who will inherit it or take over?

There are useful PRs getting ignored, then closed by OP, like #45

function UUID.uuid4/0 is undefined (module UUID is not available)

I'm building the OTP release using Distillery with MIX_ENV=prod mix release --env=prod --verbose and running the foreground process. The application fails when one of the hex packages tries to call UUID.uuid4() function. I tried to connect to the remote console and call the function manually:

iex([email protected])1> UUID.uuid4()
** (UndefinedFunctionError) function UUID.uuid4/0 is undefined (module UUID is not available)
    UUID.uuid4()

I don't have such a problem when I run the application via mix:

~/D/A/driver-location ❯❯❯ iex -S mix run
Erlang/OTP 21 [erts-10.1.3] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [hipe] [dtrace]

Interactive Elixir (1.7.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> UUID.uuid4()
"caf94bb3-a34d-4013-943c-befd590bdb16"

Any ideas why it could happen?

could not find an app file at "_build/dev/lib/uuid/ebin/uuid.app".

I'm not sure what causes this but I'm wondering if it's two conflicting packages?

For example my project looks like this (simplified)

λ ~/code/anakin/ ye-kaffkae-publishre mix deps.tree
anakin
├── commanded ~> 0.18 (Hex package)
│   ├── elixir_uuid ~> 1.2 (Hex package)
├── example_dep ~> 2.0.3 (Hex package)
│   └── uuid ~> 1.1.8 (Hex package)
...

which causes the following issue when I clean the deps:

Unchecked dependencies for environment dev:
* uuid (Hex package)
  could not find an app file at "_build/dev/lib/uuid/ebin/uuid.app". This may happen if the dependency was not yet compiled, or you specified the wrong application name in your deps, or the dependency indeed has no app file (then you can pass app: false as option)
** (Mix) Can't continue due to errors on dependencies

Is this my issue? I'm not sure.

Warnings with Erlang 19.0

warning: crypto:rand_bytes/1 is deprecated and will be removed in a future release; use crypto:strong_rand_bytes/1
  lib/uuid.ex:310

warning: crypto:rand_bytes/1 is deprecated and will be removed in a future release; use crypto:strong_rand_bytes/1
  lib/uuid.ex:442

warning: crypto:rand_bytes/1 is deprecated and will be removed in a future release; use crypto:strong_rand_bytes/1
  lib/uuid.ex:465

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.