./ MultiCS.r82 / base64.c
#define CR '\r' #define LF '\n' #define CRLF "\r\n" #define CBASE64_BUFFSZ 32 char base64_chr_table(int index) { char table[] = { 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P', 'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f', 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v', 'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'}; return table[index]; } typedef struct b64_chunk { /* ** longeur de la chaine, comme on n'aura besoin d'aller de 0 a 3, on utilise un ** unsigned char plutot qu'un unsigned int pour gagner 3 octets sur un une ** plateforme 32 bits. */ int len; /* ** Buffers d'encodage et de décodage. */ char enc[4]; char dec[3]; }B64_CHUNK; void base64_encoding_process(B64_CHUNK *ptr) { ptr->enc[0] = base64_chr_table((ptr->dec[0] & 0xFC) >> 2); ptr->enc[1] = base64_chr_table((((ptr->dec[0] & 0x03) << 4) | ((ptr->dec[1] & 0xF0) >> 4))); ptr->enc[2] = (ptr->len > 1) ? base64_chr_table(((ptr->dec[1] & 0x0F) << 2) | ((ptr->dec[2] & 0xC0) >> 6)) : '='; ptr->enc[3] = (ptr->len > 2) ? base64_chr_table(ptr->dec[2] & 0x3F) : '='; } void base64_decoding_process(B64_CHUNK *ptr) { ptr->dec[0] = ((ptr->enc[0] & 0x3F) << 2) | (((ptr->enc[1]) & 0x30) >> 4); ptr->dec[1] = ((ptr->enc[1] & 0x0F) << 4) | (((ptr->enc[2]) & 0x3C) >> 2); ptr->dec[2] = ((ptr->enc[2] & 0x0F) << 6) | ((ptr->enc[3]) & 0x3F); } /* ** Encodage d'une chaine de caracteres */ char * base64_pencode(const char *in, char *out, int linesz) { int i, o, len; B64_CHUNK *chunk; chunk = malloc(sizeof(*chunk)); for(i = 0, o = 0, len = 0; in[i];) { for (chunk->len = 0; chunk->len < 3 && in[i];) { chunk->dec[chunk->len++] = in[i++]; } base64_encoding_process(chunk); if (len >= linesz) { out[o++] = '\r'; out[o++] = '\n'; len = 0; } for (chunk->len = 0; chunk->len < 4;) { out[o++] = chunk->enc[chunk->len++]; len++; } } out[o] = '\0'; free(chunk); return out; } /* ** Décodage d'une chaine de caracteres */ void base64_chr_real(char *chr) { if ( *chr >= 0x41 && *chr <= 0x5A) { *chr -= 0x41; } else if (*chr >= 0x61 && *chr <= 0x7A) { *chr -= 0x47; } else if (*chr >= 0x30 && *chr <= 0x39) { *chr += 0x04; } else if (*chr == 0x2B) { *chr = 0x3E; } else if (*chr == 0x2F) { *chr = 0x3F; } else if (*chr == 0x3D) { *chr = 64; } else { *chr = -1; } } char * base64_pdecode(const char *in, char *out) { int i, o; B64_CHUNK *chunk; chunk = malloc(sizeof(*chunk)); for (i = 0, o = 0; in[i];) { for (chunk->len = 0; chunk->len < 4 && in[i];) { chunk->enc[chunk->len] = in[i++]; base64_chr_real(chunk->enc + chunk->len); if (chunk->enc[chunk->len] >= 0) { chunk->len++; } } base64_decoding_process(chunk); for (chunk->len = 0; chunk->len < 3 && chunk->dec[chunk->len];) { out[o++] = chunk->dec[chunk->len++]; } } out[o] = '\0'; free(chunk); return out; }