Skip to content

Instantly share code, notes, and snippets.

@caindy
Last active August 29, 2015 13:56
Show Gist options
  • Save caindy/8821426 to your computer and use it in GitHub Desktop.
Save caindy/8821426 to your computer and use it in GitHub Desktop.
Elixir module to create unique identifiers of specified length, with serialization to and from strings. Put here to solicit feedback on coding style/correctness, as I am new to Elixir.
defmodule Hello.Util.UUID do
def new(byte_count // 16) do
dividend = div(byte_count, 16)
remainder = rem(byte_count, 16)
cnt = case remainder do
r when r === 0 -> dividend
_ -> dividend + remainder
end
make cnt, byte_count, <<>>
end
defp make(0, byte_count, acc), do:
binary_part(acc, 0, byte_count)
defp make(cnt, byte_count, acc) do
u = :ossp_uuid.make :v4, :binary
make(cnt - 1, byte_count, acc <> u)
end
def valid?(uuid, bytes // 16)
def valid?(uuid, bytes) when is_binary(uuid) do
case uuid do
<<_::[size(bytes), binary]>> -> true
_ -> false
end
end
def valid?(uuid, bytes) when is_list(uuid) do
chars = bytes * 2
{:ok, r} = Regex.compile("[A-F0-9]{#{chars}}")
Regex.match?(r, uuid) and length_valid?(uuid, chars)
end
defp length_valid?(uuid, chars) when is_binary(uuid), do:
length_valid?(bitstring_to_list(uuid), chars)
defp length_valid?(uuid, chars) when is_list(uuid), do:
length(uuid) === chars
def to_string(uuid) when is_binary(uuid) do
l = lc <<nibble::4>> inbits uuid, do: hd(integer_to_list(nibble, 16))
:erlang.list_to_binary l
end
def from_string(uuid) when is_binary(uuid), do:
from_string(bitstring_to_list(uuid))
def from_string(uuid) when is_list(uuid), do:
append_byte(uuid, <<>>)
defp append_byte([], acc), do: acc
defp append_byte([x,y|rest], acc), do:
append_byte(rest, acc <> <<list_to_integer([x, y], 16)>>)
end
@caindy
Copy link
Author

caindy commented Feb 5, 2014

Hi Peter, thanks for checking this out!

So, I've been using the if/unless/cond for nil tests, mostly, but I agree the case here obscures the intent. In fact, this code was wrong. Here's the corrected version.

  def new(byte_count // 16) do 
    dividend = div(byte_count, 16)
    add = if rem(byte_count, 16) > 0, do: 1, else: 0
    make (dividend + add), byte_count, <<>>
  end

Thanks for your feedback 😊

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment