blob: e0126225e7c02c399432755272a29a41c1734137 [file] [log] [blame]
willy tarreau9e138862006-05-14 23:06:28 +02001/*
2 * Ascii to Base64 conversion as described in RFC1421.
Willy Tarreaubaaee002006-06-26 02:48:02 +02003 *
Willy Tarreau69e989c2008-06-29 17:17:38 +02004 * Copyright 2006-2008 Willy Tarreau <w@1wt.eu>
willy tarreau9e138862006-05-14 23:06:28 +02005 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 */
12
Willy Tarreau2dd0d472006-06-29 17:53:05 +020013#include <common/base64.h>
Willy Tarreaue3ba5f02006-06-29 18:54:54 +020014#include <common/config.h>
willy tarreau9e138862006-05-14 23:06:28 +020015
Willy Tarreau69e989c2008-06-29 17:17:38 +020016const char base64tab[65]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
willy tarreau9e138862006-05-14 23:06:28 +020017
18/* Encodes <ilen> bytes from <in> to <out> for at most <olen> chars (including
19 * the trailing zero). Returns the number of bytes written. No check is made
20 * for <in> or <out> to be NULL. Returns negative value if <olen> is too short
21 * to accept <ilen>. 4 output bytes are produced for 1 to 3 input bytes.
22 */
23int a2base64(char *in, int ilen, char *out, int olen)
24{
willy tarreau9e138862006-05-14 23:06:28 +020025 int convlen;
26
27 convlen = ((ilen + 2) / 3) * 4;
28
29 if (convlen >= olen)
30 return -1;
31
32 /* we don't need to check olen anymore */
33 while (ilen >= 3) {
Willy Tarreaubaaee002006-06-26 02:48:02 +020034 out[0] = base64tab[(((unsigned char)in[0]) >> 2)];
35 out[1] = base64tab[(((unsigned char)in[0] & 0x03) << 4) | (((unsigned char)in[1]) >> 4)];
36 out[2] = base64tab[(((unsigned char)in[1] & 0x0F) << 2) | (((unsigned char)in[2]) >> 6)];
37 out[3] = base64tab[(((unsigned char)in[2] & 0x3F))];
willy tarreau9e138862006-05-14 23:06:28 +020038 out += 4;
39 in += 3; ilen -= 3;
40 }
41
42 if (!ilen) {
43 out[0] = '\0';
44 } else {
Willy Tarreaubaaee002006-06-26 02:48:02 +020045 out[0] = base64tab[((unsigned char)in[0]) >> 2];
willy tarreau9e138862006-05-14 23:06:28 +020046 if (ilen == 1) {
Willy Tarreaubaaee002006-06-26 02:48:02 +020047 out[1] = base64tab[((unsigned char)in[0] & 0x03) << 4];
willy tarreau9e138862006-05-14 23:06:28 +020048 out[2] = '=';
49 } else {
Willy Tarreaubaaee002006-06-26 02:48:02 +020050 out[1] = base64tab[(((unsigned char)in[0] & 0x03) << 4) |
willy tarreau9e138862006-05-14 23:06:28 +020051 (((unsigned char)in[1]) >> 4)];
Willy Tarreaubaaee002006-06-26 02:48:02 +020052 out[2] = base64tab[((unsigned char)in[1] & 0x0F) << 2];
willy tarreau9e138862006-05-14 23:06:28 +020053 }
54 out[3] = '=';
55 out[4] = '\0';
56 }
57
58 return convlen;
59}