Advertisement
TheRouletteBoi

Base64

Aug 15th, 2017
647
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.07 KB | None | 0 0
  1. static void QuartToTrip(char *quart, char *trip, int inlen)
  2. {
  3.     if (inlen >= 2)
  4.         trip[0] = (char)(quart[0] << 2 | quart[1] >> 4);
  5.     if (inlen >= 3)
  6.         trip[1] = (char)((quart[1] & 0x0F) << 4 | quart[2] >> 2);
  7.     if (inlen >= 4)
  8.         trip[2] = (char)((quart[2] & 0x3) << 6 | quart[3]);
  9. }
  10.  
  11. static void TripToQuart(const char *trip, char *quart, int inlen)
  12. {
  13.     unsigned char triptemp[3];
  14.     int i;
  15.     for (i = 0; i < inlen; i++)
  16.     {
  17.         triptemp[i] = (unsigned char)trip[i];
  18.     }
  19.     while (i < 3) //fill the rest with 0
  20.     {
  21.         triptemp[i] = 0;
  22.         i++;
  23.     }
  24.     quart[0] = (char)(triptemp[0] >> 2);
  25.     quart[1] = (char)(((triptemp[0] & 3) << 4) | (triptemp[1] >> 4));
  26.     quart[2] = (char)((triptemp[1] & 0x0F) << 2 | (triptemp[2] >> 6));
  27.     quart[3] = (char)(triptemp[2] & 0x3F);
  28.  
  29. }
  30.  
  31. typedef struct
  32. {
  33.     const char *input;
  34.     int len;
  35.     int encodingType;
  36. } B64StreamData;
  37. const char defaultEncoding[] = { '+','/','=' };
  38. const char alternateEncoding[] = { '[',']','_' };
  39. const char urlSafeEncodeing[] = { '-','_','=' };
  40.  
  41. void B64Decode(const char *input, char *output, int inlen, int * outlen, int encodingType)
  42. {
  43.     const char *encoding = NULL;
  44.     const char *holdin = input;
  45.     int readpos = 0;
  46.     int writepos = 0;
  47.     char block[4];
  48.  
  49.     //int outlen = -1;
  50.     //int inlen = (int)strlen(input);
  51.  
  52.     // 10-31-2004 : Added by Saad Nader
  53.     // now supports URL safe encoding
  54.     ////////////////////////////////////////////////
  55.     switch (encodingType)
  56.     {
  57.     case 1:
  58.         encoding = alternateEncoding;
  59.         break;
  60.     case 2:
  61.         encoding = urlSafeEncodeing;
  62.         break;
  63.     default: encoding = defaultEncoding;
  64.     }
  65.  
  66.     if (inlen <= 0)
  67.     {
  68.         if (outlen)
  69.             *outlen = 0;
  70.         output[0] = '\0';
  71.         return;
  72.     }
  73.  
  74.     // Break at end of string or padding character
  75.     while (readpos < inlen && input[readpos] != encoding[2])
  76.     {
  77.         //    'A'-'Z' maps to 0-25
  78.         //    'a'-'z' maps to 26-51
  79.         //    '0'-'9' maps to 52-61
  80.         //    62 maps to encoding[0]
  81.         //    63 maps to encoding[1]
  82.         if (input[readpos] >= '0' && input[readpos] <= '9')
  83.             block[readpos % 4] = (char)(input[readpos] - 48 + 52);
  84.         else if (input[readpos] >= 'a' && input[readpos] <= 'z')
  85.             block[readpos % 4] = (char)(input[readpos] - 71);
  86.         else if (input[readpos] >= 'A' && input[readpos] <= 'Z')
  87.             block[readpos % 4] = (char)(input[readpos] - 65);
  88.         else if (input[readpos] == encoding[0])
  89.             block[readpos % 4] = 62;
  90.         else if (input[readpos] == encoding[1])
  91.             block[readpos % 4] = 63;
  92.  
  93.         // padding or '\0' characters also mark end of input
  94.         else if (input[readpos] == encoding[2])
  95.             break;
  96.         else if (input[readpos] == '\0')
  97.             break;
  98.         else
  99.         {
  100.             //  (assert(0)); //bad input data
  101.             if (outlen)
  102.                 *outlen = 0;
  103.             output[0] = '\0';
  104.             return; //invaid data
  105.         }
  106.  
  107.         // every 4 bytes, convert QuartToTrip into destination
  108.         if (readpos % 4 == 3) // zero based, so (3%4) means four bytes, 0-1-2-3
  109.         {
  110.             QuartToTrip(block, &output[writepos], 4);
  111.             writepos += 3;
  112.         }
  113.         readpos++;
  114.     }
  115.  
  116.     // Convert any leftover characters in block
  117.     if ((readpos != 0) && (readpos % 4 != 0))
  118.     {
  119.         // fill block with pad (required for QuartToTrip)
  120.         memset(&block[readpos % 4], encoding[2], (unsigned int)4 - (readpos % 4));
  121.         QuartToTrip(block, &output[writepos], readpos % 4);
  122.  
  123.         // output bytes depend on the number of non-pad input bytes
  124.         if (readpos % 4 == 3)
  125.             writepos += 2;
  126.         else
  127.             writepos += 1;
  128.     }
  129.  
  130.     if (outlen)
  131.         *outlen = writepos;
  132. }
  133. void B64Encode(const char *input, char *output, int inlen, int encodingType)
  134. {
  135.     const char *encoding;
  136.     char *holdout = output;
  137.     char *lastchar;
  138.     int todo = inlen;
  139.  
  140.     // 10-31-2004 : Added by Saad Nader
  141.     // now supports URL safe encoding
  142.     ////////////////////////////////////////////////
  143.     switch (encodingType)
  144.     {
  145.     case 1:
  146.         encoding = alternateEncoding;
  147.         break;
  148.     case 2:
  149.         encoding = urlSafeEncodeing;
  150.         break;
  151.     default: encoding = defaultEncoding;
  152.     }
  153.  
  154.     //assume interval of 3
  155.     while (todo > 0)
  156.     {
  157.         TripToQuart(input, output, min(todo, 3));
  158.         output += 4;
  159.         input += 3;
  160.         todo -= 3;
  161.     }
  162.     lastchar = output;
  163.     if (inlen % 3 == 1)
  164.         lastchar -= 2;
  165.     else if (inlen % 3 == 2)
  166.         lastchar -= 1;
  167.     *output = 0; //null terminate!
  168.     while (output > holdout)
  169.     {
  170.         output--;
  171.         if (output >= lastchar) //pad the end
  172.             *output = encoding[2];
  173.         else if (*output <= 25)
  174.             *output = (char)(*output + 65);
  175.         else if (*output <= 51)
  176.             *output = (char)(*output + 71);
  177.         else if (*output <= 61)
  178.             *output = (char)(*output + 48 - 52);
  179.         else if (*output == 62)
  180.             *output = encoding[0];
  181.         else if (*output == 63)
  182.             *output = encoding[1];
  183.     }
  184. }
  185. int B64DecodeLen(const char *input, int encodingType)
  186. {
  187.     const char *encoding;
  188.     const char *holdin = input;
  189.  
  190.     switch (encodingType)
  191.     {
  192.     case 1:
  193.         encoding = alternateEncoding;
  194.         break;
  195.     case 2:
  196.         encoding = urlSafeEncodeing;
  197.         break;
  198.     default: encoding = defaultEncoding;
  199.     }
  200.  
  201.     while (*input)
  202.     {
  203.         if (*input == encoding[2])
  204.             return (input - holdin) / 4 * 3 + (input - holdin - 1) % 4;
  205.         input++;
  206.     }
  207.  
  208.     return (input - holdin) / 4 * 3;
  209. }
  210.  
  211. void B64InitEncodeStream(B64StreamData *data, const char *input, int len, int encodingType)
  212. {
  213.     data->input = input;
  214.     data->len = len;
  215.     data->encodingType = encodingType;
  216. }
  217.  
  218. bool B64EncodeStream(B64StreamData *data, char output[4])
  219. {
  220.     const char *encoding;
  221.     char *c;
  222.     int i;
  223.  
  224.     if (data->len <= 0)
  225.         return false;
  226.  
  227.     // 10-31-2004 : Added by Saad Nader
  228.     // now supports URL safe encoding
  229.     ////////////////////////////////////////////////
  230.     switch (data->encodingType)
  231.     {
  232.     case 1:
  233.         encoding = alternateEncoding;
  234.         break;
  235.     case 2:
  236.         encoding = urlSafeEncodeing;
  237.         break;
  238.     default: encoding = defaultEncoding;
  239.     }
  240.  
  241.     TripToQuart(data->input, output, min(data->len, 3));
  242.     data->input += 3;
  243.     data->len -= 3;
  244.  
  245.     for (i = 0; i < 4; i++)
  246.     {
  247.         c = &output[i];
  248.         if (*c <= 25)
  249.             *c = (char)(*c + 65);
  250.         else if (*c <= 51)
  251.             *c = (char)(*c + 71);
  252.         else if (*c <= 61)
  253.             *c = (char)(*c + 48 - 52);
  254.         else if (*c == 62)
  255.             *c = encoding[0];
  256.         else if (*c == 63)
  257.             *c = encoding[1];
  258.     }
  259.  
  260.     if (data->len < 0)
  261.     {
  262.         output[3] = encoding[2];
  263.         if (data->len == -2)
  264.             output[2] = encoding[2];
  265.     }
  266.  
  267.     return true;
  268. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement