Sto sviluppando un programma c/C++ su linux. Puoi dirmi se esiste una libreria c/C++ che decodifica l'url?Libreria di decodifica URL C/C++
Cerco librerie che convertono "http% 3A% 2F% 2F" a: "http: //"
o "a + t +% 26 + t" a "a & t "
Grazie.
Sto sviluppando un programma c/C++ su linux. Puoi dirmi se esiste una libreria c/C++ che decodifica l'url?Libreria di decodifica URL C/C++
Cerco librerie che convertono "http% 3A% 2F% 2F" a: "http: //"
o "a + t +% 26 + t" a "a & t "
Grazie.
Il sempre eccellente glib ha un numero di URI functions, inclusi estrazione di schemi, escaping e non-escape.
A meno che l'OP non utilizzi glib per cominciare (presumo che non lo sia se sta usando C++), glib è eccessivo se l'unico scopo è usare il suo URI funzioni. Non è una piccola biblioteca. – Void
uriparser la libreria è piccola e leggera.
Questa funzione che ho appena montato è molto leggera e dovrebbe fare ciò che desideri, nota che non ho programmato questo a rigorosi standard URI (usato quello che so in cima alla mia testa). È sicuro per i buffer e non trabocca per quanto posso vedere; adattarsi nel modo che ritiene in forma:
#include <assert.h>
void urldecode(char *pszDecodedOut, size_t nBufferSize, const char *pszEncodedIn)
{
memset(pszDecodedOut, 0, nBufferSize);
enum DecodeState_e
{
STATE_SEARCH = 0, ///< searching for an ampersand to convert
STATE_CONVERTING, ///< convert the two proceeding characters from hex
};
DecodeState_e state = STATE_SEARCH;
for(unsigned int i = 0; i < strlen(pszEncodedIn)-1; ++i)
{
switch(state)
{
case STATE_SEARCH:
{
if(pszEncodedIn[i] != '%')
{
strncat(pszDecodedOut, &pszEncodedIn[i], 1);
assert(strlen(pszDecodedOut) < nBufferSize);
break;
}
// We are now converting
state = STATE_CONVERTING;
}
break;
case STATE_CONVERTING:
{
// Conversion complete (i.e. don't convert again next iter)
state = STATE_SEARCH;
// Create a buffer to hold the hex. For example, if %20, this
// buffer would hold 20 (in ASCII)
char pszTempNumBuf[3] = {0};
strncpy(pszTempNumBuf, &pszEncodedIn[i], 2);
// Ensure both characters are hexadecimal
bool bBothDigits = true;
for(int j = 0; j < 2; ++j)
{
if(!isxdigit(pszTempNumBuf[j]))
bBothDigits = false;
}
if(!bBothDigits)
break;
// Convert two hexadecimal characters into one character
int nAsciiCharacter;
sscanf(pszTempNumBuf, "%x", &nAsciiCharacter);
// Ensure we aren't going to overflow
assert(strlen(pszDecodedOut) < nBufferSize);
// Concatenate this character onto the output
strncat(pszDecodedOut, (char*)&nAsciiCharacter, 1);
// Skip the next character
i++;
}
break;
}
}
}
Ho utilizzato la funzione di Saul in un programma di analisi che stavo scrivendo (analizzando milioni di URL stringhe codificate), e mentre si lavora, a quella scala che stava rallentando il mio programma giù orribilmente, così ho deciso di scrivere una versione più veloce. Questo è migliaia di volte più veloce quando compilato con GCC e l'opzione -O2. Può anche usare lo stesso buffer di output dell'input (ad esempio urldecode2 (buf, buf) funzionerà se la stringa originale era in buf e deve essere sovrascritta dalla sua controparte decodificata).
Edit: Non prende la dimensione di buffer in ingresso perché si presume che il buffer sarà abbastanza grande, questo è sicuro perché è noto che la lunghezza dell'uscita sarà sempre < = che dell'ingresso, quindi utilizzare lo stesso tampone per l'uscita o creare uno che è almeno la dimensione dell'input + 1 per il terminatore nullo, ad esempio:
char *output = malloc(strlen(input)+1);
urldecode2(output, input);
printf("Decoded string: %s\n", output);
Edit 2: un utente anonimo ha tentato di modifica questa risposta per gestire la traduzione del carattere '+' in '', che penso che probabilmente dovrebbe fare, ancora una volta questo non era qualcosa che Avevo bisogno della mia applicazione, ma l'ho aggiunta di seguito.
Ecco la routine:
#include <stdlib.h>
#include <ctype.h>
void urldecode2(char *dst, const char *src)
{
char a, b;
while (*src) {
if ((*src == '%') &&
((a = src[1]) && (b = src[2])) &&
(isxdigit(a) && isxdigit(b))) {
if (a >= 'a')
a -= 'a'-'A';
if (a >= 'A')
a -= ('A' - 10);
else
a -= '0';
if (b >= 'a')
b -= 'a'-'A';
if (b >= 'A')
b -= ('A' - 10);
else
b -= '0';
*dst++ = 16*a+b;
src+=3;
} else if (*src == '+') {
*dst++ = ' ';
src++;
} else {
*dst++ = *src++;
}
}
*dst++ = '\0';
}
La sottrazione dovrebbe essere il contrario. In questo momento sta producendo valori negativi e funziona solo quando si usano lettere HEX maiuscole. – anavarroma
Grazie per questo. Sono stato in grado di usarlo oggi. Come ha commentato Adrià, i calcoli "a - = 'A' - 'a'" e b - = 'A' - 'a' "erano sbagliati e davano risultati negativi per cifre esadecimali minuscole. Mi sono permesso di correggere questo con il mio Ora l'esempio elabora correttamente l'esagono in maiuscolo e minuscolo –
/**
* Locale-independent conversion of ASCII characters to lowercase.
*/
int av_tolower(int c)
{
if (c >= 'A' && c <= 'Z')
c ^= 0x20;
return c;
}
/**
* Decodes an URL from its percent-encoded form back into normal
* representation. This function returns the decoded URL in a string.
* The URL to be decoded does not necessarily have to be encoded but
* in that case the original string is duplicated.
*
* @param url a string to be decoded.
* @return new string with the URL decoded or NULL if decoding failed.
* Note that the returned string should be explicitly freed when not
* used anymore.
*/
char *urldecode(const char *url)
{
int s = 0, d = 0, url_len = 0;
char c;
char *dest = NULL;
if (!url)
return NULL;
url_len = strlen(url) + 1;
dest = av_malloc(url_len);
if (!dest)
return NULL;
while (s < url_len) {
c = url[s++];
if (c == '%' && s + 2 < url_len) {
char c2 = url[s++];
char c3 = url[s++];
if (isxdigit(c2) && isxdigit(c3)) {
c2 = av_tolower(c2);
c3 = av_tolower(c3);
if (c2 <= '9')
c2 = c2 - '0';
else
c2 = c2 - 'a' + 10;
if (c3 <= '9')
c3 = c3 - '0';
else
c3 = c3 - 'a' + 10;
dest[d++] = 16 * c2 + c3;
} else { /* %zz or something other invalid */
dest[d++] = c;
dest[d++] = c2;
dest[d++] = c3;
}
} else if (c == '+') {
dest[d++] = ' ';
} else {
dest[d++] = c;
}
}
return dest;
}
by
www.elesos.com
È impeccabile? – hB0
Prova urlcpp https://github.com/larroy/urlcpp E 'un modulo C++ che si può facilmente integrare nel progetto, dipende da boost :: regex
io suggerirei curl and libcurl . È ampiamente usato e dovrebbe fare il trucco per te. Basta controllare il loro sito web.
Grazie a @ThomasH per la sua risposta. Vorrei proporre qui un formattation meglio ...
E ... poiché il componente URI decodificato è sempre meno lungo lo stesso componente codificata URI, è sempre possibile implodere all'interno del stesso array di caratteri (alias: "stringa").Quindi, io propongo qui due possibilità:
#include <stdio.h>
int decodeURIComponent (char *sSource, char *sDest) {
int nLength;
for (nLength = 0; *sSource; nLength++) {
if (*sSource == '%' && sSource[1] && sSource[2] && isxdigit(sSource[1]) && isxdigit(sSource[2])) {
sSource[1] -= sSource[1] <= '9' ? '0' : (sSource[1] <= 'F' ? 'A' : 'a')-10;
sSource[2] -= sSource[2] <= '9' ? '0' : (sSource[2] <= 'F' ? 'A' : 'a')-10;
sDest[nLength] = 16 * sSource[1] + sSource[2];
sSource += 3;
continue;
}
sDest[nLength] = *sSource++;
}
sDest[nLength] = '\0';
return nLength;
}
#define implodeURIComponent(url) decodeURIComponent(url, url)
E, alla fine ...:
int main() {
char sMyUrl[] = "http%3a%2F%2ffoo+bar%2fabcd";
int nNewLength = implodeURIComponent(sMyUrl);
/* Let's print: "http://foo+bar/abcd\nLength: 19" */
printf("%s\nLength: %d\n", sMyUrl, nNewLength);
return 0;
}
Ste *
Ecco un decoder C per una stringa codificata per cento. Restituisce -1 se la codifica non è valida e 0 altrimenti. La stringa decodificata è memorizzata in out. Sono abbastanza sicuro che questo è il codice più veloce delle risposte fornite finora.
int percent_decode(char* out, const char* in) {
{
static const char tbl[256] = {
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1,
-1,10,11,12,13,14,15,-1, -1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
-1,10,11,12,13,14,15,-1, -1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1
};
char c, v1, v2, beg=out;
if(in != NULL) {
while((c=*in++) != '\0') {
if(c == '%') {
if(!(v1=*in++) || (v1=tbl[(unsigned char)v1])<0 ||
!(v2=*in++) || (v2=tbl[(unsigned char)v2])<0) {
*beg = '\0';
return -1;
}
c = (v1<<4)|v2;
}
*out++ = c;
}
}
*out = '\0';
return 0;
}
Mi piace - il! (v1 = * in ++) e! (v2 = * in ++) sono ridondanti anche se tbl [0] restituisce - 1 invece si può fare: 'if ((v1 = tbl [(unsigned char) * in ++]) <0 || (v2 = tbl [(unsigned char) * in ++]) <0) {... ' – GaspardP
@sbi: Non mi sembra un vero capriccio. – greyfade
@greyfade: Oops, ho ricevuto la domanda sbagliata. Dispiace per la confusione. Ce n'era uno simile, però, solo pochi giorni fa. – sbi
Direi che c'è un dupe: http://stackoverflow.com/questions/2616011/ – sbi