代码之家  ›  专栏  ›  技术社区  ›  Kirill Trofimov

erlang:uuid生成器

  •  9
  • Kirill Trofimov  · 技术社区  · 16 年前

    您使用什么模块或库来生成通用唯一标识符(UUID)?

    8 回复  |  直到 5 年前
        1
  •  7
  •   Cody Poll    13 年前

    对于像我这样的未来谷歌人, erlang-uuid from avtobiff 工作非常简单。

        2
  •  6
  •   Tzury Bar Yochay    16 年前

    从…起 http://github.com/travis/erlang-uuid

    -module(uuid).
    -export([v4/0, to_string/1, get_parts/1]).
    -import(random).
    
    v4() ->
        v4(random:uniform(math:pow(2, 48)) - 1, random:uniform(math:pow(2, 12)) - 1, random:uniform(math:pow(2, 32)) - 1, random:uniform(math:pow(2, 30)) - 1).
    v4(R1, R2, R3, R4) ->
        <<R1:48, 4:4, R2:12, 2:2, R3:32, R4: 30>>.
    to_string(U) ->
        lists:flatten(io_lib:format("~8.16.0b-~4.16.0b-~4.16.0b-~2.16.0b~2.16.0b-~12.16.0b", get_parts(U))).
    
    get_parts(<<TL:32, TM:16, THV:16, CSR:8, CSL:8, N:48>>) ->
        [TL, TM, THV, CSR, CSL, N].
    
        3
  •  5
  •   toraritte    6 年前

    http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_uuids.erl

    % Licensed under the Apache License, Version 2.0 (the "License"); you may not
    % use this file except in compliance with the License. You may obtain a copy of
    % the License at
    %
    %   http://www.apache.org/licenses/LICENSE-2.0
    %
    % Unless required by applicable law or agreed to in writing, software
    % distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
    % WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
    % License for the specific language governing permissions and limitations under
    % the License.
    -module(couch_uuids).
    -include("couch_db.hrl").
    
    -behaviour(gen_server).
    
    -export([start/0, stop/0]).
    -export([new/0, random/0, utc_random/0]).
    
    -export([init/1, terminate/2, code_change/3]).
    -export([handle_call/3, handle_cast/2, handle_info/2]).
    
    start() ->
        gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
    
    stop() ->
        gen_server:cast(?MODULE, stop).
    
    new() ->
        gen_server:call(?MODULE, create).
    
    random() ->
        list_to_binary(couch_util:to_hex(crypto:rand_bytes(16))).
    
    utc_random() ->
        Now = {_, _, Micro} = now(),
        Nowish = calendar:now_to_universal_time(Now),
        Nowsecs = calendar:datetime_to_gregorian_seconds(Nowish),
        Then = calendar:datetime_to_gregorian_seconds({{1970, 1, 1}, {0, 0, 0}}),
        Prefix = io_lib:format("~14.16.0b", [(Nowsecs - Then) * 1000000 + Micro]),
        list_to_binary(Prefix ++ couch_util:to_hex(crypto:rand_bytes(9))).
    
    init([]) ->
        ok = couch_config:register(
            fun("uuids", _) -> gen_server:cast(?MODULE, change) end
        ),
        {ok, state()}.
    
    terminate(_Reason, _State) ->
        ok.
    
    handle_call(create, _From, random) ->
        {reply, random(), random};
    handle_call(create, _From, utc_random) ->
        {reply, utc_random(), utc_random};
    handle_call(create, _From, {sequential, Pref, Seq}) ->
        Result = ?l2b(Pref ++ io_lib:format("~6.16.0b", [Seq])),
        case Seq >= 16#fff000 of
            true ->
                {reply, Result, {sequential, new_prefix(), inc()}};
            _ ->
                {reply, Result, {sequential, Pref, Seq + inc()}}
        end.
    
    handle_cast(change, _State) ->
        {noreply, state()};
    handle_cast(stop, State) ->
        {stop, normal, State};
    handle_cast(_Msg, State) ->
        {noreply, State}.
    
    handle_info(_Info, State) ->
        {noreply, State}.
    
    code_change(_OldVsn, State, _Extra) ->
        {ok, State}.
    
    new_prefix() ->
        couch_util:to_hex((crypto:rand_bytes(13))).
    
    inc() ->
        crypto:rand_uniform(1, 16#ffe).
    
    state() ->
        AlgoStr = couch_config:get("uuids", "algorithm", "random"),
        case couch_util:to_existing_atom(AlgoStr) of
            random ->
                random;
            utc_random ->
                utc_random;
            sequential ->
                {sequential, new_prefix(), inc()};
            Unknown ->
                throw({unknown_uuid_algorithm, Unknown})
        end.
    
        4
  •  4
  •   mokele    14 年前
        5
  •  3
  •   razumyan    16 年前

    你为什么用这个 round(math:pow(2, 48)) ? 我认为 1 bsl 48 将更快地工作,代码不会失去理解。

        6
  •  2
  •   Aleksander Alekseev    13 年前

    https://github.com/afiskon/erlang-uuid-v4 有史以来最简单的实现。

        7
  •  2
  •   DenisKolodin    11 年前

    如果你不需要跟随 RFC 4122 你可以用 now/0

        8
  •  2
  •   zxq9    5 年前
        9
  •  1
  •   suraj    5 年前

    此代码生成V4 UUID代码

    -module(uuid).
    -export([uuid_v4/0]).
    -define(VARIANT10, 2#10).
    -define(UUIDv4, 4).
    
    
    uuid_v4() ->
        <<U0:32, U1:16, _:4, U2:12, _:2, U3:30, U4:32>> = crypto:strong_rand_bytes(16),
        lists:flatten(io_lib:format("~8.16.0b-~4.16.0b-~4.16.0b-~2.16.0b~2.16.0b-~12.16.0b",get_binary_uuid(<<U0:32, U1:16, ?UUIDv4:4, U2:12, ?VARIANT10:2, U3:30, U4:32>>))).
    
    get_binary_uuid(<<TL:32, TM:16, THV:16, CSR:8, CSL:8, N:48>>) ->
        [TL, TM, THV, CSR, CSL, N].
    
    

    对于编译运行:c(uuid)。

    对于运行代码:uuid:uuid\u v4()。