Para quem programa em linguagem C e precisou de um urlDecode para ISO-8859-1 irá achar esse fonte útil:
char *matriz[16][16] = {
{"^@","^A","^B","^C","^D","^E","^F","^G","^H","^I","<br>","^K", "^L","^M", "^N","^O"},
{"^P","^Q","^R","^S","^T","^U","^V","^W","^X","^Y","^Z","^[", "^\\","^]", "^^","^_"},
{ " ", "!","\"", "#", "$", "%", "&","\'", "(", ")", "*", "+", ",", "-", ".", "/"},
{ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";","<", "=",">", "?"},
{ "@", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O"},
{ "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[", "\\", "]", "^", "_"},
{ "`", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o"},
{ "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "{", "|", "}", "~","^?"},
{ " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "},
{ " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "},
{ " ", "¡", "¢", "£", "¤", "¥", "¦", "§", "¨", "©", "ª", "«", "¬", " ", "®", "¯"},
{ "°", "±", "²", "³", "´", "µ", "¶", "·", "¸", "¹", "º", "»", "¼", "½", "¾", "¿"},
{ "À", "Á", "Â", "Ã", "Ä", "Å", "Æ", "Ç", "È", "É", "Ê", "Ë", "Ì", "Í", "Î", "Ï"},
{ "Ð", "Ñ", "Ò", "Ó", "Ô", "Õ", "Ö", "×", "Ø", "Ù", "Ú", "Û", "Ü", "Ý", "Þ", "ß"},
{ "à", "á", "â", "ã", "ä", "å", "æ", "ç", "è", "é", "ê", "ë", "í", "ì", "î", "ï"},
{ "ð", "ñ", "ò", "ó", "ô", "õ", "ö", "÷", "ø", "ù", "ú", "û", "ü", "ý", "þ", "ÿ"}
};
int hex(char x)
{
if(x=='0'){ return 0;}
if(x=='1'){ return 1;}
if(x=='2'){ return 2;}
if(x=='3'){ return 3;}
if(x=='4'){ return 4;}
if(x=='5'){ return 5;}
if(x=='6'){ return 6;}
if(x=='7'){ return 7;}
if(x=='8'){ return 8;}
if(x=='9'){ return 9;}
if(x=='A'||x=='a'){ return 10;}
if(x=='B'||x=='b'){ return 11;}
if(x=='C'||x=='c'){ return 12;}
if(x=='D'||x=='d'){ return 13;}
if(x=='E'||x=='e'){ return 14;}
if(x=='F'||x=='f'){ return 15;}
return -1;
}
char hexch(int x)
{
if(x== 0){ return '0';}
if(x== 1){ return '1';}
if(x== 2){ return '2';}
if(x== 3){ return '3';}
if(x== 4){ return '4';}
if(x== 5){ return '5';}
if(x== 6){ return '6';}
if(x== 7){ return '7';}
if(x== 8){ return '8';}
if(x== 9){ return '9';}
if(x==10){ return 'A';}
if(x==11){ return 'B';}
if(x==12){ return 'C';}
if(x==13){ return 'D';}
if(x==14){ return 'E';}
if(x==15){ return 'F';}
return '\0';
}
char *dec(int a, int b)
{
return matriz[a][b];
}
int urlDecode(char *out, char *s )
{
int a, b;
int tm = strlen(s);
int remove=0;
char c, decoded[8];
strcpy(out, ""); //limpa tudo que tiver em out
for(int i=0; i<tm; i++)
{
c = *s++;
if (c=='%')
{
a = hex(*s++) ;// primeiro hexadecimal
b = hex(*s++) ;// segundo hexadecimal
strcpy(decoded, "");
strcat(decoded, dec(a,b));
strcat(out, decoded);
//nem todos são formados por um
//unico caractere. Remove ecesso no final
remove+=strlen(decoded);
}
else if (c == '+')
{
strcat(out, " ");
}
else
{
char m[2]={c,'\0'};
strcat(out, m);
}
}
out[strlen(out)-remove]='\0';
return strlen(out);
}
void matrixDecode()
{
printf( "\nMatriz de decodificação:\n");
for(int i=0; i<16; i++)
{
for(int j=0; j<16; j++)
{
printf("%c%c=%s\t", hexch(i),hexch(j),dec(i,j));
}
printf("\n");
for(int j=0; j<16; j++)
{
printf("%i=%s\t", i*16+j,dec(i,j));
}
printf("\n");
printf("\n");
}
}
void testaDecode()
{
printf( "\nTestando decode:\n");
char *url = "username=%C1gatha+Silva&email=agata%40dasilva.com";
printf( "url = %s\n", url );
int tm = strlen(url);
printf( "tamanho url = %i\n\n", tm);
char resp[tm];
tm = urlDecode(resp, url) ;
printf( "decodificado = %s\n", resp);
printf( "tamanho do decod = %i\n", tm);
}
int main()
{
matrixDecode();
testaDecode();
return 0;
}
Resultado:
Testando decode:
url = username=%C1gatha+Silva&email=agata%40dasilva.com
tamanho url = 49
decodificado = username=Ágatha Silva&email=agata@dasilva.com
tamanho do decod = 46
Melhorias:
// Melhoria sugerida pelo usuário Flávio Pedroza em
// https://www.clubedohardware.com.br/topic/1560019-existe-c-injection-assim-como-existe-sql-injection/
int hex(char x)
{
if ((x>='0') && (x<='9')) { return x-48;}
if ((x>='A') && (x<='F')) { return x-55;}
if ((x>='a') && (x<='f')) { return x-87;}
return -1;
}
char hexch(int x)
{
if ((x>= 0) && (x <= 9)){ return x+48;}
if ((x>=10) && (x<=15)) { return x+55;}
return '\0';
}