10

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

4

9 回答 9

7

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

于 2013-07-08T17:43:26.220 回答
6

来自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].
于 2009-11-01T13:52:20.607 回答
5

来自 couchdb 的 Uuid 生成器: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.
于 2009-11-03T06:25:13.263 回答
4

我建议为具有钢筋支持的 Erlang 使用 ossp-uuid nif 绑定 https://github.com/yrashk/erlang-ossp-uuid

ossp_uuid:make(v4, text)
于 2012-09-05T17:57:24.317 回答
3

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

于 2009-11-02T08:05:02.073 回答
2

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

于 2013-05-03T07:34:37.380 回答
2

如果您不需要遵循RFC 4122,您可以使用now/0call 来生成没有外部依赖关系的唯一 ID,因为 now call 生成的元组在 VM 内部是绝对唯一的,并且在节点之间具有很大概率是唯一的。

于 2015-05-19T15:20:03.907 回答
2

这个:

库:https ://gitlab.com/zxq9/zuuid

文档:http: //zxq9.com/projects/zuuid/docs/

它是我所知道的 Erlang 中唯一完整的 RFC-4122 UUID 实现,其中 v1、v2、v3、v4、v5 和实现为“vVI”的“v6”推荐以及 NFC 的变体检测机制,Microsoft ,以及其他一些非 RFC 风格。我写这篇文章是作为样式和文档的一个例子——基于我从 Erlang 列表中那些足够善良的人那里收到的无数建议。

PS:非常感谢 erlang-questions 的优秀人员抽出时间对我进行了尖锐的分析lib对它来说要好得多。

于 2016-11-18T12:17:41.717 回答
1

此代码生成 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_v4()。

于 2021-06-06T21:03:50.117 回答