Compare commits

..

9 commits
v0.2 ... main

Author SHA1 Message Date
Eric
aacf2324c7 improve decode time
atob() has been replaced with a lookup table, removing previous
conditionals and function calls necessary to decode.
2025-05-29 16:02:45 +02:00
Eric
debab62506 remove getsxts for better function readb
Decoding input is read faster now.
With this, all options have been tuned to a reasonable degree.
2025-05-29 13:48:49 +02:00
Eric
0a4a98390d improve printw to write faster
Now all encoding options are faster.
2025-05-29 00:51:00 +02:00
Eric
f0577d8ea0 decrease encode time
The functions encode and decode are now capable of processing larger
buffers with less conditional logic. Input and output functions need to
follow suit to make better use of this next. Encode without line
wrapping already makes use of these improvements, because input and
output are now entirely handled by <stdio.h> functions.
2025-05-28 23:24:05 +02:00
Eric
3194981825 repair Makefile to include -g in CFLAGS again 2025-05-28 20:33:16 +02:00
Eric
4e8bb86ddd change Makefile to be stricter
-Og enables better detection of bugs that would only occur in optimized
compilations and allows for slightly lesser than -O1 optimization that
does not interfere with debugging.
2025-05-28 17:55:13 +02:00
Eric
733a013ee7 remove bugs related to uninitialized variables
These bugs became visible when using optimization options. They were
either not present unoptimized or very unlikely to occur. However, given
the options, the resulting program would behave incorrectly and reliably
break under all circumstances.

The makefile will see the intended changes accordingly in the following
commit to ensure compatibility.
2025-05-28 17:31:07 +02:00
Eric
fa5095133a remove buffer size dependency from input functions
This should've been part of 848c37, when buffers were unwired from input
functions. Now buffer size is also no longer supplied in function calls
but assumed. It is up to the caller to provide appropriately sized
buffers.
2025-05-27 18:37:48 +02:00
Eric
b76c50a91b change header macro names to be more idiomatic 2025-05-27 15:14:55 +02:00
8 changed files with 158 additions and 132 deletions

View file

@ -1,13 +1,14 @@
CFLAGS = -g -Wall -Wextra -Werror
CC = gcc
CFLAGS = -Og -g -Wall -Wextra -Werror
objects = main.o input.o output.o encode.o
b64 : $(objects)
cc -o b64 $(objects)
$(CC) -o b64 $(objects)
main.o input.o : input.h
main.o output.o : output.h
main.o encode.o : encode.h
main.o output.o : output.h
.PHONY : clean
clean :

149
encode.c
View file

@ -2,99 +2,106 @@
#define PADDING '='
unsigned char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
"abcdefghijklmnopqrstuvwxyz" \
"0123456789" \
"+/";
static
unsigned char b64toascii[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
"abcdefghijklmnopqrstuvwxyz" \
"0123456789" \
"+/";
static
unsigned char b64urltoascii[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
"abcdefghijklmnopqrstuvwxyz" \
"0123456789" \
"-_";
static
unsigned char asciitob64[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 62, 0, 62, 0, 63, 52, 53,
54, 55, 56, 57, 58, 59, 60, 61, 0, 0,
0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 63, 0, 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
};
unsigned char b64u[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
"abcdefghijklmnopqrstuvwxyz" \
"0123456789" \
"-_";
int
encode(unsigned char *op, int olen, unsigned char *sp, int url)
{
int n;
unsigned char *sb, *enc;
int tmp;
unsigned char *table;
unsigned char *sbeg;
unsigned char *tend;
sb = sp;
enc = (!url) ? b64 : b64u;
switch (olen) {
case 3:
*sp++ = enc[(*op & ~3) >> 2];
n = (*op++ & 3) << 4;
*sp++ = enc[n + ((*op & ~15) >> 4)];
n = (*op++ & 15) << 2;
*sp++ = enc[n + ((*op & 192) >> 6)];
*sp = enc[*op & ~192];
break;
table = (!url) ? b64toascii : b64urltoascii;
sbeg = sp;
tend = op + olen - (olen % 3);
while (op < tend) {
*sp++ = table[(*op & ~3) >> 2];
tmp = (*op++ & 3) << 4;
*sp++ = table[tmp + ((*op & ~15) >> 4)];
tmp = (*op++ & 15) << 2;
*sp++ = table[tmp + ((*op & 192) >> 6)];
*sp++ = table[*op++ & ~192];
}
switch (olen % 3) {
case 2:
*sp++ = enc[(*op & ~3) >> 2];
n = (*op++ & 3) << 4;
*sp++ = enc[n + ((*op & ~15) >> 4)];
*sp++ = enc[(*op & 15) << 2];
*sp = PADDING;
*sp++ = table[(*op & ~3) >> 2];
tmp = (*op++ & 3) << 4;
*sp++ = table[tmp + ((*op & ~15) >> 4)];
*sp++ = table[(*op & 15) << 2];
*sp++ = PADDING;
break;
case 1:
*sp++ = enc[(*op & ~3) >> 2];
*sp++ = enc[(*op & 3) << 4];
*sp++ = table[(*op & ~3) >> 2];
*sp++ = table[(*op & 3) << 4];
*sp++ = PADDING;
*sp++ = PADDING;
*sp = PADDING;
break;
}
return sp-sb+1;
return sp-sbeg;
}
int
decode(unsigned char *sp, int slen, unsigned char *op, int url)
decode(unsigned char *sp, int slen, unsigned char *op)
{
int n, b, atob(int c, int url);
unsigned char *ob;
int tmp, b;
unsigned char *obeg;
unsigned char *qend;
ob = op;
switch (slen) {
case 4:
n = atob(*sp++, url) << 2;
b = atob(*sp++, url);
*op++ = n + ((b & ~15) >> 4);
n = (b & 15) << 4;
b = atob(*sp++, url);
*op++ = n + ((b & ~3) >> 2);
*op = ((b & 3) << 6) + atob(*sp, url);
break;
obeg = op;
qend = sp + slen - (slen % 4);
while (sp < qend) {
tmp = asciitob64[*sp++] << 2;
b = asciitob64[*sp++];
*op++ = tmp + ((b & ~15) >> 4);
tmp = (b & 15) << 4;
b = asciitob64[*sp++];
*op++ = tmp + ((b & ~3) >> 2);
*op++ = ((b & 3) << 6) + asciitob64[*sp++];
}
switch (slen % 4) {
case 3:
n = atob(*sp++, url) << 2;
b = atob(*sp++, url);
*op++ = n + ((b & ~15) >> 4);
n = (b & 15) << 4;
*op = n + ((atob(*sp, url) & ~3) >> 2);
tmp = asciitob64[*sp++] << 2;
b = asciitob64[*sp++];
*op++ = tmp + ((b & ~15) >> 4);
tmp = (b & 15) << 4;
*op++ = tmp + ((asciitob64[*sp++] & ~3) >> 2);
break;
case 2:
n = atob(*sp++, url) << 2;
*op = n + ((atob(*sp, url) & ~15) >> 4);
tmp = asciitob64[*sp++] << 2;
*op++ = tmp + ((asciitob64[*sp++] & ~15) >> 4);
break;
}
return op-ob+1;
}
int atob(int c, int url)
{
if (c >= 'A' && c <= 'Z')
c -= 'A';
else if (c >= 'a' && c <= 'z')
c = c - 'a' + 26;
else if (c >= '0' && c <= '9')
c = c - '0' + 26 * 2;
else if (c == ((!url) ? '+' : '-'))
c = 62;
else
c = 63;
return c;
return op-obeg;
}

View file

@ -1,10 +1,10 @@
#ifndef HEADER_ENCODE
#define HEADER_ENCODE
#ifndef ENCODE_H
#define ENCODE_H
int
encode(unsigned char *op, int olen, unsigned char *sp, int url);
int
decode(unsigned char *sp, int slen, unsigned char *op, int url);
decode(unsigned char *sp, int slen, unsigned char *op);
#endif

43
input.c
View file

@ -1,30 +1,29 @@
#include "input.h"
#define PADDING '='
#define PADDING '='
int
getocts(FILE *fp, unsigned char *o, int olen)
readb(FILE *fp, unsigned char *s, int slen)
{
int c, n;
int read, tread;
unsigned char *send, *sbeg;
unsigned char *l, *r;
n = 0;
while (n < olen-1 && (c = fgetc(fp)) != EOF)
o[n++] = c;
read = tread = 0;
sbeg = l = r = s;
while (tread < slen && (read = fread(l, sizeof(*l), slen-tread, fp))) {
tread += read;
send = s + tread;
for (r = l; r < send; ++r)
if (*r != '\n')
*l++ = *r;
tread -= r - l;
if (l > sbeg) {
for (--l; *l == PADDING; --l)
;
++l;
}
}
return n;
}
int
getsxts(FILE *fp, unsigned char *s, int slen)
{
int c, n, pad;
n = pad = 0;
while (n < slen-1 && (c = fgetc(fp)) != EOF && c != PADDING)
if (c != '\n')
s[n++] = c;
while (n+pad < slen-1)
s[n+pad++] = PADDING;
return n;
return l-sbeg;
}

View file

@ -1,12 +1,9 @@
#ifndef HEADER_INPUT
#define HEADER_INPUT
#ifndef INPUT_H
#define INPUT_H
#include <stdio.h>
int
getocts(FILE *fp, unsigned char *o, int olen);
int
getsxts(FILE *fp, unsigned char *s, int slen);
readb(FILE *fp, unsigned char *s, int slen);
#endif

41
main.c
View file

@ -4,20 +4,21 @@
#include "output.h"
#include "encode.h"
#define OBUFSIZE 4
#define SBUFSIZE 5
#define OCTETBUF 1500
#define SXTETBUF 2000
unsigned char obuf[OBUFSIZE];
unsigned char sbuf[SBUFSIZE];
unsigned char obuf[OCTETBUF];
unsigned char sbuf[SXTETBUF];
int
main(int argc, char *argv[])
{
int c, n, l;
int c, n, last;
int dec, url, hlp, wrp;
char *prog = *argv;
FILE *in, *out;
char *prog;
prog = *argv;
dec = url = hlp = wrp = 0;
while (--argc > 0 && (*++argv)[0] == '-')
while ((c = *++argv[0]))
@ -42,6 +43,7 @@ main(int argc, char *argv[])
if (hlp) {
fprintf(stdout, "Usage: %s -duhw infile outfile\n", prog);
} else {
in = out = NULL;
if (argc >= 1 && (in = fopen(*argv, "r")) == NULL) {
fprintf(stderr, "%s: can't open %s\n", prog, *argv);
exit(EXIT_FAILURE);
@ -51,22 +53,23 @@ main(int argc, char *argv[])
exit(EXIT_FAILURE);
}
if (dec) {
while ((n = getsxts((argc >= 1) ? in : stdin, sbuf, SBUFSIZE))) {
n = decode(sbuf, n, obuf, url);
fwrite(obuf, sizeof(*obuf), n, (argc == 2) ? out : stdout);
while ((n = readb((in) ? in : stdin, sbuf, SXTETBUF))) {
n = decode(sbuf, n, obuf);
fwrite(obuf, sizeof(*obuf), n, (out) ? out : stdout);
}
} else if (wrp) {
last = 0;
while ((n = fread(obuf, sizeof(*obuf), OCTETBUF, (in) ? in : stdin))) {
n = encode(obuf, n, sbuf, url);
last = printw((out) ? out : stdout, sbuf, n);
}
if (last != '\n')
fprintf((out) ? out : stdout, "\n");
} else {
while ((n = getocts((argc >= 1) ? in : stdin, obuf, OBUFSIZE))) {
if (wrp) {
n = encode(obuf, n, sbuf, url);
l = printw((argc == 2) ? out : stdout, sbuf, n);
} else {
encode(obuf, n, sbuf, url);
fprintf((argc == 2) ? out : stdout, "%s", sbuf);
}
while ((n = fread(obuf, sizeof(*obuf), OCTETBUF, (in) ? in : stdin))) {
n = encode(obuf, n, sbuf, url);
fwrite(sbuf, sizeof(*sbuf), n, (out) ? out : stdout);
}
if (wrp && l != '\n')
fprintf((argc == 2) ? out : stdout, "\n");
}
if (in)
fclose(in);

View file

@ -8,11 +8,30 @@ printw(FILE *fp, unsigned char *s, int slen)
static int col;
int c;
while (slen--) {
fputc((c = *s++), fp);
++col;
if (!(col %= WRAPCOL))
fputc((c = '\n'), fp);
c = '\n';
if (col) {
if (slen >= WRAPCOL-col) {
fwrite(s, sizeof(*s), WRAPCOL-col, fp);
s += WRAPCOL-col;
slen -= WRAPCOL-col;
col = 0;
fputc('\n', fp);
} else {
fwrite(s, sizeof(*s), slen, fp);
s += slen;
col += slen;
slen -= slen;
c = *(s+slen-1);
}
}
for (; slen >= WRAPCOL; slen -= WRAPCOL, s += WRAPCOL) {
fwrite(s, sizeof(*s), WRAPCOL, fp);
fputc('\n', fp);
}
if (slen > 0) {
fwrite(s, sizeof(*s), slen, fp);
col += slen;
c = *(s+slen-1);
}
return c;

View file

@ -1,5 +1,5 @@
#ifndef HEADER_OUTPUT
#define HEADER_OUTPUT
#ifndef OUTPUT_H
#define OUTPUT_H
#include <stdio.h>