Procházet zdrojové kódy

base62 encode/decode

Feng Lee před 9 roky
rodič
revize
e16f8506ef
2 změnil soubory, kde provedl 77 přidání a 2 odebrání
  1. 58 0
      src/emqttd_base62.erl
  2. 19 2
      test/emqttd_lib_SUITE.erl

+ 58 - 0
src/emqttd_base62.erl

@@ -0,0 +1,58 @@
+%%--------------------------------------------------------------------
+%% Copyright (c) 2016 Feng Lee <feng@emqtt.io>.
+%%
+%% 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(emqttd_base62).
+
+-export([encode/1, decode/1]).
+
+%% @doc Encode an integer to base62 string
+-spec(encode(non_neg_integer()) -> binary()).
+encode(I) when is_integer(I) andalso I > 0 ->
+    list_to_binary(encode(I, [])).
+
+encode(I, Acc) when I < 62 ->
+    [char(I) | Acc];
+encode(I, Acc) ->
+    encode(I div 62, [char(I rem 62) | Acc]).
+
+char(I) when I < 10 ->
+    $0 + I;
+
+char(I) when I < 36 ->
+    $A + I - 10;
+
+char(I) when I < 62 ->
+    $a + I - 36.
+
+%% @doc Decode base62 string to an integer
+-spec(decode(string() | binary()) -> integer()).
+decode(B) when is_binary(B) ->
+    decode(binary_to_list(B));
+decode(S) when is_list(S) ->
+    decode(S, 0).
+
+decode([], I) ->
+    I;
+decode([C|S], I) ->
+    decode(S, I * 62 + byte(C)).
+
+byte(C) when $0 =< C andalso C =< $9 ->
+    C - $0;
+byte(C) when $A =< C andalso C =< $Z ->
+    C - $A + 10;
+byte(C) when $a =< C andalso C =< $z ->
+    C - $a + 36.
+

+ 19 - 2
test/emqttd_lib_SUITE.erl

@@ -28,9 +28,11 @@
 
 -define(PQ, priority_queue).
 
+-define(BASE62, emqttd_base62).
+
 all() -> [{group, guid}, {group, opts},
           {group, ?PQ}, {group, time},
-          {group, node}].
+          {group, node}, {group, base62}].
 
 groups() ->
     [{guid, [], [guid_gen]},
@@ -38,7 +40,8 @@ groups() ->
      {?PQ,  [], [priority_queue_plen,
                  priority_queue_out2]},
      {time, [], [time_now_to_]},
-     {node, [], [node_is_aliving, node_parse_name]}].
+     {node, [], [node_is_aliving, node_parse_name]},
+     {base62, [], [base62_encode]}].
 
 %%--------------------------------------------------------------------
 %% emqttd_guid
@@ -144,3 +147,17 @@ node_parse_name(_) ->
     'a@127.0.0.1' = emqttd_node:parse_name("a@127.0.0.1"),
     'b@127.0.0.1' = emqttd_node:parse_name("b").
 
+%%--------------------------------------------------------------------
+%% base62 encode decode
+%%--------------------------------------------------------------------
+
+base62_encode(_) ->
+    10 = ?BASE62:decode(?BASE62:encode(10)),
+    100 = ?BASE62:decode(?BASE62:encode(100)),
+    9999 = ?BASE62:decode(?BASE62:encode(9999)),
+    65535 = ?BASE62:decode(?BASE62:encode(65535)),
+    <<X:128/unsigned-big-integer>> = emqttd_guid:gen(),
+    <<Y:128/unsigned-big-integer>> = emqttd_guid:gen(),
+    X = ?BASE62:decode(?BASE62:encode(X)),
+    Y = ?BASE62:decode(?BASE62:encode(Y)).
+