URL decoding function in C++/C?


H

Herman.Schultz

Hi,

Can you please tell me if there is a library function in C++/C to do
URL decoding?
i.e. change from:
http%3A%2F%2F
to:
http://

Thank you.
 
Ad

Advertisements

?

=?ISO-8859-1?Q?Erik_Wikstr=F6m?=

Hi,

Can you please tell me if there is a library function in C++/C to do
URL decoding?
i.e. change from:
http%3A%2F%2F
to:
http://

There's non in standard C++, if you are using some framework/library
there might be one in that. Else I think you can do something similar
yourself quite easy (this is based on my limited understanding of how
this URL encoding works).

All you have to do is copy the URL until you encounter '%', then you
read in the next two characters, convert them to an int, create a char
variable, assign the number to it, add the char to the copy. Then
proceed like this until you reach the end of the URL.

This however requires that your platform uses ASCII as native chars (or
whatever it is called).
 
D

Default User

Hi,

Can you please tell me if there is a library function in C++/C to do
URL decoding?
i.e. change from:
http%3A%2F%2F
to:
http://

Nothing standard. Google around, there are tons of snippets for that
sort of thing.



Brian
 
B

BobR

Hi,
Can you please tell me if there is a library function in C++/C to do
URL decoding?
i.e. change from:
http%3A%2F%2F
to:
http://

Thank you.

Not hard to write your own.

{
std::cout<<"-------"<<std::endl;
std::string Test( "http%3A%2F%2F" );
std::cout<<Test<<std::endl;
std::string Find1( "%3A" );
std::string Rep1( ":" );
std::string Find2( "%2F" );
std::string Rep2( "/" );
Test.replace( Test.find( Find1 ), Find1.size(), Rep1);
std::size_t Pos;
while( ( Pos = Test.find( Find2 ) ) != Test.npos ){
Test.replace( Pos, Find2.size(), Rep2 );
}
std::cout<<Test<<std::endl;
std::cout<<"-------"<<std::endl;
}


Maybe put the from/to pairs in a std::map, and use that in a loop.
 
D

Default User

BobR said:
Not hard to write your own.

