base64

Base64 encoder and decoder
git clone https://noulin.net/git/base64.git
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: