-
-
Save nickjj/99ea84f460f41dae4139d0610ce8030c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Original 730ms version to generate 5,000 random codes. | |
defmodule V1 do | |
def random_code() do | |
charset = "CDEFGHJKLMNPQRTUVWXYZ23679" |> String.split("", trim: true) | |
random_chars = Enum.reduce((0..16), [], fn (_i, acc) -> | |
[Enum.random(charset) | acc] | |
end) |> Enum.join("") | |
group_a = String.slice(random_chars, 1..4) | |
group_b = String.slice(random_chars, 5..8) | |
group_c = String.slice(random_chars, 9..12) | |
group_d = String.slice(random_chars, 13..16) | |
"#{group_a}-#{group_b}-#{group_c}-#{group_d}" | |
end | |
end | |
# 25ms version to generate 5,000 random codes. | |
defmodule V7 do | |
chars = 'CDEFGHJKLMNPQRTUVWXYZ23679' | |
@char_count length(chars) | |
for {char, i} <- Enum.with_index(chars, 1) do | |
def char(unquote(i)), do: unquote(char) | |
end | |
def generate() do | |
<< | |
char(:rand.uniform(@char_count)), | |
char(:rand.uniform(@char_count)), | |
char(:rand.uniform(@char_count)), | |
char(:rand.uniform(@char_count)), | |
?-, | |
char(:rand.uniform(@char_count)), | |
char(:rand.uniform(@char_count)), | |
char(:rand.uniform(@char_count)), | |
char(:rand.uniform(@char_count)), | |
?-, | |
char(:rand.uniform(@char_count)), | |
char(:rand.uniform(@char_count)), | |
char(:rand.uniform(@char_count)), | |
char(:rand.uniform(@char_count)), | |
?-, | |
char(:rand.uniform(@char_count)), | |
char(:rand.uniform(@char_count)), | |
char(:rand.uniform(@char_count)), | |
char(:rand.uniform(@char_count)) | |
>> | |
end | |
end | |
# 3ms version to generate 5,000 random codes. | |
defmodule V4 do | |
chars = 'CDEFGHJKLMNPQRTUVWXYZ23679CDEFGHJKL' | |
@chars List.to_tuple(chars) | |
def encode(data, charset) do | |
# Maps the data to the charset | |
encode(data, charset, []) | |
end | |
def encode(<<>>, _, acc) do | |
acc | |
end | |
def encode( | |
<<a::size(5), b::size(5), c::size(5), d::size(5), e::size(5), f::size(5), g::size(5), | |
h::size(5), a2::size(5), b2::size(5), c2::size(5), d2::size(5), e2::size(5), | |
f2::size(5), g2::size(5), h2::size(5), rest::binary>>, | |
charset, | |
acc | |
) do | |
encode(rest, charset, [ | |
IO.iodata_to_binary([ | |
elem(@chars, a), | |
elem(@chars, b), | |
elem(@chars, c), | |
elem(@chars, d), | |
'-', | |
elem(@chars, e), | |
elem(@chars, f), | |
elem(@chars, g), | |
elem(@chars, h), | |
'-', | |
elem(@chars, a2), | |
elem(@chars, b2), | |
elem(@chars, c2), | |
elem(@chars, d2), | |
'-', | |
elem(@chars, e2), | |
elem(@chars, f2), | |
elem(@chars, g2), | |
elem(@chars, h2) | |
]) | |
| acc | |
]) | |
end | |
def generate(n) do | |
# We need n codes | |
# Each code is 16 bytes from charset | |
# Each byte needs 5 bits of random data | |
# So the number of bytes needed is | |
# n * 16 / 8 * 5 = n * 2 * 5 = n * 10 | |
:crypto.strong_rand_bytes(n * 10) | |
|> encode(@chars) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment