Мне нужно иметь возможность генерировать случайные строки с правильными URL-адресами, чтобы я мог использовать их в ссылках (например, в ссылке активации, отправленной пользователю электронной почты), поэтому как я могу ее создать? Есть ли способ сделать это только с Elixir или мне нужно будет использовать некоторую библиотеку?
Как создать случайную безопасную строку с Elixir
Ответ 1
Вместо этого вы можете создать строку с кодировкой Base64, которая будет использоваться в качестве токена подтверждения. Этот токен подтверждения будет затем сохранен в вашей БД и передан в качестве параметров для ссылки активации. Ваш URL-адрес активации будет выглядеть примерно так:
activation_url(MyApp.Endpoint, :confirm, confirm_id: confirm_id)
Вышеупомянутый помощник URL предполагает, что в этом контроллере есть действие MyApp.ActivationController
и confirm/2
. Чтобы сгенерировать confirm_id
, вы можете сделать:
def random_string(length) do
:crypto.strong_rand_bytes(length) |> Base.url_encode64 |> binary_part(0, length)
end
# random_string(64)
В вашем MyApp.ActivationController.confirm/2
у вас может быть код lik:
def confirm(conn, %{"confirm_id" => confirm_id}) do
user = Repo.get_by(User, confirm_id: confirm_id)
User.confirm(user)
conn
|> put_flash(:info, "Account confirmed!")
|> redirect(to: "/")
end
Надеюсь, что это поможет!
Ответ 2
Вы можете легко определить модуль для этого. В этом примере @chars
определяет, какие символы появляются в ваших сгенерированных строках.
defmodule StringGenerator do
@chars "ABCDEFGHIJKLMNOPQRSTUVWXYZ" |> String.split("")
def string_of_length(length) do
Enum.reduce((1..length), [], fn (_i, acc) ->
[Enum.random(@chars) | acc]
end) |> Enum.join("")
end
end
StringGenerator.string_of_length(3) # => "YCZ"
Ответ 3
Как отмечено в комментарии @JimGray, ваша спецификация должна действительно быть в терминах количества энтропии, которую вы хотите представлять случайными URL-адресами. Что-то вроде строк "Мне нужны N бит", потому что кто-то сказал вам использовать N бит, или "Я хочу избежать повторения в N строках, и я могу принять риск 1 в n столкновения". В любом случае, это непосредственно об энтропии и только косвенно о длине строки.
Например, убедитесь, что если вы используете такое решение, как ответ @Gjaldon, вы понимаете, хотя используется 512 бит случайности, количество энтропии для фактической строки, генерируемой random_string(64)
, составляет 320 бит. Насколько это достаточно, конечно, зависит от вашего сценария, который, как отмечено выше, вероятно, лучше всего выражается, например, "Мне нужно миллион строк с не более чем 1 триллионом риска повторения", и в этом случае 320 бит грубого избытка, поскольку вам понадобится только 79.
Если вам требуется больше контроля и понимания генерации случайных строк, посмотрите EntropyString. С помощью этой библиотеки вы можете сделать что-то вроде следующего, чтобы получить строку с 256 битами энтропии:
iex> defmodule Id, do: use EntropyString, charset: charset64
iex> Id.token
"ziKYK7t5LzVYn5XiJ_jYh30KxCCsLorRXqLwwEnZYHJ"
Или, если вы реализуете миллион строк с повторным риском в 1 триллион, достаточно, вы можете настроить свое генерирование Id, например:
iex> defmodule Id do
...> use EntropyString, charset: charset64
...> @bits entropy_bits(1.0e6, 1.0e12)
...> def random, do: Id.random_string(@bits)
...> end
iex> Id.random
"FhlGVXOaXV9f3f"
В любом случае, управление и понимание - это приятные вещи.