Merge pull request #1713 from Gilbert-Wong/emqx30-dev
Enhance base62 encode/decode Funs
This commit is contained in:
commit
86348b5c94
|
@ -1,8 +1,8 @@
|
||||||
language: erlang
|
language: erlang
|
||||||
|
|
||||||
otp_release:
|
otp_release:
|
||||||
- 20.0
|
- 21.0
|
||||||
- 20.1
|
- 21.0.4
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- make
|
- make
|
||||||
|
|
|
@ -14,43 +14,100 @@
|
||||||
|
|
||||||
-module(emqx_base62).
|
-module(emqx_base62).
|
||||||
|
|
||||||
-export([encode/1, decode/1]).
|
-export([encode/1,
|
||||||
|
encode/2,
|
||||||
|
decode/1,
|
||||||
|
decode/2]).
|
||||||
|
|
||||||
%% @doc Encode an integer to base62 string
|
%% @doc Encode any data to base62 binary
|
||||||
-spec(encode(non_neg_integer()) -> binary()).
|
-spec encode(string()
|
||||||
encode(I) when is_integer(I) andalso I > 0 ->
|
| integer()
|
||||||
list_to_binary(encode(I, [])).
|
| binary()) -> float().
|
||||||
|
encode(I) when is_integer(I) ->
|
||||||
|
encode(integer_to_binary(I));
|
||||||
|
encode(S) when is_list(S)->
|
||||||
|
encode(list_to_binary(S));
|
||||||
|
encode(B) when is_binary(B) ->
|
||||||
|
encode(B, <<>>).
|
||||||
|
|
||||||
encode(I, Acc) when I < 62 ->
|
%% encode(D, string) ->
|
||||||
[char(I) | Acc];
|
%% binary_to_list(encode(D)).
|
||||||
encode(I, Acc) ->
|
|
||||||
encode(I div 62, [char(I rem 62) | Acc]).
|
|
||||||
|
|
||||||
char(I) when I < 10 ->
|
%% @doc Decode base62 binary to origin data binary
|
||||||
$0 + I;
|
decode(L) when is_list(L) ->
|
||||||
|
decode(list_to_binary(L));
|
||||||
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(B) when is_binary(B) ->
|
||||||
decode(binary_to_list(B));
|
decode(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 ->
|
%% Internal functions
|
||||||
C - $A + 10;
|
%%====================================================================
|
||||||
byte(C) when $a =< C andalso C =< $z ->
|
|
||||||
C - $a + 36.
|
encode(D, string) ->
|
||||||
|
binary_to_list(encode(D));
|
||||||
|
encode(<<Index1:6, Index2:6, Index3:6, Index4:6, Rest/binary>>, Acc) ->
|
||||||
|
CharList = [encode_char(Index1), encode_char(Index2), encode_char(Index3), encode_char(Index4)],
|
||||||
|
NewAcc = <<Acc/binary,(iolist_to_binary(CharList))/binary>>,
|
||||||
|
encode(Rest, NewAcc);
|
||||||
|
encode(<<Index1:6, Index2:6, Index3:4>>, Acc) ->
|
||||||
|
CharList = [encode_char(Index1), encode_char(Index2), encode_char(Index3)],
|
||||||
|
NewAcc = <<Acc/binary,(iolist_to_binary(CharList))/binary>>,
|
||||||
|
encode(<<>>, NewAcc);
|
||||||
|
encode(<<Index1:6, Index2:2>>, Acc) ->
|
||||||
|
CharList = [encode_char(Index1), encode_char(Index2)],
|
||||||
|
NewAcc = <<Acc/binary,(iolist_to_binary(CharList))/binary>>,
|
||||||
|
encode(<<>>, NewAcc);
|
||||||
|
encode(<<>>, Acc) ->
|
||||||
|
Acc.
|
||||||
|
|
||||||
|
decode(D, integer) ->
|
||||||
|
binary_to_integer(decode(D));
|
||||||
|
decode(D, string) ->
|
||||||
|
binary_to_list(decode(D));
|
||||||
|
decode(<<Head:8, Rest/binary>>, Acc)
|
||||||
|
when bit_size(Rest) >= 8->
|
||||||
|
case Head == $9 of
|
||||||
|
true ->
|
||||||
|
<<Head1:8, Rest1/binary>> = Rest,
|
||||||
|
DecodeChar = decode_char(9, Head1),
|
||||||
|
<<_:2, RestBit:6>> = <<DecodeChar>>,
|
||||||
|
NewAcc = <<Acc/bitstring, RestBit:6>>,
|
||||||
|
decode(Rest1, NewAcc);
|
||||||
|
false ->
|
||||||
|
DecodeChar = decode_char(Head),
|
||||||
|
<<_:2, RestBit:6>> = <<DecodeChar>>,
|
||||||
|
NewAcc = <<Acc/bitstring, RestBit:6>>,
|
||||||
|
decode(Rest, NewAcc)
|
||||||
|
end;
|
||||||
|
decode(<<Head:8, Rest/binary>>, Acc) ->
|
||||||
|
DecodeChar = decode_char(Head),
|
||||||
|
LeftBitSize = bit_size(Acc) rem 8,
|
||||||
|
RightBitSize = 8 - LeftBitSize,
|
||||||
|
<<_:LeftBitSize, RestBit:RightBitSize>> = <<DecodeChar>>,
|
||||||
|
NewAcc = <<Acc/bitstring, RestBit:RightBitSize>>,
|
||||||
|
decode(Rest, NewAcc);
|
||||||
|
decode(<<>>, Acc) ->
|
||||||
|
Acc.
|
||||||
|
|
||||||
|
|
||||||
|
encode_char(I) when I < 26 ->
|
||||||
|
$A + I;
|
||||||
|
encode_char(I) when I < 52 ->
|
||||||
|
$a + I - 26;
|
||||||
|
encode_char(I) when I < 61 ->
|
||||||
|
$0 + I - 52;
|
||||||
|
encode_char(I) ->
|
||||||
|
[$9, $A + I - 61].
|
||||||
|
|
||||||
|
decode_char(I) when I >= $a andalso I =< $z ->
|
||||||
|
I + 26 - $a;
|
||||||
|
decode_char(I) when I >= $0 andalso I =< $8->
|
||||||
|
I + 52 - $0;
|
||||||
|
decode_char(I) when I >= $A andalso I =< $Z->
|
||||||
|
I - $A.
|
||||||
|
|
||||||
|
decode_char(9, I) ->
|
||||||
|
I + 61 - $A.
|
||||||
|
|
||||||
|
|
|
@ -129,5 +129,6 @@ to_base62(<<I:128>>) ->
|
||||||
emqx_base62:encode(I).
|
emqx_base62:encode(I).
|
||||||
|
|
||||||
from_base62(S) ->
|
from_base62(S) ->
|
||||||
I = emqx_base62:decode(S), <<I:128>>.
|
I = emqx_base62:decode(S, integer),
|
||||||
|
<<I:128>>.
|
||||||
|
|
||||||
|
|
|
@ -26,11 +26,14 @@
|
||||||
all() -> [t_base62_encode].
|
all() -> [t_base62_encode].
|
||||||
|
|
||||||
t_base62_encode(_) ->
|
t_base62_encode(_) ->
|
||||||
10 = ?BASE62:decode(?BASE62:encode(10)),
|
<<"10">> = ?BASE62:decode(?BASE62:encode(<<"10">>)),
|
||||||
100 = ?BASE62:decode(?BASE62:encode(100)),
|
<<"100">> = ?BASE62:decode(?BASE62:encode(<<"100">>)),
|
||||||
9999 = ?BASE62:decode(?BASE62:encode(9999)),
|
<<"9999">> = ?BASE62:decode(?BASE62:encode(<<"9999">>)),
|
||||||
65535 = ?BASE62:decode(?BASE62:encode(65535)),
|
<<"65535">> = ?BASE62:decode(?BASE62:encode(<<"65535">>)),
|
||||||
<<X:128/unsigned-big-integer>> = emqx_guid:gen(),
|
<<X:128/unsigned-big-integer>> = emqx_guid:gen(),
|
||||||
<<Y:128/unsigned-big-integer>> = emqx_guid:gen(),
|
<<Y:128/unsigned-big-integer>> = emqx_guid:gen(),
|
||||||
X = ?BASE62:decode(?BASE62:encode(X)),
|
X = ?BASE62:decode(?BASE62:encode(X), integer),
|
||||||
Y = ?BASE62:decode(?BASE62:encode(Y)).
|
Y = ?BASE62:decode(?BASE62:encode(Y), integer),
|
||||||
|
<<"helloworld">> = ?BASE62:decode(?BASE62:encode("helloworld")),
|
||||||
|
"helloworld" = ?BASE62:decode(?BASE62:encode("helloworld", string), string).
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue