[erlang-questions] Generating readable unique IDs for use outside erlang
Ulf Wiger
ulf.wiger@REDACTED
Thu Feb 10 17:01:23 CET 2011
On 10 Feb 2011, at 15:34, Dave Challis wrote:
> Is there a good (and fast) way of generating a unique id for use outside Erlang?
Depending on your needs, it could be useful to provide a mapping between
an internal id and an external, reasonably memorable, one.
This code is from a blog example in ErlHive
(http://erlhive.svn.sourceforge.net/viewvc/erlhive/trunk/lib/erlhive/examples/blog/src/flexiblog.erl?revision=69&view=markup)
The trick for generating a unique Id in this case was to rely on the Erlhive 'stream' data type:
new_blog(Properties) ->
Caller = erlhive.user:auth(),
B_props = blog_props(Properties),
N = erlhive.user:append([blogs, Caller], B_props),
Key = [blogs, Caller, N],
then providing conversion functions to/from external presentation:
%%% @spec (item()) -> string()
%%% @doc Converts an internal blog, article or comment identifier
%%% to an external representation.
%%%
id_to_string([blogs,U,I]) when is_binary(U), is_integer(I) ->
"blogs/" ++ .lists:concat([b2l(U), "/", i2l(I)]);
id_to_string([ba,U,I,J]) when is_binary(U), is_integer(I), is_integer(J) ->
"ba/" ++ blog_item_serial(U,I,J);
id_to_string([bc,U,I,J]) when is_binary(U), is_integer(I), is_integer(J) ->
"bc/" ++ blog_item_serial(U,I,J).
blog_item_serial(U, I, J) ->
.lists:concat([b2l(U), "/", i2l(I), "/", i2l(J)]).
b2l(B) ->
binary_to_list(B).
i2l(I) ->
integer_to_list(I).
%%% @spec (string()) -> item()
%%% @doc Converts an external string representation to an internal
%%% blog, article or comment identifier.
%%%
string_to_id("blogs/" ++ BStr) ->
{UStr, I} = one_int(BStr),
[blogs, list_to_binary(UStr), I];
string_to_id("ba/" ++ BIStr) ->
{UStr, I, J} = two_ints(BIStr),
[ba, list_to_binary(UStr), I, J];
string_to_id("bc/" ++ BIStr) ->
{UStr, I, J} = two_ints(BIStr),
[bc, list_to_binary(UStr), I, J].
one_int(Str) ->
{RevS, I} = pick(.lists:reverse(Str), []),
{.lists:reverse(RevS), I}.
two_ints(Str) ->
{Rest1, J} = pick(.lists:reverse(Str), []),
{Rest2, I} = pick(Rest1, []),
{.lists:reverse(Rest2), I, J}.
pick("/" ++ Rest, Acc) ->
{Rest, list_to_integer(Acc)};
pick([H|T], Acc) when H >= $0, H =< $9 ->
pick(T, [H|Acc]).
Otherwise, I too like the {node(), now()} version.
BR,
Ulf
>
> The best method I can find for generating a unique id is to use:
> {node(), now()}
>
> Which generates something like:
> {foo@REDACTED,{1297,347375,276224}}
>
> This works great, and is what I use within erlang.
>
> However, it looks a bit meaningless is likely to confuse users of the non-erlang application that uses it - is there a nice way to turn that into an integer, or series of integers instead?
>
> E.g. turning the above into:
> 3473290872_1297_347375_276224
> (or ideally a single integer)
>
> would be fine, but I'm not sure how to get an integer from a term.
>
> Chances are I'll be generating hundreds of thousands to several million of these, so I'm also a bit concerned about efficiency - turning the {node(), now()} tuple into a string would no doubt take up more memory (and some processing time).
>
> Any suggestions on this?
>
> --
> Dave Challis
> dsc@REDACTED
>
> ________________________________________________________________
> erlang-questions (at) erlang.org mailing list.
> See http://www.erlang.org/faq.html
> To unsubscribe; mailto:erlang-questions-unsubscribe@REDACTED
>
Ulf Wiger, CTO, Erlang Solutions, Ltd.
http://erlang-solutions.com
More information about the erlang-questions
mailing list