sexta-feira, 27 de agosto de 2021

Linguagem C: url Decode ISO-8859-1

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", ":", ";","&lt;", "=","&gt;", "?"},
    { "@", "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';
}


Nenhum comentário: