4

How can i encode a URL in client side and Decode the same in Server side.Is there any Built in apis are available for this purpose.Please anyone suggest a solution.Also i want to know how can i do percentage encoding in C++?

Rono
  • 143
  • 1
  • 2
  • 9
  • You should specify OS / libraries used. – Codeguard Aug 19 '13 at 06:16
  • 1
    [`curl_easy_escape`](http://curl.haxx.se/libcurl/c/curl_easy_escape.html) and [`curl_easy_unescape`](http://curl.haxx.se/libcurl/c/curl_easy_unescape.html) seem like obvious possibilities. – Jerry Coffin Aug 19 '13 at 06:21
  • At last i found out an API for URL Encode/Decode--> UrlCanonicalize. This is a shell api, we can use this API for Encoding or Decoding our URL. Please Refer below link http://msdn.microsoft.com/en-us/library/windows/desktop/bb773768(v=vs.85).aspx – Rono Aug 19 '13 at 12:59
  • Does this answer your question? [Encode/Decode URLs in C++](https://stackoverflow.com/questions/154536/encode-decode-urls-in-c) – user2284570 Apr 14 '21 at 00:20

3 Answers3

8

I've found this implementation from dlib quite useful. You don't even need to grab the whole library, just these 4 functions (unhex, hex, encode, decode). And it has a boost license.

strangeqargo
  • 1,276
  • 1
  • 15
  • 23
6

You can check out this article and this

Encode:

std::string UriEncode(const std::string & sSrc)
{
   const char DEC2HEX[16 + 1] = "0123456789ABCDEF";
   const unsigned char * pSrc = (const unsigned char *)sSrc.c_str();
   const int SRC_LEN = sSrc.length();
   unsigned char * const pStart = new unsigned char[SRC_LEN * 3];
   unsigned char * pEnd = pStart;
   const unsigned char * const SRC_END = pSrc + SRC_LEN;

   for (; pSrc < SRC_END; ++pSrc)
   {
      if (SAFE[*pSrc]) 
         *pEnd++ = *pSrc;
      else
      {
         // escape this char
         *pEnd++ = '%';
         *pEnd++ = DEC2HEX[*pSrc >> 4];
         *pEnd++ = DEC2HEX[*pSrc & 0x0F];
      }
   }

   std::string sResult((char *)pStart, (char *)pEnd);
   delete [] pStart;
   return sResult;
}

Decode:

std::string UriDecode(const std::string & sSrc)
{
   // Note from RFC1630: "Sequences which start with a percent
   // sign but are not followed by two hexadecimal characters
   // (0-9, A-F) are reserved for future extension"

   const unsigned char * pSrc = (const unsigned char *)sSrc.c_str();
   const int SRC_LEN = sSrc.length();
   const unsigned char * const SRC_END = pSrc + SRC_LEN;
   // last decodable '%' 
   const unsigned char * const SRC_LAST_DEC = SRC_END - 2;

   char * const pStart = new char[SRC_LEN];
   char * pEnd = pStart;

   while (pSrc < SRC_LAST_DEC)
   {
      if (*pSrc == '%')
      {
         char dec1, dec2;
         if (-1 != (dec1 = HEX2DEC[*(pSrc + 1)])
            && -1 != (dec2 = HEX2DEC[*(pSrc + 2)]))
         {
            *pEnd++ = (dec1 << 4) + dec2;
            pSrc += 3;
            continue;
         }
      }

      *pEnd++ = *pSrc++;
   }

   // the last 2- chars
   while (pSrc < SRC_END)
      *pEnd++ = *pSrc++;

   std::string sResult(pStart, pEnd);
   delete [] pStart;
   return sResult;
}
Rahul Tripathi
  • 168,305
  • 31
  • 280
  • 331
  • 1
    Better -- now a little rewriting to get rid of the `new[]` and `delete []`, and... – Jerry Coffin Aug 19 '13 at 06:26
  • Better to use a `std::string` or a `std::vector` rather than using `new []` and `delete []` directly. Just for example, if an exception is thrown anywhere between the `new` and the `delete`, these will leak memory. – Jerry Coffin Aug 19 '13 at 06:37
  • Ok...Got your point. Actually this is just a copy paste from the site which I have refernced. Now I guess OP can get an idea what he has to do!!! ;) – Rahul Tripathi Aug 19 '13 at 06:38
  • @JerryCoffin--> Thanks for the reply.Can i use any built in api like URLCanonicalize or something like that for the same? – Rono Aug 19 '13 at 06:40
  • @Rono: Built into what? – Jerry Coffin Aug 19 '13 at 06:40
  • @JerryCoffin-->Modified commment plz check – Rono Aug 19 '13 at 06:42
  • @JerryCoffin->>Simply my question is How can i do percentage encoding in C++ – Rono Aug 19 '13 at 07:21
  • 6
    At last i found out an API for URL Encode/Decode--> UrlCanonicalize. This is a shell api, we can use this API for Encoding or Decoding our URL. Please Refer below link http://msdn.microsoft.com/en-us/library/windows/desktop/bb773768(v=vs.85).aspx – Rono Aug 19 '13 at 12:59
  • 4
    hmmm... isn't the encode function missing a `SAFE` declaration? how would `if(SAFE[*pSrc])` be processed? – g3rv4 Jan 18 '14 at 21:01
  • I don't think the included encode function is complete. For example: It will not deal with spaces in the input correctly. UPDATE: I stand corrected as a proper way of handling spaces is by converting them to '%20' and not '+'. – Arxo Clay Sep 09 '14 at 21:11
  • @GervasioMarchand: visit the link at the beginning - there's the whole code. The `UrlCanonicalize` Windows API needs the URI to be complete with protocol prefix which the above code does not. – fmuecke Aug 31 '15 at 21:21
  • @g3rv4 can confirm the function is working well with the following SAFE declaration: https://github.com/manikandaraj/MLabs/blob/f57279973f6e92ffe06d81f2934f1ec6be9df544/C%2B%2B/Utils/URIUtil/URIUtility.cpp#L44-L66 however it is worth noting that this function will only encode from windows-1252, not UTF-8 – hack-tramp May 05 '21 at 09:17
0

For Encoding:

You can use "g_uri_escape_string()" function provided glib.h. https://developer.gnome.org/glib/stable/glib-URI-Functions.html

#include <stdio.h>
#include <stdlib.h>
#include <glib.h>
int main() {
    char *uri = "http://www.example.com?hello world";
    char *encoded_uri = NULL;
    //as per wiki (https://en.wikipedia.org/wiki/Percent-encoding)
    char *escape_char_str = "!*'();:@&=+$,/?#[]"; 
    encoded_uri = g_uri_escape_string(uri, escape_char_str, TRUE);
    printf("[%s]\n", encoded_uri);
    free(encoded_uri);

    return 0;
}

compile it with:

gcc encoding_URI.c `pkg-config --cflags --libs glib-2.0`
Vineet Mimrot
  • 99
  • 1
  • 6