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

发布于 2024-08-10 02:19:46 字数 34 浏览 5 评论 0原文

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

What module or library do you use to generate universally unique identifier (UUID)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

初心未许 2024-08-17 02:19:46

对于像我这样未来的 Google 用户来说,avtobiff 的 erlang-uuid 工作起来非常简单。

For future googlers like myself, erlang-uuid from avtobiff works very simply.

南…巷孤猫 2024-08-17 02:19:46

来自 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].

from 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].
千紇 2024-08-17 02:19:46

来自 couchdb 的 Uuid 生成器:
http://svn.apache.org/viewvc/couchdb/主干/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.

Uuid generator from couchdb:
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.
尴尬癌患者 2024-08-17 02:19:46

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

ossp_uuid:make(v4, text)

I recommend using the ossp-uuid nif bindings for Erlang that has rebar support
https://github.com/yrashk/erlang-ossp-uuid

ossp_uuid:make(v4, text)
戏剧牡丹亭 2024-08-17 02:19:46

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

Why did you use round(math:pow(2, 48))? I think that 1 bsl 48 will work more quickly and code will not lose understanding.

牛↙奶布丁 2024-08-17 02:19:46

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

Try this one: https://github.com/afiskon/erlang-uuid-v4 The simplest implementation ever.

也只是曾经 2024-08-17 02:19:46

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

If you don't need follow RFC 4122 you can use now/0 call to generate unique ID without external dependencies, because tuple, generated by now call is absolutely unique inside VM and unique with large probability beetween nodes.

初吻给了烟 2024-08-17 02:19:46

这一个:

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

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

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

PS:非常感谢那些出色的 erlang-questions 人花时间对我提出的所有问题。 lib 对此要好得多。

This one:

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

Docs: http://zxq9.com/projects/zuuid/docs/

It is the only complete RFC-4122 UUID implementation in Erlang I'm aware of with v1, v2, v3, v4, v5, and the "v6" recommendation implemented as "vVI" as well as a variant detection mechanism for NFC, Microsoft, and a few other non-RFC flavors. I wrote this as an example of style and documentation -- based on the zillion recommendations I received from the kind-enough-to-be-mean folks on the Erlang list.

PS: Huge thanks to the awesome folks of erlang-questions for taking the time to sharpshoot me on everything. The lib is far better for it.

与之呼应 2024-08-17 02:19:46

此代码生成

-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].

用于编译运行的 V4 UUID 代码:c(uuid)。

对于运行代码:uuid:uuid_v4()。

This code generate V4 UUID code

-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].

For compile run : c(uuid).

For run code : uuid:uuid_v4().

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文