#c #urlencode #libcurl
#c #urlencode #libcurl
Вопрос:
Есть ли простой способ выполнить кодирование URL на C? Я использую libcurl, но я не нашел метода. В частности, мне нужно выполнить процентное экранирование.
Ответ №1:
На C на основе википедии, без необходимости выделять и освобождать. Убедитесь, что выходной буфер равен по крайней мере 3-кратной строке входного URL. Обычно вам нужно кодировать только до, возможно, 4K, поскольку URL-адреса, как правило, короткие, поэтому просто делайте это в стеке.
char rfc3986[256] = {0};
char html5[256] = {0};
void url_encoder_rfc_tables_init(){
int i;
for (i = 0; i < 256; i ){
rfc3986[i] = isalnum( i) || i == '~' || i == '-' || i == '.' || i == '_' ? i : 0;
html5[i] = isalnum( i) || i == '*' || i == '-' || i == '.' || i == '_' ? i : (i == ' ') ? ' ' : 0;
}
}
char *url_encode( char *table, unsigned char *s, char *enc){
for (; *s; s ){
if (table[*s]) *enc = table[*s];
else sprintf( enc, "%%X", *s);
while (* enc);
}
return( enc);
}
Используйте это следующим образом
url_encoder_rfc_tables_init();
url_encode( html5, url, url_encoded);
Комментарии:
1. Эту строку «sprintf( enc, «%c», таблица[*s])» можно упростить до «*enc = *s» — вы избегаете вызова дорогостоящей функции форматирования.
2. Вы имеете в виду *enc = table[*s]?
3. Теперь это решение предполагает, что буферу «enc» присваивается значение 0 перед вызовом.
Ответ №2:
Комментарии:
1. Обратите внимание! вышеуказанные функции не выдают результатов, совместимых с (например) Функция PHP urlencode
Ответ №3:
Я написал это, чтобы также позаботиться о кодировке строки запроса символом пробела
Использование: UrlEncode(«http://www.example.com/index.html ?Привет=Мир«, » :/», буфер, buf_size)
url: строка URL для кодирования. Может быть строковым литералом или строковым массивом
кодировать: строка символов, заканчивающаяся нулем, для кодирования. Это хорошо, потому что вы можете во время выполнения определить, какую часть URL кодировать
буфер: буфер для хранения новой строки
размер: размер буфера
return: возвращает размер новой строки, если буфер достаточно велик, ИЛИ возвращает требуемый размер буфера, если буфер недостаточно велик. Вы можете дважды нажать на эту функцию, если хотите выделить точный необходимый размер.
int UrlEncode(char* url, char* encode, char* buffer, unsigned int size)
{
char chars[127] = {0};
unsigned int length = 0;
if(!url || !encode || !buffer) return 0;
//Create an array to hold ascii chars, loop through encode string
//and assign to place in array. I used this construct instead of a large if statement for speed.
while(*encode) chars[*encode ] = *encode;
//Loop through url, if we find an encode char, replace with % and add hex
//as ascii chars. Move buffer up by 2 and track the length needed.
//If we reach the query string (?), move to query string encoding
URLENCODE_BASE_URL:
while(size amp;amp; (*buffer = *url)) {
if(*url == '?') goto URLENCODE_QUERY_STRING;
if(chars[*url] amp;amp; size > 2) {
*buffer = '%';
itoa(*url, buffer, 16);
buffer ; size-=2; length =2;
}
url , buffer , size--; length ;
}
goto URLENCODE_RETURN;
//Same as above but on spaces (' '), replace with plus (' ') and convert
//to hex ascii. I moved this out into a separate loop for speed.
URLENCODE_QUERY_STRING:
while(size amp;amp; (*buffer = *url)) {
if(chars[*url] amp;amp; size > 2) {
*buffer = '%';
if(*url == ' ') itoa(' ', buffer, 16);
else itoa(*url, buffer, 16);
buffer ; size-=2; length =2;
}
url , buffer , size--; length ;
}
//Terminate the end of the buffer, and if the buffer wasn't large enough
//calc the rest of the url length and return
URLENCODE_RETURN:
*buffer = '';
if(*url)
while(*url) { if(chars[*url]) length =2; url ; length ; }
return length;
}
Эта функция в значительной степени обрабатывает большинство (если не все) кодировок URL, которые вам понадобятся. Лучше всего — это действительно быстро!