以 32 字符的十六进制格式生成一个随机的 16 字节字符串
Generate a random 16-byte string in the 32-character hexadecimal format
我是 Elixir / Erlang 的新手。我已经使用 Ruby 一段时间了,我想将这段代码转换为 Elixir / Erlang。
SecureRandom::random_bytes(16).each_byte.map { |b| sprintf("%02X",b) }.join
%% Generate random bytes
<<X:128/big-unsigned-integer>> = crypto:strong_rand_bytes(16).
%% conver to hex
lists:flatten(io_lib:format("~32.16.0b", [X])).
要获得相同的结果,在 Elixir 中,您可以使用 Erlang 模块 :crypto.strong_rand_bytes(16)
生成随机数,并使用 Base.encode16
进行转换
查看 https://hexdocs.pm/elixir/Base.html 以更好地理解 Base
模块
.
示例:
:crypto.strong_rand_bytes(16) |> Base.encode16 # => "4B14868924ACEE98C9C9C404A1F87B08"
首先,您的 ruby 代码可以简化为:
SecureRandom.hex(16).upcase
接下来,在 erlang 中,“字符串”可能是一个模糊的概念。在 erlang 中,构建一个包含字符串块的列表,然后传递列表,然后当你需要输出字符串时,erlang 会自动为你加入块:
-module(a).
-compile(export_all).
go() ->
MyIolist = [ io_lib:format("~2.16.0B", [X]) || <<X>> <= crypto:strong_rand_bytes(16) ],
%% Print a ruler -------
Ruler = "1234567890",
lists:foreach(fun(_X) -> io:format("~s", [Ruler]) end,
lists:seq(1, 4) ),
io:format("~n"),
%%-----------------------
%% Print the list containing the chunks of the string:
io:format("~s~n", [MyIolist]).
格式顺序:
"~2.16.0B"
读作:
2 => field width,
16 => base (base 10 is the default)
0 => padding character (so that the integers 0-15 are represented by two characters)
~B => format code that allows you to specify the base of an integer and uses uppercase for letters
(the particulars go between ~ and B)
在shell中:
23> c(a).
a.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,a}
24> a:go().
1234567890123456789012345678901234567890
21755436149C16E0A9902F7B7E9F6929
ok
25> a:go().
1234567890123456789012345678901234567890
86D3850FA2590B810C1CAB0B965EE415
ok
26> a:go().
1234567890123456789012345678901234567890
A9C31CAFCC74C8311A5389E3BA1CD19F
ok
27> a:go().
1234567890123456789012345678901234567890
FB82878326F7B6FDB87069AF031345FF
ok
28> a:go().
1234567890123456789012345678901234567890
57515F06DFA699710E543D9885CB90ED
ok
29> a:go().
1234567890123456789012345678901234567890
F84B308723DB660A8A4371E3A80C23DC
ok
我 运行 重复了几次,所以你可以看到字符串的长度都是一样的。 16 个字节 * 2 hex_chars/byte = 32 个字符。
正如 Venkatakumar Srinivasan 所展示的,为了您的目的,您可以将所有 16 个字节(128 位)视为一个整数:
-module(a).
-compile(export_all).
go() ->
<<X:128>> = crypto:strong_rand_bytes(16),
Result = io_lib:format("~32.16.0B", [X]),
%% Print a ruler:
Ruler = "1234567890",
lists:foreach(fun(_X) -> io:format("~s", [Ruler]) end,
lists:seq(1, 4) ),
io:format("~n"),
%%-----------------------
%% Print the list containing the chunks of the string:
io:format("~s~n", Result).
在shell中:
42> c(a).
a.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,a}
43> a:go().
1234567890123456789012345678901234567890
551589BE1CB7B0C048AEF67DD9343F7F
ok
44> a:go().
1234567890123456789012345678901234567890
AC3DC11F714D7F8FE8ABBED566E9AB5B
ok
45> a:go().
1234567890123456789012345678901234567890
176530F08AFEC3B5452A818E4A95C743
ok
46> a:go().
1234567890123456789012345678901234567890
8F2E651B3D7D53AF88147244BB8F6153
ok
没有理由打电话给flatten()
。尽管 io_lib:format()
并不关心创建完整的字符串,但是当您告诉 erlang 使用格式序列 ~s
输出 io_lib:format()
返回的列表时,erlang 会将所有内容连接到一个字符串中.
我是 Elixir / Erlang 的新手。我已经使用 Ruby 一段时间了,我想将这段代码转换为 Elixir / Erlang。
SecureRandom::random_bytes(16).each_byte.map { |b| sprintf("%02X",b) }.join
%% Generate random bytes
<<X:128/big-unsigned-integer>> = crypto:strong_rand_bytes(16).
%% conver to hex
lists:flatten(io_lib:format("~32.16.0b", [X])).
要获得相同的结果,在 Elixir 中,您可以使用 Erlang 模块 :crypto.strong_rand_bytes(16)
生成随机数,并使用 Base.encode16
查看 https://hexdocs.pm/elixir/Base.html 以更好地理解 Base
模块
.
示例:
:crypto.strong_rand_bytes(16) |> Base.encode16 # => "4B14868924ACEE98C9C9C404A1F87B08"
首先,您的 ruby 代码可以简化为:
SecureRandom.hex(16).upcase
接下来,在 erlang 中,“字符串”可能是一个模糊的概念。在 erlang 中,构建一个包含字符串块的列表,然后传递列表,然后当你需要输出字符串时,erlang 会自动为你加入块:
-module(a).
-compile(export_all).
go() ->
MyIolist = [ io_lib:format("~2.16.0B", [X]) || <<X>> <= crypto:strong_rand_bytes(16) ],
%% Print a ruler -------
Ruler = "1234567890",
lists:foreach(fun(_X) -> io:format("~s", [Ruler]) end,
lists:seq(1, 4) ),
io:format("~n"),
%%-----------------------
%% Print the list containing the chunks of the string:
io:format("~s~n", [MyIolist]).
格式顺序:
"~2.16.0B"
读作:
2 => field width,
16 => base (base 10 is the default)
0 => padding character (so that the integers 0-15 are represented by two characters)
~B => format code that allows you to specify the base of an integer and uses uppercase for letters
(the particulars go between ~ and B)
在shell中:
23> c(a).
a.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,a}
24> a:go().
1234567890123456789012345678901234567890
21755436149C16E0A9902F7B7E9F6929
ok
25> a:go().
1234567890123456789012345678901234567890
86D3850FA2590B810C1CAB0B965EE415
ok
26> a:go().
1234567890123456789012345678901234567890
A9C31CAFCC74C8311A5389E3BA1CD19F
ok
27> a:go().
1234567890123456789012345678901234567890
FB82878326F7B6FDB87069AF031345FF
ok
28> a:go().
1234567890123456789012345678901234567890
57515F06DFA699710E543D9885CB90ED
ok
29> a:go().
1234567890123456789012345678901234567890
F84B308723DB660A8A4371E3A80C23DC
ok
我 运行 重复了几次,所以你可以看到字符串的长度都是一样的。 16 个字节 * 2 hex_chars/byte = 32 个字符。
正如 Venkatakumar Srinivasan 所展示的,为了您的目的,您可以将所有 16 个字节(128 位)视为一个整数:
-module(a).
-compile(export_all).
go() ->
<<X:128>> = crypto:strong_rand_bytes(16),
Result = io_lib:format("~32.16.0B", [X]),
%% Print a ruler:
Ruler = "1234567890",
lists:foreach(fun(_X) -> io:format("~s", [Ruler]) end,
lists:seq(1, 4) ),
io:format("~n"),
%%-----------------------
%% Print the list containing the chunks of the string:
io:format("~s~n", Result).
在shell中:
42> c(a).
a.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,a}
43> a:go().
1234567890123456789012345678901234567890
551589BE1CB7B0C048AEF67DD9343F7F
ok
44> a:go().
1234567890123456789012345678901234567890
AC3DC11F714D7F8FE8ABBED566E9AB5B
ok
45> a:go().
1234567890123456789012345678901234567890
176530F08AFEC3B5452A818E4A95C743
ok
46> a:go().
1234567890123456789012345678901234567890
8F2E651B3D7D53AF88147244BB8F6153
ok
没有理由打电话给flatten()
。尽管 io_lib:format()
并不关心创建完整的字符串,但是当您告诉 erlang 使用格式序列 ~s
输出 io_lib:format()
返回的列表时,erlang 会将所有内容连接到一个字符串中.