LCOV - code coverage report
Current view: top level - src - base64.c (source / functions) Hit Total Coverage
Test: mkernel.info Lines: 40 44 90.9 %
Date: 2024-12-05 21:00:54 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /**
       2             :  *    @file  base64.c
       3             :  *   @brief  Simple Base64 encoding and decoding functions
       4             :  *
       5             :  *  Copied and adapted from https://github.com/elzoughby/Base64
       6             :  *
       7             :  *  @author  François Cerbelle (Fanfan), francois@cerbelle.net
       8             :  *
       9             :  *  @internal
      10             :  *       Created:  25/10/2024
      11             :  *      Revision:  none
      12             :  * Last modified:  2024-11-06 10:36
      13             :  *      Compiler:  gcc
      14             :  *  Organization:  Cerbelle.net
      15             :  *     Copyright:  Copyright (c) 2024, François Cerbelle
      16             :  *
      17             :  *  This source code is released for free distribution under the terms of the
      18             :  *  GNU General Public License as published by the Free Software Foundation.
      19             :  */
      20             : 
      21             : #ifdef HAVE_CONFIG_H
      22             : #include "config.h"
      23             : #endif
      24             : 
      25             : #include "base64.h"
      26             : 
      27             : #include <stdlib.h>
      28             : #include <stdio.h>                              /* perror */
      29             : #include <string.h>
      30             : 
      31             : static char base46_map[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
      32             :                             'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y',
      33             :                             'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
      34             :                             'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2',
      35             :                             '3', '4', '5', '6', '7', '8', '9', '+', '/'
      36             :                            };
      37             : 
      38             : 
      39          17 : char* base64_encode(char* plain) {
      40          17 :     unsigned char counts = 0;
      41             :     char buffer[3];
      42          17 :     char* cipher = malloc(strlen(plain) * 4 / 3 + 4);
      43          17 :     int i = 0, c = 0;
      44             : 
      45          17 :     if (NULL==cipher) {
      46           0 :         perror("base64_encode");
      47           0 :         return NULL;
      48             :     }
      49             : 
      50          89 :     for(i = 0; plain[i] != '\0'; i++) {
      51          72 :         buffer[counts++] = plain[i];
      52          72 :         if(counts == 3) {
      53          21 :             cipher[c++] = base46_map[buffer[0] >> 2];
      54          21 :             cipher[c++] = base46_map[((buffer[0] & 0x03) << 4) + (buffer[1] >> 4)];
      55          21 :             cipher[c++] = base46_map[((buffer[1] & 0x0f) << 2) + (buffer[2] >> 6)];
      56          21 :             cipher[c++] = base46_map[buffer[2] & 0x3f];
      57          21 :             counts = 0;
      58             :         }
      59             :     }
      60             : 
      61          17 :     if(counts > 0) {
      62           6 :         cipher[c++] = base46_map[buffer[0] >> 2];
      63           6 :         if(counts == 1) {
      64           3 :             cipher[c++] = base46_map[(buffer[0] & 0x03) << 4];
      65           3 :             cipher[c++] = '=';
      66             :         } else {                      // if counts == 2
      67           3 :             cipher[c++] = base46_map[((buffer[0] & 0x03) << 4) + (buffer[1] >> 4)];
      68           3 :             cipher[c++] = base46_map[(buffer[1] & 0x0f) << 2];
      69             :         }
      70           6 :         cipher[c++] = '=';
      71             :     }
      72             : 
      73          17 :     cipher[c] = '\0';   /* string padding character */
      74          17 :     return cipher;
      75             : }
      76             : 
      77           8 : char* base64_decode(char* cipher) {
      78             : 
      79           8 :     unsigned char counts = 0;
      80             :     char buffer[4];
      81           8 :     char* plain = malloc(strlen(cipher) * 3 / 4 + 1);
      82           8 :     int i = 0, p = 0;
      83             : 
      84           8 :     if (NULL==plain) {
      85           0 :         perror("base64_decode");
      86           0 :         return NULL;
      87             :     }
      88             : 
      89          20 :     for(i = 0; cipher[i] != '\0'; i++) {
      90             :         unsigned char k;
      91         282 :         for(k = 0 ; k < 64 && base46_map[k] != cipher[i]; k++);
      92          12 :         buffer[counts++] = k;
      93          12 :         if(counts == 4) {
      94           3 :             plain[p++] = (buffer[0] << 2) + (buffer[1] >> 4);
      95           3 :             if(buffer[2] != 64)
      96           3 :                 plain[p++] = (buffer[1] << 4) + (buffer[2] >> 2);
      97           3 :             if(buffer[3] != 64)
      98           3 :                 plain[p++] = (buffer[2] << 6) + buffer[3];
      99           3 :             counts = 0;
     100             :         }
     101             :     }
     102             : 
     103           8 :     plain[p] = '\0';    /* string padding character */
     104           8 :     return plain;
     105             : }
     106             : 
     107             : /* vim: set tw=80: */

Generated by: LCOV version 1.16