@@ -658,10 +658,7 @@ defmodule Base do
658
658
@ spec valid64? ( binary , ignore: :whitespace , padding: boolean ) :: boolean
659
659
def valid64? ( string , opts \\ [ ] ) when is_binary ( string ) do
660
660
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? )
665
662
end
666
663
667
664
@ doc """
@@ -755,110 +752,124 @@ defmodule Base do
755
752
@ spec url_valid64? ( binary , ignore: :whitespace , padding: boolean ) :: boolean
756
753
def url_valid64? ( string , opts \\ [ ] ) when is_binary ( string ) do
757
754
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? )
762
756
end
763
757
764
758
for { base , alphabet } <- [ base: b64_alphabet , url: b64url_alphabet ] do
765
759
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 } ?"
767
764
{ min , decoded } = alphabet |> Enum . with_index ( ) |> to_decode_list . ( )
768
765
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 )
771
780
end
772
781
782
+ defp unquote ( validate_name ) ( << >> , _pad? ) , do: true
783
+
773
784
defp unquote ( validate_name ) ( string , pad? ) do
774
785
segs = div ( byte_size ( string ) + 7 , 8 ) - 1
775
786
<< 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 )
787
788
788
789
case rest do
790
+ _ when not main_valid? ->
791
+ false
792
+
789
793
<< 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 )
792
796
793
797
<< 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 )
797
801
798
802
<< 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 )
803
807
804
808
<< 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 )
811
815
812
816
<< 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 )
820
824
821
825
<< 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 )
830
834
831
835
<< 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 )
834
838
835
839
<< 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 )
839
843
840
844
<< 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 )
847
851
848
852
<< 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 )
856
860
857
861
_ ->
858
- raise ArgumentError , "incorrect padding"
862
+ false
859
863
end
860
864
end
861
865
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
+
862
873
defp unquote ( decode_name ) ( char ) do
863
874
index = char - unquote ( min )
864
875
0 commit comments