mirror of
https://github.com/yarrick/iodine.git
synced 2024-11-24 00:59:19 +02:00
Base64 codec now uses + as 64th char
This commit is contained in:
parent
de2912c089
commit
524522d00a
164
src/base64.c
164
src/base64.c
|
@ -23,14 +23,11 @@
|
||||||
#include "base64.h"
|
#include "base64.h"
|
||||||
|
|
||||||
static const char cb64[] =
|
static const char cb64[] =
|
||||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789.";
|
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789+";
|
||||||
static unsigned char rev64[128];
|
static unsigned char rev64[128];
|
||||||
static int reverse_init = 0;
|
static int reverse_init = 0;
|
||||||
|
|
||||||
#define REV64(x) rev64[(int) (x)]
|
#define REV64(x) rev64[(int) (x)]
|
||||||
#define MODE (cb64[62])
|
|
||||||
#define P62 (cb64[62])
|
|
||||||
#define P63 (cb64[63])
|
|
||||||
|
|
||||||
static struct encoder base64_encoder =
|
static struct encoder base64_encoder =
|
||||||
{
|
{
|
||||||
|
@ -53,140 +50,6 @@ base64_handles_dots()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
findesc(int *count, unsigned char *esc, char c1, char c2, char c3, char c4)
|
|
||||||
{
|
|
||||||
int min1 = 0;
|
|
||||||
int min2 = 0;
|
|
||||||
|
|
||||||
int num1 = 0xFF; /* a very big number */
|
|
||||||
int num2 = 0xFE; /* a nearly as big number */
|
|
||||||
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* check if no more escapes needed */
|
|
||||||
if (count[62] == 0 && count[63] == 0) {
|
|
||||||
esc[0] = MODE;
|
|
||||||
esc[1] = MODE;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < 62; i++) {
|
|
||||||
if (i == c1 || i == c2 || i == c3 || i == c4) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count[i] < num1) {
|
|
||||||
min2 = min1;
|
|
||||||
num2 = num1;
|
|
||||||
min1 = i;
|
|
||||||
num1 = count[i];
|
|
||||||
} else if (count[i] < num2) {
|
|
||||||
min2 = i;
|
|
||||||
num2 = count[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
esc[0] = cb64[min1];
|
|
||||||
esc[1] = cb64[min2];
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
escape_chars(char *buf, size_t buflen)
|
|
||||||
{
|
|
||||||
int counter[64];
|
|
||||||
int escapes;
|
|
||||||
int reset;
|
|
||||||
int i;
|
|
||||||
unsigned char temp[4096];
|
|
||||||
unsigned char *r;
|
|
||||||
unsigned char *w;
|
|
||||||
unsigned char *e;
|
|
||||||
unsigned char esc[2];
|
|
||||||
|
|
||||||
memset(counter, 0, sizeof(counter));
|
|
||||||
esc[0] = P62;
|
|
||||||
esc[1] = P63;
|
|
||||||
|
|
||||||
/* first, find the number of times each token is used */
|
|
||||||
r = (unsigned char *) buf;
|
|
||||||
w = temp;
|
|
||||||
while (*r) {
|
|
||||||
counter[REV64(*r)]++;
|
|
||||||
*w++ = *r++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check if work needed */
|
|
||||||
if (counter[62] == 0 && counter[63] == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
r = temp;
|
|
||||||
w = (unsigned char *) buf;
|
|
||||||
reset = 1;
|
|
||||||
escapes = 0;
|
|
||||||
/* check a block for esc chars */
|
|
||||||
while (*r) {
|
|
||||||
if (reset == 0 && escapes == 0 && (
|
|
||||||
r[0] == esc[0] || r[1] == esc[0] ||r[2] == esc[0] ||r[2] == esc[0] ||
|
|
||||||
r[0] == esc[1] || r[1] == esc[1] ||r[2] == esc[1] ||r[2] == esc[1])) {
|
|
||||||
/* last set of escape chars were unused.
|
|
||||||
* if we reset last escape switch then maybe we dont have to switch now */
|
|
||||||
|
|
||||||
/* change the latest escape switch to 999 (RESET) */
|
|
||||||
e[1] = MODE;
|
|
||||||
e[2] = MODE;
|
|
||||||
|
|
||||||
/* store default esc chars */
|
|
||||||
esc[0] = P62;
|
|
||||||
esc[1] = P63;
|
|
||||||
|
|
||||||
reset = 1;
|
|
||||||
}
|
|
||||||
/* these two if blocks can not be combined because a block can contain both
|
|
||||||
* char 9 and/or . and the current escape chars. */
|
|
||||||
if (r[0] == esc[0] || r[1] == esc[0] ||r[2] == esc[0] ||r[2] == esc[0] ||
|
|
||||||
r[0] == esc[1] || r[1] == esc[1] ||r[2] == esc[1] ||r[2] == esc[1]) {
|
|
||||||
/* switch escape chars */
|
|
||||||
escapes = 0;
|
|
||||||
reset = 0;
|
|
||||||
|
|
||||||
/* find 2 suitable escape chars */
|
|
||||||
findesc(counter, esc, REV64(r[0]), REV64(r[1]), REV64(r[2]), REV64(r[3]));
|
|
||||||
|
|
||||||
/* store escape switch position */
|
|
||||||
e = w;
|
|
||||||
|
|
||||||
/* write new escape chars */
|
|
||||||
*w++ = MODE;
|
|
||||||
*w++ = esc[0];
|
|
||||||
*w++ = esc[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* update counter on remaining chars */
|
|
||||||
for (i = 0; i < 4; i++) {
|
|
||||||
if (r[i])
|
|
||||||
counter[REV64(r[i])]--;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* do the escaping */
|
|
||||||
for (i = 0; i < 4; i++) {
|
|
||||||
if (r[i] == P62) {
|
|
||||||
r[i] = esc[0];
|
|
||||||
escapes++;
|
|
||||||
} else if (r[i] == P63) {
|
|
||||||
r[i] = esc[1];
|
|
||||||
escapes++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* copy back to buf */
|
|
||||||
*w++ = *r++;
|
|
||||||
*w++ = *r++;
|
|
||||||
*w++ = *r++;
|
|
||||||
*w++ = *r++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
base64_encode(char *buf, size_t *buflen, const void *data, size_t size)
|
base64_encode(char *buf, size_t *buflen, const void *data, size_t size)
|
||||||
{
|
{
|
||||||
|
@ -231,8 +94,6 @@ base64_encode(char *buf, size_t *buflen, const void *data, size_t size)
|
||||||
}
|
}
|
||||||
*p = 0;
|
*p = 0;
|
||||||
|
|
||||||
escape_chars(buf, *buflen);
|
|
||||||
|
|
||||||
/* store number of bytes from data that was used */
|
/* store number of bytes from data that was used */
|
||||||
*buflen = size;
|
*buflen = size;
|
||||||
|
|
||||||
|
@ -274,8 +135,6 @@ base64_decode(void *buf, size_t *buflen, const char *str, size_t slen)
|
||||||
const char *p;
|
const char *p;
|
||||||
unsigned char c;
|
unsigned char c;
|
||||||
unsigned char block[4];
|
unsigned char block[4];
|
||||||
unsigned char prot62;
|
|
||||||
unsigned char prot63;
|
|
||||||
int len;
|
int len;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -296,33 +155,12 @@ base64_decode(void *buf, size_t *buflen, const char *str, size_t slen)
|
||||||
slen = maxsize;
|
slen = maxsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
prot62 = P62;
|
|
||||||
prot63 = P63;
|
|
||||||
|
|
||||||
q = buf;
|
q = buf;
|
||||||
for (p = str; *p; p += 4) {
|
for (p = str; *p; p += 4) {
|
||||||
/* handle escape instructions */
|
|
||||||
if (*p == MODE) {
|
|
||||||
p++;
|
|
||||||
if (p[0] == MODE && p[1] == MODE) {
|
|
||||||
/* reset escape chars */
|
|
||||||
prot62 = P62;
|
|
||||||
prot63 = P63;
|
|
||||||
|
|
||||||
p += 2;
|
|
||||||
} else {
|
|
||||||
prot62 = *p++;
|
|
||||||
prot63 = *p++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* since the str is const, we unescape in another buf */
|
/* since the str is const, we unescape in another buf */
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
block[i] = p[i];
|
block[i] = p[i];
|
||||||
if (prot62 == block[i]) {
|
|
||||||
block[i] = P62;
|
|
||||||
} else if (prot63 == block[i]) {
|
|
||||||
block[i] = P63;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
len = decode_token(block, (unsigned char *) q, slen);
|
len = decode_token(block, (unsigned char *) q, slen);
|
||||||
q += len;
|
q += len;
|
||||||
|
|
|
@ -30,7 +30,7 @@ static struct tuple
|
||||||
char *b;
|
char *b;
|
||||||
} testpairs[] = {
|
} testpairs[] = {
|
||||||
{ "iodinetestingtesting", "Aw8KAw4LDgvZDgLUz2rLC2rPBMC" },
|
{ "iodinetestingtesting", "Aw8KAw4LDgvZDgLUz2rLC2rPBMC" },
|
||||||
{ "abc123", "ywjJmtiZ" },
|
{ "abc1231", "ywjJmtiZmq" },
|
||||||
{
|
{
|
||||||
"\xFF\xEF\x7C\xEF\xAE\x78\xDF\x6D\x74\xCF\x2C\x70\xBE\xEB\x6C\xAE\xAA\x68"
|
"\xFF\xEF\x7C\xEF\xAE\x78\xDF\x6D\x74\xCF\x2C\x70\xBE\xEB\x6C\xAE\xAA\x68"
|
||||||
"\x9E\x69\x64\x8E\x28\x60\x7D\xE7\x5C\x6D\xA6\x58\x5D\x65\x54\x4D\x24\x50"
|
"\x9E\x69\x64\x8E\x28\x60\x7D\xE7\x5C\x6D\xA6\x58\x5D\x65\x54\x4D\x24\x50"
|
||||||
|
@ -41,9 +41,9 @@ static struct tuple
|
||||||
"\xBE\xEB\x6C\xAE\xAA\x68\x9E\x69\x64\x8E\x28\x60\x7D\xE7\x5C\x6D\xA6\x58"
|
"\xBE\xEB\x6C\xAE\xAA\x68\x9E\x69\x64\x8E\x28\x60\x7D\xE7\x5C\x6D\xA6\x58"
|
||||||
"\x5D\x65\x54\x4D\x24\x50\x3C\xE3\x4C\x2C\xA2\x48\x1C\x61\x44\x0C\x20\x40",
|
"\x5D\x65\x54\x4D\x24\x50\x3C\xE3\x4C\x2C\xA2\x48\x1C\x61\x44\x0C\x20\x40",
|
||||||
|
|
||||||
"9abba876543210-ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfe999dcbapZ"
|
"+9876543210-ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcbapZ"
|
||||||
"776543210-ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9abba87654"
|
"776543210-ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba+987654"
|
||||||
"3210-ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfe999dcba"
|
"3210-ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"\xFF\xEF\x7C\xEF\xAE\x78\xDF\x6D\x74\xCF\x2C\x70\xBE\xEB\x6C\xAE\xAA\x68"
|
"\xFF\xEF\x7C\xEF\xAE\x78\xDF\x6D\x74\xCF\x2C\x70\xBE\xEB\x6C\xAE\xAA\x68"
|
||||||
|
@ -55,8 +55,8 @@ static struct tuple
|
||||||
"\xBE\xEB\x6C\xAE\xA1\x61\x91\x61\x61\x81\x28\x60\x7D\xE7\x5C\x6D\xA6\x58"
|
"\xBE\xEB\x6C\xAE\xA1\x61\x91\x61\x61\x81\x28\x60\x7D\xE7\x5C\x6D\xA6\x58"
|
||||||
"\x5D\x65\x54\x4D\x24\x50\x3C\xE3\x4C\x2C\xA2\x48\x1C\x61\x44\x0C\x20\x40",
|
"\x5D\x65\x54\x4D\x24\x50\x3C\xE3\x4C\x2C\xA2\x48\x1C\x61\x44\x0C\x20\x40",
|
||||||
|
|
||||||
"9IJJI876543210-ZYXWVUTSRQPONMLK9LMJIHGFEDCBAzyxwvutsrqponmlkjihgfedcbapZ"
|
"+9876543210-ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcbapZ"
|
||||||
"776543210-ZYXWVUTSRQfHKwfHGsHGFEDCBAzyxwvutsrqponmlkjihgfedcbaML87654321"
|
"776543210-ZYXWVUTSRQfHKwfHGsHGFEDCBAzyxwvutsrqponmlkjihgfedcba+987654321"
|
||||||
"0-ZYXWVUTSRQfHKwfHGsHGFEDCBAzyxwvutsrqponmlkjihgfedcba"
|
"0-ZYXWVUTSRQfHKwfHGsHGFEDCBAzyxwvutsrqponmlkjihgfedcba"
|
||||||
},
|
},
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
|
|
Loading…
Reference in New Issue