prop_base62.erl 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. -module(prop_base62).
  2. -include_lib("proper/include/proper.hrl").
  3. %%%%%%%%%%%%%%%%%%
  4. %%% Properties %%%
  5. %%%%%%%%%%%%%%%%%%
  6. prop_symmetric() ->
  7. ?FORALL(Data, raw_data(),
  8. begin
  9. Encoded = emqx_base62:encode(Data),
  10. to_binary(Data) =:= emqx_base62:decode(Encoded)
  11. end).
  12. prop_size() ->
  13. ?FORALL(Data, binary(),
  14. begin
  15. Encoded = emqx_base62:encode(Data),
  16. base62_size(Data, Encoded)
  17. end).
  18. %%%%%%%%%%%%%%%
  19. %%% Helpers %%%
  20. %%%%%%%%%%%%%%%
  21. to_binary(Data) when is_list(Data) ->
  22. unicode:characters_to_binary(Data);
  23. to_binary(Data) when is_integer(Data) ->
  24. integer_to_binary(Data);
  25. to_binary(Data) when is_binary(Data) ->
  26. Data.
  27. base62_size(Data, Encoded) ->
  28. DataSize = erlang:size(Data),
  29. EncodedSize = erlang:size(Encoded),
  30. case (DataSize * 8 rem 6) of
  31. 0 ->
  32. %% Due to the particularity of base 62, 3 bytes data maybe encoded
  33. %% as 4 bytes data or 5 bytes data, the encode size maybe in the
  34. %% range between DataSize*4/3 and DataSize*8/3
  35. RangeStart = DataSize div 3 * 4,
  36. RangeEnd = DataSize div 3 * 8,
  37. EncodedSize >= RangeStart andalso EncodedSize =< RangeEnd;
  38. _Rem ->
  39. RangeStart = DataSize * 8 div 6 + 1,
  40. RangeEnd = DataSize * 8 div 6 * 2 + 1,
  41. EncodedSize >= RangeStart andalso EncodedSize =< RangeEnd
  42. end.
  43. %%%%%%%%%%%%%%%%%%
  44. %%% Generators %%%
  45. %%%%%%%%%%%%%%%%%%
  46. raw_data() -> oneof([integer(), string(), binary()]).