u_char LOW_BYTE_MASK = 15;
char* HEXS = (char*)"0123456789ABCDEF";
char* URL_ALLOW = (char*)"abcdefghijklmnopqrstuvwxyz/:#?&=0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ+-,._*~@!$^()[]{}';|";
#define BudaHex2Dec(c) (c<='9'? (c-'0'):(c<='Z'? (c-55):(c-87)))
#define BudaPreWrite(max_len, dec, fail) if((max_len-=dec)<0) goto fail;
#define BudaPreWrite1(max_len, fail) if((--max_len)<0) goto fail;
int url_encode(u_char *s, u_char *d, int max_len)
{
u_char c, c_high, c_low, *ps = s, *pd=d;
while(c=*(ps++))
{
if(strchr(URL_ALLOW, c)) { BudaPreWrite1(max_len, fail); *(pd++) = c; }
else { BudaPreWrite(max_len, 3, fail); *(pd++) = '%'; *(pd++) = HEXS[c >> 4]; *(pd++) = HEXS[c & BYTE_LOW4_MASK]; }
}
*pd=0;
succeed: return 0;
fail: log("url_encode failed"); return -1;
}
int url_decode(u_char *s, u_char *d, int max_len)
{
u_char c, *ps=s, *pd=d, c_high, c_low;
while(c=*(ps++))
{
BudaPreWrite1(max_len, fail);
if (c != '%') *(pd++) = c;
else
{
c = *(ps++); c_high=BudaHex2Dec(c); c = *(ps++); c_low=BudaHex2Dec(c);
c = *(pd++) = ((c_high<<4) | c_low); //printf("decoded ");
}
}
*pd=0;
succeed: return 0;
fail: log("url_decode failed"); return -1;
}
参考资料
RFC 3986 - Uniform Resource Identifier (URI): Generic Syntax
gemini