Skip to content

Commit

Permalink
Backport the word64 support for encode/decode
Browse files Browse the repository at this point in the history
  • Loading branch information
bogdan-iancu committed Aug 31, 2018
1 parent 107e1f6 commit c245e77
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 1 deletion.
121 changes: 120 additions & 1 deletion ut.c
Expand Up @@ -195,6 +195,9 @@ int parse_reply_codes( str *options_reply_codes_str,
static const char base64digits[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

static const char word64digits[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+.";

#define BAD ((unsigned char)-1)
static const unsigned char base64val[] = {
BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD,
Expand All @@ -204,10 +207,39 @@ BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD, 62, BAD,BAD,BAD, 63,
BAD, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,BAD, BAD,BAD,BAD,BAD,
BAD, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,BAD, BAD,BAD,BAD,BAD
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,BAD, BAD,BAD,BAD,BAD,

BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD,
BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD,
BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD,
BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD,
BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD,
BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD,
BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD,
BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD
};
#define DECODE64(c) (isascii(c) ? base64val[c] : BAD)

static const unsigned char word64val[] = {
BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD,
BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD,
BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD, 62, BAD,BAD, 63,BAD,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61,BAD,BAD, BAD,BAD,BAD,BAD,
BAD, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,BAD, BAD,BAD,BAD,BAD,
BAD, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,BAD, BAD,BAD,BAD,BAD,

BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD,
BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD,
BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD,
BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD,
BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD,
BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD,
BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD,
BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD
};


/* function that encodes to base64
* output buffer is assumed to have the right length */
Expand Down Expand Up @@ -239,6 +271,35 @@ void base64encode(unsigned char *out, unsigned char *in, int inlen)
}
}

/* function that encodes to word64
* output buffer is assumed to have the right length */
void word64encode(unsigned char *out, unsigned char *in, int inlen)
{
for (; inlen >= 3; inlen -= 3)
{
*out++ = word64digits[in[0] >> 2];
*out++ = word64digits[((in[0] << 4) & 0x30) | (in[1] >> 4)];
*out++ = word64digits[((in[1] << 2) & 0x3c) | (in[2] >> 6)];
*out++ = word64digits[in[2] & 0x3f];
in += 3;
}

if (inlen > 0)
{
unsigned char fragment;

*out++ = word64digits[in[0] >> 2];
fragment = (in[0] << 4) & 0x30;

if (inlen > 1)
fragment |= in[1] >> 4;

*out++ = word64digits[fragment];
*out++ = (inlen < 2) ? '-' : word64digits[(in[1] << 2) & 0x3c];
*out++ = '-';
}
}

/* function that decodes from base64
* output buffer is assumed to have the right length */
int base64decode(unsigned char *out,unsigned char *in,int len)
Expand Down Expand Up @@ -298,3 +359,61 @@ int base64decode(unsigned char *out,unsigned char *in,int len)
return out_len;
}

/* function that decodes from word64
* output buffer is assumed to have the right length */
int word64decode(unsigned char *out, unsigned char *in, int len)
{
int i=0;
unsigned char c1,c2,c3,c4;
int out_len=0;

while (len > i)
{
do
{
c1 = word64val[in[i++]];
} while (i<len && c1 == BAD);

if (c1 == BAD)
break;

do
{
c2 = word64val[in[i++]];
} while (i<len && c2 == BAD);

if (c2 == BAD)
break;

out[out_len++] = (c1 << 2) | ((c2 & 0x30) >> 4);

do
{
c3 = in[i++];
if (c3 == 61)
return out_len;

c3 = word64val[c3];
} while (i<len && c3 == BAD);

if (c3 == BAD)
break;

out[out_len++] = ((c2 & 0x0f) << 4) | ((c3 & 0x3c) >> 2);

do
{
c4 = in[i++];
if (c4 == 61)
return out_len;
c4 = word64val[c4];
} while (i<len && c4 == BAD);

if (c4 == BAD)
break;

out[out_len++] = ((c3 & 0x03) << 6) | c4;
}

return out_len;
}
11 changes: 11 additions & 0 deletions ut.h
Expand Up @@ -998,15 +998,26 @@ int parse_reply_codes( str *options_reply_codes_str,
void base64encode(unsigned char *out, unsigned char *in, int inlen);
int base64decode(unsigned char *out,unsigned char *in,int len);

/*
* "word64" is a combination between:
* - RFC 3261-compatible "word" token characters
* - modulo-64 encoding of base64
*/
void word64encode(unsigned char *out, unsigned char *in, int inlen);
int word64decode(unsigned char *out, unsigned char *in, int len);

static inline int calc_base64_encode_len(int len)
{
return (len/3 + (len%3?1:0))*4;
}
#define calc_word64_encode_len calc_base64_encode_len

static inline int calc_max_base64_decode_len(int len)
{
return len*3/4;
}

#define calc_max_word64_decode_len calc_max_base64_decode_len


#endif

0 comments on commit c245e77

Please sign in to comment.