你使用哪个模块或库生成通用唯一标识符(UUID)?
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].
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.
我建议使用具有rebar支持的Erlang ossp-uuid nif绑定 https://github.com/yrashk/erlang-ossp-uuid
ossp_uuid:make(v4, text)
你为什么使用round(math:pow(2, 48))
?我认为1 bsl 48
会更快地工作,代码也不会失去可读性。
now/0
调用生成唯一ID而无需外部依赖项,因为由now调用生成的元组在VM内是绝对唯一的,并且在节点之间具有大概率的唯一性。这是一个库:
链接: https://gitlab.com/zxq9/zuuid
文档: http://zxq9.com/projects/zuuid/docs/
这是我所知道的唯一完整的 RFC-4122 UUID Erlang 实现,包括 v1、v2、v3、v4、v5 和“v6”建议实现为“vVI”,以及 NFC、Microsoft 和其他一些非 RFC 变体的变体检测机制。我编写了这个示例以展示风格和文档 - 基于我从 Erlang 列表上那些够好心的人们得到的数不胜数的建议。
附注: 非常感谢 erlang-questions 的精彩人员花时间指出我的问题。该库因此变得更加优秀。
这段代码生成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()。