Boa noite.
Essa solução em
perl seria caso de crucificação, nos idos tempos da lista do Yahoo :-p
Na intenção de amarrar o assunto ao tema literal da lista, deixo duas sugestões de urlencoding em
shell propriamente dito.
Vamos assumir essa senha:
$ string='A$B#C@D/E F'Primeiro, uma sugestão que codifica apenas os caracteres que podem deixar a url confusa. Por ex,
'$#@/ '.
urlencode2()
{
local tohex='$#@/ '
eval echo $(sed -r "s:[$tohex]:\$(od -N1 -tx1 <<< '&' | grep -o ' ..' | tr ' ' %):g" <<< "${1:-$string}")
}
$ urlencode2
A%24B%23C%40D%2fE%20F
Vamos comparar a velocidade dessa solução com a em
perl.
urlencode1()
{
echo -ne "${1:-$string}" | perl -pe 's/\W/"%".unpack "H*",$&/gei'
echo
}
$ urlencode1
A%24B%23C%40D%2fE%20F"
benshmark" é uma funçãozinha que executa n vezes cada função passada por nome via parâmetro e mede o tempo total da execução repetida para cada uma delas.
benshmark()
{
local s L=$1; shift
for s
{
echo -n "$s "
time for ((i=0;i<L;i++)); { $s; } &> /dev/null
}
}
$ benshmark 2000 urlencode{1..2}
urlencode1 0m3,724s
urlencode2 0m20,830sA solução em shell ficou mais lenta. Inaceitável! Tem que melhorar isso daí :)
A primeira coisa a levar em consideração é que, se é pra codificar em hexadecimal para não deixar a url confusa para os aplicativos, tanto faz codificar apenas os caracteres que confundem quanto codificar tudo. O cuidado em codificar apenas os caracteres especiais complica desnecessariamente o procedimento. Então vamos codificar tudo e ver o que acontece :)
urlencode3()
{
: "$(od -tx1 <<< "${1:-$string}" | grep -oE '( ..)+')"
: "${_// /%}"
echo "${_%\%*}"
}
$ urlencode3
%41%24%42%23%43%40%44%2f%45%20%46A segunda coisa é confirmar que a senha 100% urlencoded realmente é compreendida.
Teste em um projeto privado no GitLab:
$ user=arkanon
$ git clone https://gitlab.com/$user/teste.git
Cloning into 'teste'...
Username for 'https://gitlab.com': ^CUsei como senha a string
'A$B#C@D/E F' sem os apóstrofos. Como até espaço há na senha, se ela não estiver codificada, a url no "git clone" deverá, no mínimo, estar entre aspas:
Vamos testar com a senha codificada apenas nos caracteres especiais:
$ hpass1=$(urlencode2 "$pass")
$ echo $hpass1
A%24B%23C%40D%2fE%20F
$ git clone https://$user:$hpass1@gitlab.com/$user/teste.git teste-hpass1
Cloning into 'teste-hpass1'...
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 197 bytes | 98.00 KiB/s, done.
repo 'user.name' has been set to 'Arkanon'
repo 'user.email' has been set to 'arkanon@lsd.org.br'Funcionou, como esperado. Agora vamos testar com a senha completamente codificada:
$ hpass2=$(urlencode3 "$pass")
$ echo $hpass2
%41%24%42%23%43%40%44%2f%45%20%46
$ git clone https://$user:$hpass2@gitlab.com/$user/teste.git teste-hpass2
Cloning into 'teste-hpass2'...
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 197 bytes | 98.00 KiB/s, done.
repo 'user.name' has been set to 'Arkanon'
repo 'user.email' has been set to 'arkanon@lsd.org.br'Beleza, também funcionou!
E, finalmente, vamos comparar novamente, dessa vez as 3 soluções.
Três comparações na sequência:
$ benshmark 2000 urlencode{1..3}
urlencode1 0m6,681s
urlencode2 0m21,149s
urlencode3 0m3,943s
$ benshmark 2000 urlencode{1..3}
urlencode1 0m4,282s
urlencode2 0m23,017s
urlencode3 0m3,893s
$ benshmark 2000 urlencode{1..3}
urlencode1 0m4,435s
urlencode2 0m24,310s
urlencode3 0m3,990sBem melhor, hein? :)
Abrashos.