[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>
|
#include <common/config.h>
|
||||||
|
|
||||||
int a2base64(char *in, int ilen, char *out, int olen);
|
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[];
|
extern const char base64tab[];
|
||||||
|
|
||||||
#endif /* _COMMON_BASE64_H */
|
#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 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
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* 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/base64.h>
|
||||||
#include <common/config.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 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
|
/* 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
|
* 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;
|
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