While testing a module I found a bug in the way it encodes a URL. So I hit the web to find out why.
The subroutines it uses for encoding and decoding where very old and had many more bugs then the one I found, so I installed URL::Encode and because the module complained I then installed URL::Encode::XS also.
I used URL::Encode to test the two output and fix the broken code, because most of the time using a cpan module just slows the main project down a lot when the included modules are providing a very small chunk of code.
So my fix for the broken URL encode and decode is below and outputs the same as URL::Encode.
It looks like it would be a lot faster then including a module (URL::Encode) to do the same actions.
sub url_encode {
my $rv = shift;
$rv =~ s/([^a-z\d\Q.-_~ \E])/sprintf("%%%2.2X", ord($1))/geix;
$rv =~ tr/ /+/;
return $rv;
}
sub url_decode {
my $rv = shift;
$rv =~ tr/+/ /;
$rv =~ s/\%([a-f\d]{2})/ pack 'C', hex $1 /geix;
return $rv;
}
But with URL::Encode::XS module installed the code above is very, very slow.
This bench script can show the speed difference.
#!/usr/bin/perl
####################
# LOAD CORE MODULES
####################
use strict;
use warnings FATAL => 'all';
# Autoflush ON
local $| = 1;
use URL::Encode;
use Benchmark qw(cmpthese);
my $thing = '%© © <> []"\'=?.-_^&*(){}@#!|,;:`~$/\\ 1 + 2 = 3 1
+s sd sds';
my $thing22 = '%25%26copy%3B+%A9+%3C%3E+%5B%5D%22%27%3D%3F.-_%5E%26%2A
+%28%29%7B%7D%40%23%21%7C%2C%3B%3A%60~%24%2F%5C+1+%2B+2+%3D+3+++1s+sd+
+sds';
my $num_of_iters = '1000000';
####################
# RUN BENCH
####################
print "\n\nBenchmarking $num_of_iters iterations on Perl $] ($^O)\n\n"
+;
cmpthese(
$num_of_iters, {
'MY::Decoder' => sub {
url_decode( $thing22 );
},
'URL::Decode' => sub {
URL::Encode::url_decode( $thing22 );
},
'MY::Encoder' => sub {
url_encode( $thing );
},
'URL::Encode' => sub {
URL::Encode::url_encode($thing);
},
}
);
print "\n";
my $thing2 = URL::Encode::url_encode($thing);
print $thing2."\n";
$thing2 = URL::Encode::url_decode($thing2);
print $thing2."\n";
print "\n\n";
my $thing3 = url_encode($thing);
print $thing3."\n";
$thing3 = url_decode($thing3);
print $thing3."\n";
sub url_encode {
my $rv = shift;
$rv =~ s/([^a-z\d\Q.-_~ \E])/sprintf("%%%2.2X", ord($1))/geix;
$rv =~ tr/ /+/;
return $rv;
}
sub url_decode {
my $rv = shift;
$rv =~ tr/+/ /;
$rv =~ s/\%([a-f\d]{2})/ pack 'C', hex $1 /geix;
return $rv;
}