%%-------------------------------------------------------------------- %% Copyright (c) 2017-2021 EMQ Technologies Co., Ltd. All Rights Reserved. %% %% 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(emqx_base62). %% APIs -export([ encode/1 , decode/1 ]). %%-------------------------------------------------------------------- %% APIs %%-------------------------------------------------------------------- %% @doc Encode any data to base62 binary -spec encode(string() | integer() | binary()) -> binary(). encode(I) when is_integer(I) -> encode(integer_to_binary(I)); encode(S) when is_list(S)-> encode(unicode:characters_to_binary(S)); encode(B) when is_binary(B) -> encode(B, <<>>). %% encode(D, string) -> %% binary_to_list(encode(D)). %% @doc Decode base62 binary to origin data binary decode(B) when is_binary(B) -> decode(B, <<>>). %%-------------------------------------------------------------------- %% Interval Functions %%-------------------------------------------------------------------- encode(<>, Acc) -> CharList = [encode_char(Index1), encode_char(Index2), encode_char(Index3), encode_char(Index4)], NewAcc = <>, encode(Rest, NewAcc); encode(<>, Acc) -> CharList = [encode_char(Index1), encode_char(Index2), encode_char(Index3)], NewAcc = <>, encode(<<>>, NewAcc); encode(<>, Acc) -> CharList = [encode_char(Index1), encode_char(Index2)], NewAcc = <>, encode(<<>>, NewAcc); encode(<<>>, Acc) -> Acc. decode(<>, Acc) when bit_size(Rest) >= 8-> case Head == $9 of true -> <> = Rest, DecodeChar = decode_char(9, Head1), <<_:2, RestBit:6>> = <>, NewAcc = <>, decode(Rest1, NewAcc); false -> DecodeChar = decode_char(Head), <<_:2, RestBit:6>> = <>, NewAcc = <>, decode(Rest, NewAcc) end; decode(<>, Acc) -> DecodeChar = decode_char(Head), LeftBitSize = bit_size(Acc) rem 8, RightBitSize = 8 - LeftBitSize, <<_:LeftBitSize, RestBit:RightBitSize>> = <>, NewAcc = <>, 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.