@@ -658,10 +658,7 @@ defmodule Base do
658658 @ spec valid64? ( binary , ignore: :whitespace , padding: boolean ) :: boolean
659659 def valid64? ( string , opts \\ [ ] ) when is_binary ( string ) do
660660 pad? = Keyword . get ( opts , :padding , true )
661- string |> remove_ignored ( opts [ :ignore ] ) |> validate64base! ( pad? )
662- true
663- rescue
664- ArgumentError -> false
661+ string |> remove_ignored ( opts [ :ignore ] ) |> validate64base? ( pad? )
665662 end
666663
667664 @ doc """
@@ -755,110 +752,124 @@ defmodule Base do
755752 @ spec url_valid64? ( binary , ignore: :whitespace , padding: boolean ) :: boolean
756753 def url_valid64? ( string , opts \\ [ ] ) when is_binary ( string ) do
757754 pad? = Keyword . get ( opts , :padding , true )
758- string |> remove_ignored ( opts [ :ignore ] ) |> validate64url! ( pad? )
759- true
760- rescue
761- ArgumentError -> false
755+ string |> remove_ignored ( opts [ :ignore ] ) |> validate64url? ( pad? )
762756 end
763757
764758 for { base , alphabet } <- [ base: b64_alphabet , url: b64url_alphabet ] do
765759 decode_name = :"decode64#{ base } !"
766- validate_name = :"validate64#{ base } !"
760+
761+ validate_name = :"validate64#{ base } ?"
762+ validate_main_name = :"validate_main64#{ validate_name } ?"
763+ valid_char_name = :"valid_char64#{ base } ?"
767764 { min , decoded } = alphabet |> Enum . with_index ( ) |> to_decode_list . ( )
768765
769- defp unquote ( validate_name ) ( << >> , _pad? ) do
770- true
766+ defp unquote ( validate_main_name ) ( << >> ) , do: true
767+
768+ defp unquote ( validate_main_name ) (
769+ << c1 :: 8 , c2 :: 8 , c3 :: 8 , c4 :: 8 , c5 :: 8 , c6 :: 8 , c7 :: 8 , c8 :: 8 , rest :: binary >>
770+ ) do
771+ unquote ( valid_char_name ) ( c1 ) and
772+ unquote ( valid_char_name ) ( c2 ) and
773+ unquote ( valid_char_name ) ( c3 ) and
774+ unquote ( valid_char_name ) ( c4 ) and
775+ unquote ( valid_char_name ) ( c5 ) and
776+ unquote ( valid_char_name ) ( c6 ) and
777+ unquote ( valid_char_name ) ( c7 ) and
778+ unquote ( valid_char_name ) ( c8 ) and
779+ unquote ( validate_main_name ) ( rest )
771780 end
772781
782+ defp unquote ( validate_name ) ( << >> , _pad? ) , do: true
783+
773784 defp unquote ( validate_name ) ( string , pad? ) do
774785 segs = div ( byte_size ( string ) + 7 , 8 ) - 1
775786 << main :: size ( ^ segs ) - binary - unit ( 64 ) , rest :: binary >> = string
776-
777- for << c1 :: 8 , c2 :: 8 , c3 :: 8 , c4 :: 8 , c5 :: 8 , c6 :: 8 , c7 :: 8 , c8 :: 8 <- main >> do
778- unquote ( decode_name ) ( c1 )
779- unquote ( decode_name ) ( c2 )
780- unquote ( decode_name ) ( c3 )
781- unquote ( decode_name ) ( c4 )
782- unquote ( decode_name ) ( c5 )
783- unquote ( decode_name ) ( c6 )
784- unquote ( decode_name ) ( c7 )
785- unquote ( decode_name ) ( c8 )
786- end
787+ main_valid? = unquote ( validate_main_name ) ( main )
787788
788789 case rest do
790+ _ when not main_valid? ->
791+ false
792+
789793 << c1 :: 8 , c2 :: 8 , ?= , ?= >> ->
790- unquote ( decode_name ) ( c1 )
791- unquote ( decode_name ) ( c2 )
794+ unquote ( valid_char_name ) ( c1 ) and
795+ unquote ( valid_char_name ) ( c2 )
792796
793797 << c1 :: 8 , c2 :: 8 , c3 :: 8 , ?= >> ->
794- unquote ( decode_name ) ( c1 )
795- unquote ( decode_name ) ( c2 )
796- unquote ( decode_name ) ( c3 )
798+ unquote ( valid_char_name ) ( c1 ) and
799+ unquote ( valid_char_name ) ( c2 ) and
800+ unquote ( valid_char_name ) ( c3 )
797801
798802 << c1 :: 8 , c2 :: 8 , c3 :: 8 , c4 :: 8 >> ->
799- unquote ( decode_name ) ( c1 )
800- unquote ( decode_name ) ( c2 )
801- unquote ( decode_name ) ( c3 )
802- unquote ( decode_name ) ( c4 )
803+ unquote ( valid_char_name ) ( c1 ) and
804+ unquote ( valid_char_name ) ( c2 ) and
805+ unquote ( valid_char_name ) ( c3 ) and
806+ unquote ( valid_char_name ) ( c4 )
803807
804808 << c1 :: 8 , c2 :: 8 , c3 :: 8 , c4 :: 8 , c5 :: 8 , c6 :: 8 , ?= , ?= >> ->
805- unquote ( decode_name ) ( c1 )
806- unquote ( decode_name ) ( c2 )
807- unquote ( decode_name ) ( c3 )
808- unquote ( decode_name ) ( c4 )
809- unquote ( decode_name ) ( c5 )
810- unquote ( decode_name ) ( c6 )
809+ unquote ( valid_char_name ) ( c1 ) and
810+ unquote ( valid_char_name ) ( c2 ) and
811+ unquote ( valid_char_name ) ( c3 ) and
812+ unquote ( valid_char_name ) ( c4 ) and
813+ unquote ( valid_char_name ) ( c5 ) and
814+ unquote ( valid_char_name ) ( c6 )
811815
812816 << c1 :: 8 , c2 :: 8 , c3 :: 8 , c4 :: 8 , c5 :: 8 , c6 :: 8 , c7 :: 8 , ?= >> ->
813- unquote ( decode_name ) ( c1 )
814- unquote ( decode_name ) ( c2 )
815- unquote ( decode_name ) ( c3 )
816- unquote ( decode_name ) ( c4 )
817- unquote ( decode_name ) ( c5 )
818- unquote ( decode_name ) ( c6 )
819- unquote ( decode_name ) ( c7 )
817+ unquote ( valid_char_name ) ( c1 ) and
818+ unquote ( valid_char_name ) ( c2 ) and
819+ unquote ( valid_char_name ) ( c3 ) and
820+ unquote ( valid_char_name ) ( c4 ) and
821+ unquote ( valid_char_name ) ( c5 ) and
822+ unquote ( valid_char_name ) ( c6 ) and
823+ unquote ( valid_char_name ) ( c7 )
820824
821825 << c1 :: 8 , c2 :: 8 , c3 :: 8 , c4 :: 8 , c5 :: 8 , c6 :: 8 , c7 :: 8 , c8 :: 8 >> ->
822- unquote ( decode_name ) ( c1 )
823- unquote ( decode_name ) ( c2 )
824- unquote ( decode_name ) ( c3 )
825- unquote ( decode_name ) ( c4 )
826- unquote ( decode_name ) ( c5 )
827- unquote ( decode_name ) ( c6 )
828- unquote ( decode_name ) ( c7 )
829- unquote ( decode_name ) ( c8 )
826+ unquote ( valid_char_name ) ( c1 ) and
827+ unquote ( valid_char_name ) ( c2 ) and
828+ unquote ( valid_char_name ) ( c3 ) and
829+ unquote ( valid_char_name ) ( c4 ) and
830+ unquote ( valid_char_name ) ( c5 ) and
831+ unquote ( valid_char_name ) ( c6 ) and
832+ unquote ( valid_char_name ) ( c7 ) and
833+ unquote ( valid_char_name ) ( c8 )
830834
831835 << c1 :: 8 , c2 :: 8 >> when not pad? ->
832- unquote ( decode_name ) ( c1 )
833- unquote ( decode_name ) ( c2 )
836+ unquote ( valid_char_name ) ( c1 ) and
837+ unquote ( valid_char_name ) ( c2 )
834838
835839 << c1 :: 8 , c2 :: 8 , c3 :: 8 >> when not pad? ->
836- unquote ( decode_name ) ( c1 )
837- unquote ( decode_name ) ( c2 )
838- unquote ( decode_name ) ( c3 )
840+ unquote ( valid_char_name ) ( c1 ) and
841+ unquote ( valid_char_name ) ( c2 ) and
842+ unquote ( valid_char_name ) ( c3 )
839843
840844 << c1 :: 8 , c2 :: 8 , c3 :: 8 , c4 :: 8 , c5 :: 8 , c6 :: 8 >> when not pad? ->
841- unquote ( decode_name ) ( c1 )
842- unquote ( decode_name ) ( c2 )
843- unquote ( decode_name ) ( c3 )
844- unquote ( decode_name ) ( c4 )
845- unquote ( decode_name ) ( c5 )
846- unquote ( decode_name ) ( c6 )
845+ unquote ( valid_char_name ) ( c1 ) and
846+ unquote ( valid_char_name ) ( c2 ) and
847+ unquote ( valid_char_name ) ( c3 ) and
848+ unquote ( valid_char_name ) ( c4 ) and
849+ unquote ( valid_char_name ) ( c5 ) and
850+ unquote ( valid_char_name ) ( c6 )
847851
848852 << c1 :: 8 , c2 :: 8 , c3 :: 8 , c4 :: 8 , c5 :: 8 , c6 :: 8 , c7 :: 8 >> when not pad? ->
849- unquote ( decode_name ) ( c1 )
850- unquote ( decode_name ) ( c2 )
851- unquote ( decode_name ) ( c3 )
852- unquote ( decode_name ) ( c4 )
853- unquote ( decode_name ) ( c5 )
854- unquote ( decode_name ) ( c6 )
855- unquote ( decode_name ) ( c7 )
853+ unquote ( valid_char_name ) ( c1 ) and
854+ unquote ( valid_char_name ) ( c2 ) and
855+ unquote ( valid_char_name ) ( c3 ) and
856+ unquote ( valid_char_name ) ( c4 ) and
857+ unquote ( valid_char_name ) ( c5 ) and
858+ unquote ( valid_char_name ) ( c6 ) and
859+ unquote ( valid_char_name ) ( c7 )
856860
857861 _ ->
858- raise ArgumentError , "incorrect padding"
862+ false
859863 end
860864 end
861865
866+ @ compile { :inline , [ { valid_char_name , 1 } ] }
867+ defp unquote ( valid_char_name ) ( char )
868+ when elem ( { unquote_splicing ( decoded ) } , char - unquote ( min ) ) != nil ,
869+ do: true
870+
871+ defp unquote ( valid_char_name ) ( _char ) , do: false
872+
862873 defp unquote ( decode_name ) ( char ) do
863874 index = char - unquote ( min )
864875
0 commit comments