{
std::cout<<"-------"<<std::endl;
std::string Test( "http%3A%2F%2F" );
std::cout<<Test<<std::endl;
std::string Find1( "%3A" );
std::string Rep1( ":" );
std::string Find2( "%2F" );
std::string Rep2( "/" );

Yeah, but there are lot of characters to decode. You're better off not
reinventing the wheel unless there's a particular reason to do so, like
it's a instructional program.

Many decode programs are out there, in most any language you like.




Brian
 
Ad

Advertisements

R

Robbie Hatley

Herman said:
Hi,
Hello!

Can you please tell me if there is a library function
in C++/C to do URL decoding?
i.e. change from:
http%3A%2F%2F
to:
http://

There is no *standard* library facility to do that.

There's almost certainly libraries out there that have
that facility, though. Google for "C++ URL library" or
similar searches.

However, it may be simpler to just to write your own.

Here's a big hint: Unix file names may only contain certain
characters, not others; so Unix tends to turn unacceptable
characters into 3-character triglyphs consisting of "%"
followed by the two-digit ASCII value of the character,
in hexidecimal. (Or, if the numbers are greater than %7E,
they're probably ISO-8859-1 instead of ASCII.)

Examples:

* = %2A (as in "grep 'dog' *") // ASCII
/ = %2F (as in "user/bin") // ASCII
§ = %A7 (as in "see §38.7.13") // assuming ISO-8859-1
ñ = %F1 (as in "España") // assuming ISO-8859-1

(Google "ASCII" and "ISO-8859-1" for more on these encodings.)

So just replace each %HH with the character who's encoding
is "HH". Eg: "%64%6F%67" becomes "dog".

Grab each "%XY" using std::string.find() and std::string.substr().
Feed each "%XY" substring into a function that returns the
character with that encoding. Then replace the "%XY" in the string
with the character Z which you just generated, by using
std::string.replace().

Here's a program I just wrote, for the fun of it, which solves
your problem (tested, working code). (CAVEAT: This assumes that
any '%' character will be followed by a valid two-digit hexidecimal
number. If not, it will blow up. You'll have to add your own
error-checking.)

// dehex.cpp

#include <iostream>
#include <string>
#include <sstream>

char CharFromHex (std::string a)
{
std::istringstream Blat (a);
int Z;
Blat >> std::hex >> Z;

/*
int X = int (a[1]); // 16^1 place value
if (X >= 97) {X -= 97;} // capital letter?
else if (X >= 65) {X -= 65;} // small letter?
else {X -= 48;} // numeral?
int Y = int (a[2]); // 16^0 place value
if (Y >= 97) {Y -= 97;} // capital letter?
else if (Y >= 65) {Y -= 65;} // small letter?
else {Y -= 48;} // numeral?
int Z = 16 * X + Y; // generate numerical value of character
*/

return char (Z); // cast to char and return
}

int main (int Beren, char * Luthien[])
{
std::string Text (Luthien[1]);
std::string::size_type Pos;
std::string Hex;
while (std::string::npos != (Pos = Text.find('%')))
{
Hex = Text.substr(Pos + 1, 2);
Text.replace(Pos, 3, 1, CharFromHex(Hex));
}
std::cout << Text << std::endl;
return 0;
}
Thank you.

You're welcome.
 
J

James Kanze

There is no *standard* library facility to do that.
There's almost certainly libraries out there that have
that facility, though. Google for "C++ URL library" or
similar searches.
However, it may be simpler to just to write your own.

You're kidding, of course.
Here's a big hint: Unix file names may only contain certain
characters, not others;

It has nothing to do with Unix; the only characters which cannot
occur in a Unix filename are '/' and '\0'.

[...]
Grab each "%XY" using std::string.find() and std::string.substr().
Feed each "%XY" substring into a function that returns the
character with that encoding. Then replace the "%XY" in the string
with the character Z which you just generated, by using
std::string.replace().

And this is simpler than just calling a single function in a
third party library.
Here's a program I just wrote, for the fun of it, which solves
your problem (tested, working code). (CAVEAT: This assumes that
any '%' character will be followed by a valid two-digit hexidecimal
number. If not, it will blow up. You'll have to add your own
error-checking.)

Which will likely increase the size of the code by two or three.
 
Joined
Mar 5, 2011
Messages
1
Reaction score
0
url encoding snippet

While I generally agree with the last poster who says that you should try to use a tested library, I was unsuccessful in finding a lightweight library (curl was too heavy for me). Plus, I'm running in a special multi-threaded environment where I need to have very good accounting of my memory management. So, I wrote this snippet to do url-encoding, adapted from other code I found on the web (http://www.gidforums.com/t-2615.html). Hope it helps the next guy find what he's looking for faster. Note that it's conservative and encodes everything that's not a number or a letter, but urldecoders will generally work with that.

template <class type> //template usage to allow multiple types of parameters
void dec_to_hex(type _num, char *hdigits)
{
const char *hlookup = "0123456789ABCDEF";

if(_num<0) _num *= -1;

char mask = 0x000f;

hdigits[1] = hlookup[mask & _num];
hdigits[0] = hlookup[mask & (_num >> 4)];

return;
}

void urlencode(std::string &str) {
size_t pos = 0;
std::string replacement;
for ( ; pos < str.length(); pos++) {
if (!isalnum(str[pos])) {
char dec[2];
dec_to_hex(str[pos], dec);
std::string replacement = "%" + std::string(dec, 2);
str.replace(pos, 1, replacement);
}
}
}
 
Ad

Advertisements

Joined
Nov 6, 2011
Messages
1
Reaction score
0
I am looking for something similar and wanted to know if the code could be adapted to receive a parameter S_Cookie1 and convert the URL encoding to an HTML encoding param S_CORRECT? I need to pass S_CORRECT back to the server in a SOAP env. Thank you for any help.

S_Cookie1 = "3%2635%3Dsaptest15001%2C8P%26S5%2C88%2663%3DsecEnterprise%2C8P%264F%3D462265%2C8P%264E%3D642037JfUyOifEckq6pX62%2C8P%26pa%2C8P%26Tm%3D3650%2C83%261%2C8P%262r%3Dcgar-bobjqapp2%3A6400%2C8P%26Tn%3D{3%26.2%3D{3%26O%3DPersonalCategory%2C0P%262%3D462327%2C03}%2C2z%26.1%3D{3%26O%3DFavoritesFolder%2C0P%262%3D462326%2C03}%2C2z%26.3%3D{3%26O%3DInbox%2C0P%262%3D462328%2C03}%2C2z%26U%3D3%2C03}%2C%3Fz%263k%3D%40BOBJ_QA%2C8P%265U%3D642038JhpJ4sSqGXzP9rYn642037JfUyOifEckq6pX62%2C8P"

to

S_CORRECT = "3&amp;35=saptest15001,8P&amp;S5,88&amp;63=secEnterprise,8P&amp;4F=462265,8P&amp;4E=642037JfUyOifEckq6pX62,8P&amp;pa,8P&amp;Tm=3650,83&amp;1,8P&amp;2r=cgar-bobjqapp2:6400,8P&amp;Tn={3&amp;.2={3&amp;O=PersonalCategory,0P&amp;2=462327,03},2z&amp;.1={3&amp;O=FavoritesFolder,0P&amp;2=462326,03},2z&amp;.3={3&amp;O=Inbox,0P&amp;2=462328,03},2z&amp;U=3,03},?z&amp;[email protected]_QA,8P&amp;5U=642038JhpJ4sSqGXzP9rYn642037JfUyOifEckq6pX62,8P"
 
Ad

Advertisements


Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top