💾 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
-=-=-=-=-=-=-
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: