💾 Archived View for gmi.noulin.net › gitRepositories › base64 › file › base64.c.gmi captured on 2023-01-29 at 13:25:08. Gemini links have been rewritten to link to archived content

View Raw

More Information

-=-=-=-=-=-=-

base64

Log

Files

Refs

base64.c (4085B)

     1 #include <string.h>
     2 #include <stdlib.h>
     3 
     4 int base64_encode(unsigned char *source, size_t sourcelen, char *target, size_t targetlen);
     5 size_t base64_encode_size(size_t sourcelen);
     6 void _base64_encode_triple(unsigned char triple[3], char result[4]);
     7 int _base64_char_value(char base64char);
     8 int _base64_decode_triple(char quadruple[4], unsigned char *result);
     9 size_t base64_decode(char *source, unsigned char *target, size_t targetlen);
    10 size_t base64_decode_size(char *source);
    11 
    12 const char *BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    13 
    14 void _base64_encode_triple(unsigned char triple[3], char result[4])
    15 {
    16   int tripleValue, i;
    17 
    18   tripleValue = triple[0];
    19   tripleValue *= 256;
    20   tripleValue += triple[1];
    21   tripleValue *= 256;
    22   tripleValue += triple[2];
    23 
    24   for (i=0; i<4; i++)
    25   {
    26     result[3-i] = BASE64_CHARS[tripleValue%64];
    27     tripleValue /= 64;
    28   }
    29 }
    30 
    31 int base64_encode(unsigned char *source, size_t sourcelen, char *target, size_t targetlen)
    32 {
    33   if ((sourcelen+2)/3*4 > targetlen-1)
    34     return 0;
    35 
    36   while (sourcelen >= 3)
    37   {
    38     _base64_encode_triple(source, target);
    39     sourcelen -= 3;
    40     source += 3;
    41     target += 4;
    42   }
    43 
    44   if (sourcelen > 0)
    45   {
    46     unsigned char temp[3];
    47     memset(temp, 0, sizeof(temp));
    48     memcpy(temp, source, sourcelen);
    49     _base64_encode_triple(temp, target);
    50     target[3] = '=';
    51     if (sourcelen == 1)
    52       target[2] = '=';
    53 
    54     target += 4;
    55   }
    56 
    57   target[0] = 0;
    58 
    59   return 1;
    60 }
    61 
    62 size_t base64_encode_size(size_t sourcelen)
    63 {
    64   return (sourcelen+2)/3*4+1;
    65 }
    66 
    67 int _base64_char_value(char base64char)
    68 {
    69   if (base64char >= 'A' && base64char <= 'Z')
    70     return base64char-'A';
    71   if (base64char >= 'a' && base64char <= 'z')
    72     return base64char-'a'+26;
    73   if (base64char >= '0' && base64char <= '9')
    74     return base64char-'0'+2*26;
    75   if (base64char == '+')
    76     return 2*26+10;
    77   if (base64char == '/')
    78     return 2*26+11;
    79   return -1;
    80 }
    81 
    82 int _base64_decode_triple(char quadruple[4], unsigned char *result)
    83 {
    84   int i, triple_value, bytes_to_decode = 3, only_equals_yet = 1;
    85   int char_value[4];
    86 
    87   for (i=0; i<4; i++)
    88     char_value[i] = _base64_char_value(quadruple[i]);
    89 
    90   for (i=3; i>=0; i--)
    91   {
    92     if (char_value[i]<0)
    93     {
    94       if (only_equals_yet && quadruple[i]=='=')
    95       {
    96         char_value[i]=0;
    97         bytes_to_decode--;
    98         continue;
    99       }
   100       return 0;
   101     }
   102     only_equals_yet = 0;
   103   }
   104 
   105   if (bytes_to_decode < 0)
   106     bytes_to_decode = 0;
   107 
   108   triple_value = char_value[0];
   109   triple_value *= 64;
   110   triple_value += char_value[1];
   111   triple_value *= 64;
   112   triple_value += char_value[2];
   113   triple_value *= 64;
   114   triple_value += char_value[3];
   115 
   116   for (i=bytes_to_decode; i<3; i++)
   117     triple_value /= 256;
   118   for (i=bytes_to_decode-1; i>=0; i--)
   119   {
   120     result[i] = triple_value%256;
   121     triple_value /= 256;
   122   }
   123 
   124   return bytes_to_decode;
   125 }
   126 
   127 size_t base64_decode(char *source, unsigned char *target, size_t targetlen)
   128 {
   129   char *src, *tmpptr;
   130   char quadruple[4];
   131   unsigned char tmpresult[3];
   132   int i, tmplen = 3;
   133   size_t converted = 0;
   134 
   135   src = (char *)malloc(strlen(source)+5);
   136   if (src == NULL)
   137     return -1;
   138   strcpy(src, source);
   139   strcat(src, "====");
   140   tmpptr = src;
   141 
   142   while (tmplen == 3)
   143   {
   144     for (i=0; i<4; i++)
   145     {
   146       while (*tmpptr != '=' && _base64_char_value(*tmpptr)<0)
   147         tmpptr++;
   148 
   149       quadruple[i] = *(tmpptr++);
   150     }
   151 
   152     tmplen = _base64_decode_triple(quadruple, tmpresult);
   153 
   154     if (targetlen < tmplen)
   155     {
   156       free(src);
   157       return -1;
   158     }
   159 
   160     memcpy(target, tmpresult, tmplen);
   161     target += tmplen;
   162     targetlen -= tmplen;
   163     converted += tmplen;
   164   }
   165 
   166   free(src);
   167   return converted;
   168 }
   169 
   170 size_t base64_decode_size(char *source) {
   171 
   172   if (!source) return -1;
   173 
   174   size_t len = strlen(source);
   175 
   176   if (len < 4) /* invalid base64, minimum is 4 chars */ return -1;
   177 
   178   if (source[len-1] != '=') return len*3/4;
   179   if (source[len-2] != '=') return (len-1)*3/4;
   180   else return (len-2)*3/4;
   181 }
   182 
   183 int checkLibsheepyVersionBase64(const char *currentLibsheepyVersion) {
   184   return currentLibsheepyVersion ? 1 : 0;
   185 }
   186 
   187 // vim: set expandtab ts=2 sw=2: