From a91be306b1fbe2534f9d8c8ceb7b143042fb1083 Mon Sep 17 00:00:00 2001 From: Eric Date: Mon, 26 May 2025 23:59:47 +0200 Subject: [PATCH] add base64url encoding option --- encode.c | 54 ++++++++++++++++++++++++++++++------------------------ encode.h | 4 ++-- main.c | 11 +++++++---- 3 files changed, 39 insertions(+), 30 deletions(-) diff --git a/encode.c b/encode.c index 576f9f3..cee611f 100644 --- a/encode.c +++ b/encode.c @@ -7,32 +7,38 @@ unsigned char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ "0123456789" \ "+/"; +unsigned char b64u[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ + "abcdefghijklmnopqrstuvwxyz" \ + "0123456789" \ + "-_"; + int -encode(unsigned char *op, int olen, unsigned char *sp) +encode(unsigned char *op, int olen, unsigned char *sp, int url) { int n; - unsigned char *sb; + unsigned char *sb, *enc; sb = sp; + enc = (!url) ? b64 : b64u; switch (olen) { case 3: - *sp++ = b64[(*op & ~3) >> 2]; + *sp++ = enc[(*op & ~3) >> 2]; n = (*op++ & 3) << 4; - *sp++ = b64[n + ((*op & ~15) >> 4)]; + *sp++ = enc[n + ((*op & ~15) >> 4)]; n = (*op++ & 15) << 2; - *sp++ = b64[n + ((*op & 192) >> 6)]; - *sp = b64[*op & ~192]; + *sp++ = enc[n + ((*op & 192) >> 6)]; + *sp = enc[*op & ~192]; break; case 2: - *sp++ = b64[(*op & ~3) >> 2]; + *sp++ = enc[(*op & ~3) >> 2]; n = (*op++ & 3) << 4; - *sp++ = b64[n + ((*op & ~15) >> 4)]; - *sp++ = b64[(*op & 15) << 2]; + *sp++ = enc[n + ((*op & ~15) >> 4)]; + *sp++ = enc[(*op & 15) << 2]; *sp = PADDING; break; case 1: - *sp++ = b64[(*op & ~3) >> 2]; - *sp++ = b64[(*op & 3) << 4]; + *sp++ = enc[(*op & ~3) >> 2]; + *sp++ = enc[(*op & 3) << 4]; *sp++ = PADDING; *sp = PADDING; break; @@ -42,42 +48,42 @@ encode(unsigned char *op, int olen, unsigned char *sp) } int -decode(unsigned char *sp, int slen, unsigned char *op) +decode(unsigned char *sp, int slen, unsigned char *op, int url) { - int n, b, atob(int c); + int n, b, atob(int c, int url); unsigned char *ob; ob = op; switch (slen) { case 4: - n = atob(*sp++) << 2; - b = atob(*sp++); + n = atob(*sp++, url) << 2; + b = atob(*sp++, url); *op++ = n + ((b & ~15) >> 4); n = (b & 15) << 4; - b = atob(*sp++); + b = atob(*sp++, url); *op++ = n + ((b & ~3) >> 2); - *op = ((b & 3) << 6) + atob(*sp); + *op = ((b & 3) << 6) + atob(*sp, url); break; case 3: - n = atob(*sp++) << 2; - b = atob(*sp++); + n = atob(*sp++, url) << 2; + b = atob(*sp++, url); *op++ = n + ((b & ~15) >> 4); n = (b & 15) << 4; - *op = n + ((atob(*sp) & ~3) >> 2); + *op = n + ((atob(*sp, url) & ~3) >> 2); break; case 2: - n = atob(*sp++) << 2; - *op = n + ((atob(*sp) & ~15) >> 4); + n = atob(*sp++, url) << 2; + *op = n + ((atob(*sp, url) & ~15) >> 4); break; } return op-ob+1; } -int atob(int c) +int atob(int c, int url) { if (c >= 'A' && c <= 'Z') c -= 'A'; @@ -85,7 +91,7 @@ int atob(int c) c = c - 'a' + 26; else if (c >= '0' && c <= '9') c = c - '0' + 26 * 2; - else if (c == '+') + else if (c == ((!url) ? '+' : '-')) c = 62; else c = 63; diff --git a/encode.h b/encode.h index f211396..2ea285a 100644 --- a/encode.h +++ b/encode.h @@ -2,9 +2,9 @@ #define HEADER_ENCODE int -encode(unsigned char *op, int olen, unsigned char *sp); +encode(unsigned char *op, int olen, unsigned char *sp, int url); int -decode(unsigned char *sp, int slen, unsigned char *op); +decode(unsigned char *sp, int slen, unsigned char *op, int url); #endif diff --git a/main.c b/main.c index ff16bf6..b48684c 100644 --- a/main.c +++ b/main.c @@ -12,17 +12,20 @@ unsigned char sbuf[SBUFSIZE]; int main(int argc, char *argv[]) { - int c, n, dec, hlp; + int c, n, dec, url, hlp; char *prog = *argv; FILE *in, *out; - dec = hlp = 0; + dec = url = hlp = 0; while (--argc > 0 && (*++argv)[0] == '-') while ((c = *++argv[0])) switch (c) { case 'd': dec = 1; break; + case 'u': + url = 1; + break; case 'h': hlp = 1; break; @@ -44,12 +47,12 @@ main(int argc, char *argv[]) } if (dec) { while ((n = getsxts((argc >= 1) ? in : stdin, sbuf, SBUFSIZE))) { - n = decode(sbuf, n, obuf); + n = decode(sbuf, n, obuf, url); fwrite(obuf, sizeof(*obuf), n, (argc == 2) ? out : stdout); } } else { while ((n = getocts((argc >= 1) ? in : stdin, obuf, OBUFSIZE))) { - encode(obuf, n, sbuf); + encode(obuf, n, sbuf, url); fprintf((argc == 2) ? out : stdout, "%s", sbuf); } }