base64.c (2214B)
1 /* 2 * Copy me if you can. 3 * by 20h 4 */ 5 6 #include <unistd.h> 7 #include <stdlib.h> 8 #include <string.h> 9 #include <strings.h> 10 11 #include "ind.h" 12 13 char be[] = 14 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; 15 16 int 17 readnwstr(char *buf, char *str, int *p, int max, int l) 18 { 19 int i, j; 20 21 for (i = 0; *p < max && i < l; (*p)++) { 22 for (j = 0; j < strlen(be); j++) { 23 if (str[*p] == be[j]) { 24 buf[i++] = str[*p]; 25 break; 26 } 27 } 28 } 29 30 if (i < l) 31 return 1; 32 return 0; 33 } 34 35 char * 36 b64enc(char *str, int l) 37 { 38 char *ret; 39 int p, po, left; 40 41 po = 0; 42 p = 0; 43 44 ret = mallocz(5, 0); 45 for (; p < l; p += 3, po += 4) { 46 ret = reallocz(ret, po + 5, 0); 47 48 ret[po] = be[(str[p] & 0xFC) >> 2]; 49 ret[po+1] = be[(str[p] & 0x03) << 4 \ 50 | (str[p+1] & 0xF0) >> 4]; 51 ret[po+2] = be[(str[p+1] & 0x0F) << 2 \ 52 | (str[p+2] & 0xC0) >> 6]; 53 ret[po+3] = be[str[p+2] & 0x3F]; 54 } 55 left = l - p + 3; 56 po -= 4; 57 switch (left) { 58 case 1: 59 ret[po+2] = '='; 60 case 2: 61 ret[po+3] = '='; 62 default: 63 break; 64 } 65 ret[po+4] = '\0'; 66 67 return ret; 68 } 69 70 char * 71 b64dec(char *istr, int *len) 72 { 73 char *ret, str[5]; 74 int p, po, l, uglyline; 75 char bd[256]; 76 77 memset(bd, 0x80, 256); 78 /* Without »=«. */ 79 for (p = 0; p < strlen(be)-1; p++) 80 bd[(int)be[p]] = p; 81 bd['='] = 0; 82 83 p = 0; 84 po = 0; 85 ret = NULL; 86 87 /* 88 * If there is something prepended to the base64 block, take it as-is. 89 */ 90 for (uglyline = 1, l = 0; uglyline == 1; l = p) { 91 uglyline = 0; 92 for (; istr[l] != '\n' && istr[l]; l++) { 93 if (istr[l] == ' ') 94 uglyline = 1; 95 } 96 /* Take care of empty lines. */ 97 if ((l - p) == 1 && istr[l-1] == '\r') 98 uglyline = 1; 99 if ((l - p) == 0) 100 uglyline = 1; 101 if (uglyline) 102 po = p = l + 1; 103 } 104 if (p > 0) { 105 ret = reallocz(ret, l, 0); 106 memmove(ret, istr, p+1); 107 } 108 109 110 for (; !readnwstr(str, istr, &p, *len, 4); po += 3) { 111 ret = reallocz(ret, po + 4, 0); 112 113 ret[po] = bd[(int)str[0]] << 2 | bd[(int)str[1]] >> 4; 114 ret[po+1] = bd[(int)str[1]] << 4 | bd[(int)str[2]] >> 2; 115 ret[po+2] = bd[(int)str[2]] << 6 | bd[(int)str[3]]; 116 } 117 if (str[3] == '=') 118 po--; 119 if (str[2] == '=') 120 po--; 121 ret[po] = '\0'; 122 *len = po; 123 124 return ret; 125 } 126 127 int 128 b64len(int len) 129 { 130 return (len / 3) * 4 + (len % 3 > 0)? 4 : 0; 131 } 132