Skip to content

Commit

Permalink
Default to strong PRNG for UUID4, allow weak if explicitly requested. C…
Browse files Browse the repository at this point in the history
…loses #9.
  • Loading branch information
zyro committed Oct 24, 2015
1 parent 278d4c9 commit 3cdb903
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 9 deletions.
5 changes: 3 additions & 2 deletions .travis.yml
@@ -1,5 +1,6 @@
language: elixir
elixir:
- 1.0.4
- 1.0.5
otp_release:
- 17.1
- 18.0
sudo: false
4 changes: 4 additions & 0 deletions CHANGELOG.md
Expand Up @@ -7,6 +7,10 @@ None.

---

### v1.1.0, 24 Oct 2015, Elixir `~> 1.0`

* [Enhancement] `uuid4` now accepts an additional first argument `:strong` (default) or `:weak`, indicating whether to use strong PRNG or not.

### v1.0.1, 30 May 2015, Elixir `~> 1.0`

* [Internal] Use `:os.timestamp/1` instead of `:erlang.now/1`.
Expand Down
12 changes: 9 additions & 3 deletions README.md
Expand Up @@ -5,12 +5,12 @@ UUID generator and utilities for [Elixir](http://elixir-lang.org/). See [RFC 412

### Installation

The latest version is `1.0.1` and requires Elixir `~> 1.0`. New releases may change this minimum compatible version depending on breaking language changes. The [changelog](https://github.com/zyro/elixir-uuid/blob/master/CHANGELOG.md) lists every available release and its corresponding language version requirement.
The latest version is `1.1.0` and requires Elixir `~> 1.0`. New releases may change this minimum compatible version depending on breaking language changes. The [changelog](https://github.com/zyro/elixir-uuid/blob/master/CHANGELOG.md) lists every available release and its corresponding language version requirement.

Releases are published through [hex.pm](https://hex.pm/packages/uuid). Add as a dependency in your `mix.exs` file:
```elixir
defp deps do
[ { :uuid, "~> 1.0" } ]
[ { :uuid, "~> 1.1" } ]
end
```

Expand All @@ -37,11 +37,14 @@ iex> UUID.uuid3("5976423a-ee35-11e3-8569-14109ff1a304", "my.domain.com")

### UUID v4

Generated based on pseudo-random bytes.
Generated based on pseudo-random bytes. Accepts optional `:strong` (default) or `:weak` parameter.

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

iex> UUID.uuid4(:weak)
"cd63a9c4-0b4e-477a-8229-3f3aa971a37b"
```

### UUID v5
Expand Down Expand Up @@ -81,6 +84,9 @@ iex> UUID.uuid5(:dns, "my.domain.com", :default)
```elixir
iex> UUID.uuid4(:hex)
"19be859d0c1f4a7f95ddced995037350"

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

`:urn` is a standard UUID representation prefixed with the UUID URN:
Expand Down
32 changes: 31 additions & 1 deletion lib/uuid.ex
Expand Up @@ -261,29 +261,59 @@ defmodule UUID do
Generate a new UUID v4. This version uses pseudo-random bytes generated by
the `crypto` module.
Accepts optional `:strong` (default) or `:weak` parameter.
## Examples
```elixir
# Equivalent to: UUID.uuid4(:strong, :default)
iex> UUID.uuid4()
"fb49a0ec-d60c-4d20-9264-3b4cfe272106"
# Equivalent to: UUID.uuid4(:strong, :default)
iex> UUID.uuid4(:strong)
"fb49a0ec-d60c-4d20-9264-3b4cfe272106"
# Equivalent to: UUID.uuid4(:weak, :default)
iex> UUID.uuid4(:weak)
"cd63a9c4-0b4e-477a-8229-3f3aa971a37b"
# Equivalent to: UUID.uuid4(:strong, :default)
iex> UUID.uuid4(:default)
"fb49a0ec-d60c-4d20-9264-3b4cfe272106"
# Equivalent to: UUID.uuid4(:strong, :hex)
iex> UUID.uuid4(:hex)
"fb49a0ecd60c4d2092643b4cfe272106"
# Equivalent to: UUID.uuid4(:strong, :urn)
iex> UUID.uuid4(:urn)
"urn:uuid:fb49a0ec-d60c-4d20-9264-3b4cfe272106"
iex> UUID.uuid4(:weak, :urn)
"urn:uuid:cd63a9c4-0b4e-477a-8229-3f3aa971a37b"
```
"""
def uuid4(format \\ :default) do
def uuid4(), do: uuid4(:strong, :default)

def uuid4(:strong), do: uuid4(:strong, :default)
def uuid4(:weak), do: uuid4(:weak, :default)
def uuid4(format), do: uuid4(:strong, format)

def uuid4(:strong, format) do
<<u0::48, _::4, u1::12, _::2, u2::62>> = :crypto.strong_rand_bytes(16)
<<u0::48, @uuid_v4::4, u1::12, @variant10::2, u2::62>>
|> uuid_to_string format
end
def uuid4(:weak, format) do
<<u0::48, _::4, u1::12, _::2, u2::62>> = :crypto.rand_bytes(16)
<<u0::48, @uuid_v4::4, u1::12, @variant10::2, u2::62>>
|> uuid_to_string format
end
def uuid4(_, _) do
raise ArgumentError, message: "Invalid argument; Expected :strong|:weak"
end

@doc """
Generate a new UUID v5. This version uses an SHA1 hash of fixed value (chosen
Expand Down
2 changes: 1 addition & 1 deletion mix.exs
Expand Up @@ -4,7 +4,7 @@ defmodule UUID.Mixfile do
def project do
[app: :uuid,
name: "UUID",
version: "1.0.1",
version: "1.1.0",
source_url: "https://github.com/zyro/elixir-uuid",
homepage_url: "http://hexdocs.pm/uuid",
elixir: "~> 1.0",
Expand Down
4 changes: 2 additions & 2 deletions mix.lock
@@ -1,3 +1,3 @@
%{"benchfella": {:hex, :benchfella, "0.2.1"},
"earmark": {:hex, :earmark, "0.1.17"},
"ex_doc": {:hex, :ex_doc, "0.8.4"}}
"earmark": {:hex, :earmark, "0.1.18"},
"ex_doc": {:hex, :ex_doc, "0.10.0"}}

0 comments on commit 3cdb903

Please sign in to comment.