[MINOR] Base64 decode
Implement Base64 decoding with a reverse table. The function accepts and decodes classic base64 strings, which can be composed from many streams as long each one is properly padded, for example: SGVsbG8=IEhBUHJveHk=IQ==
This commit is contained in:
parent
4a3323b83d
commit
fccbdc8421
|
@ -17,6 +17,8 @@
|
|||
#include <common/config.h>
|
||||
|
||||
int a2base64(char *in, int ilen, char *out, int olen);
|
||||
int base64dec(const char *in, size_t ilen, char *out, size_t olen);
|
||||
|
||||
extern const char base64tab[];
|
||||
|
||||
#endif /* _COMMON_BASE64_H */
|
||||
|
|
80
src/base64.c
80
src/base64.c
|
@ -1,7 +1,8 @@
|
|||
/*
|
||||
* Ascii to Base64 conversion as described in RFC1421.
|
||||
* ASCII <-> Base64 conversion as described in RFC1421.
|
||||
*
|
||||
* Copyright 2006-2008 Willy Tarreau <w@1wt.eu>
|
||||
* Copyright 2009-2010 Krzysztof Piotr Oledzki <ole@ans.pl>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -10,10 +11,19 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <common/base64.h>
|
||||
#include <common/config.h>
|
||||
|
||||
#define B64BASE '#' /* arbitrary chosen base value */
|
||||
#define B64CMIN '+'
|
||||
#define B64CMAX 'z'
|
||||
#define B64PADV 64 /* Base64 chosen special pad value */
|
||||
|
||||
const char base64tab[65]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
const char base64rev[]="b###cXYZ[\\]^_`a###d###$%&'()*+,-./0123456789:;<=######>?@ABCDEFGHIJKLMNOPQRSTUVW";
|
||||
|
||||
/* Encodes <ilen> bytes from <in> to <out> for at most <olen> chars (including
|
||||
* the trailing zero). Returns the number of bytes written. No check is made
|
||||
|
@ -57,3 +67,71 @@ int a2base64(char *in, int ilen, char *out, int olen)
|
|||
|
||||
return convlen;
|
||||
}
|
||||
|
||||
/* Decodes <ilen> bytes from <in> to <out> for at most <olen> chars.
|
||||
* Returns the number of bytes converted. No check is made for
|
||||
* <in> or <out> to be NULL. Returns -1 if <in> is invalid or ilen
|
||||
* has wrong size, -2 if <olen> is too short.
|
||||
* 1 to 3 output bytes are produced for 4 input bytes.
|
||||
*/
|
||||
int base64dec(const char *in, size_t ilen, char *out, size_t olen) {
|
||||
|
||||
unsigned char t[4];
|
||||
signed char b;
|
||||
int convlen = 0, i = 0, pad = 0;
|
||||
|
||||
if (ilen % 4)
|
||||
return -1;
|
||||
|
||||
if (olen < ilen / 4 * 3)
|
||||
return -2;
|
||||
|
||||
while (ilen) {
|
||||
|
||||
/* if (*p < B64CMIN || *p > B64CMAX) */
|
||||
b = (signed char)*in - B64CMIN;
|
||||
if ((unsigned char)b > (B64CMAX-B64CMIN))
|
||||
return -1;
|
||||
|
||||
b = base64rev[b] - B64BASE - 1;
|
||||
|
||||
/* b == -1: invalid character */
|
||||
if (b < 0)
|
||||
return -1;
|
||||
|
||||
/* padding has to be continous */
|
||||
if (pad && b != B64PADV)
|
||||
return -1;
|
||||
|
||||
/* valid padding: "XX==" or "XXX=", but never "X===" or "====" */
|
||||
if (pad && i < 2)
|
||||
return -1;
|
||||
|
||||
if (b == B64PADV)
|
||||
pad++;
|
||||
|
||||
t[i++] = b;
|
||||
|
||||
if (i == 4) {
|
||||
/*
|
||||
* WARNING: we allow to write little more data than we
|
||||
* should, but the checks from the beginning of the
|
||||
* functions guarantee that we can safely do that.
|
||||
*/
|
||||
|
||||
/* xx000000 xx001111 xx111122 xx222222 */
|
||||
out[convlen] = ((t[0] << 2) + (t[1] >> 4));
|
||||
out[convlen+1] = ((t[1] << 4) + (t[2] >> 2));
|
||||
out[convlen+2] = ((t[2] << 6) + (t[3] >> 0));
|
||||
|
||||
convlen += 3-pad;
|
||||
|
||||
pad = i = 0;
|
||||
}
|
||||
|
||||
in++;
|
||||
ilen--;
|
||||
}
|
||||
|
||||
return convlen;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue