【问题标题】:Generate a random 16-byte string in the 32-character hexadecimal format以 32 个字符的十六进制格式生成一个随机的 16 字节字符串
【发布时间】:2021-06-28 21:24:35
【问题描述】:

我是 Elixir / Erlang 的新手。我使用 Ruby 已经有一段时间了,我想将这段代码转换为 Elixir / Erlang。

SecureRandom::random_bytes(16).each_byte.map { |b| sprintf("%02X",b) }.join

【问题讨论】:

    标签: erlang elixir


    【解决方案1】:
    %% 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])).
    

    【讨论】:

      【解决方案2】:

      为了得到同样的结果,在 Elixir 中你可以使用 Erlang 模块 :crypto.strong_rand_bytes(16) 生成随机数,然后使用 Base.encode16 进行转换

      查看https://hexdocs.pm/elixir/Base.html 以更好地了解Base 模块 . 示例:

      :crypto.strong_rand_bytes(16) |> Base.encode16 # => "4B14868924ACEE98C9C9C404A1F87B08"
      

      【讨论】:

        【解决方案3】:

        首先,您的 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)
        

        在外壳中:

        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/字节 = 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).
        

        在外壳中:

        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 会将所有内容组合成一个字符串。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-08-14
          • 2012-05-10
          • 2018-03-12
          • 2016-06-16
          • 2012-11-06
          • 1970-01-01
          • 1970-01-01
          • 2015-07-06
          相关资源
          最近更新 更多