endrilo

Implementation of the endrilo cipher in c
git clone git://git.noxz.tech/endrilo
Log | Files | Refs

commit 2a71881538c0c43d7c247221569262899280fdd4
Author: Chris Noxz <chris@noxz.tech>
Date:   Thu, 27 Feb 2020 21:01:15 +0100

initial commit

Diffstat:
A.gitignore | 2++
AMakefile | 37+++++++++++++++++++++++++++++++++++++
Aconfig.mk | 8++++++++
Aendrilo.c | 134+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 181 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -0,0 +1,2 @@ +endrilo +endrilo.o diff --git a/Makefile b/Makefile @@ -0,0 +1,37 @@ +.POSIX: + +include config.mk + +SRC = endrilo.c +OBJ = $(SRC:.c=.o) + +all: options endrilo + +options: + @echo endrilo build options: + @echo "VERSION = $(VERSION)" + @echo "PREFIX = $(PREFIX)" + @echo "CFLAGS = $(STCFLAGS)" + @echo "CC = $(CC)" + +.c.o: + $(CC) $(STCFLAGS) -c $< + +$(OBJ): config.mk + +endrilo: $(OBJ) + $(CC) -o $@ $(OBJ) $(STCFLAGS) + +clean: + rm -f endrilo $(OBJ) + +install: endrilo + @echo installing executable to ${PREFIX}/bin + mkdir -p $(PREFIX)/bin + cp -f endrilo $(PREFIX)/bin + chmod 755 $(PREFIX)/bin/endrilo + +uninstall: + rm -f $(PREFIX)/bin/endrilo + +.PHONY: all options clean install uninstall diff --git a/config.mk b/config.mk @@ -0,0 +1,8 @@ +VERSION = 0.0.1 + +PREFIX = /usr/local +MANPREFIX = $(PREFIX)/share/man + +CFLAGS = -Wall -pedantic -std=c99 +CPPFLAGS = -DVERSION=\"$(VERSION)\" -D_DEFAULT_SOURCE -D_XOPEN_SOURCE=600 +STCFLAGS = $(CPPFLAGS) $(CFLAGS) diff --git a/endrilo.c b/endrilo.c @@ -0,0 +1,134 @@ +#include <stdlib.h> +#include <stdio.h> +#include <getopt.h> + +static void print_octet(char, int, char); +static void print_char(char, char, char); +static void encode(void); +static void decode(void); + +static const char *usage = "usage: endrilo [-dh]"; +static char working_char = 0; +static char working_bit = 0; + +void +print_octet(char octet, int o, char last) +{ + int i; + + for (i = 0; i < 3; i++) { + if (1U & (octet >> (i % 8))) + working_char |= 1U << ((o * 3 + i) % 8); + if ((o * 3 + i) % 8 == 7 || (i == 2 && last)) { + fputc(working_char, stdout); + working_char = 0; + } + } +} + +void +print_char(char count, char zero, char last) +{ + int i; + + for (i = 0; i < count; i++) { + if (!zero) + working_char |= 1U << working_bit; + if (working_bit++ == 7 || (i + 1 == count && last)) { + fputc(working_char, stdout); + working_char = 0; + working_bit = 0; + } + } +} + +void +encode(void) +{ + char input = 0; + char current = 0; + char last = 0; + int b, /* bit counter */ + o, /* octet counter */ + s; /* succession counter */ + + for (b = 0, o = 0, s = 0;; s++, b++) { + if (b == 8 || b == 0) { + input = fgetc(stdin); + + /* last character, so print what's left */ + if (feof(stdin)) { + print_octet(s, o++, 1); + break; + } + } + current = 1U & (input >> (b % 8)); + + if (current != last) { + do { + if (s > 7) { + print_octet(7, o++, 0); + print_octet(0, o++, 0); + } else { + print_octet(s, o++, 0); + } + s -= 7; + } while (s > 0); + last = current; + s = 0; + } + + /* circulate counters */ + if (o >= 8) + o %= 8; + if (b == 8) + b = 0; + } +} + +void +decode(void) +{ + char input = 0; + char current = 0; + char eof = 0; + int b, /* bit counter */ + o; /* octet counter */ + + for (o = 0; !eof; current = 0, o++) { + for (b = 0; b < 3; b++) { + if ((o * 3 + b) % 8 == 0) { + input = fgetc(stdin); + if (feof(stdin)) { + eof = 1; + break; + } + } + current |= (1U & (input >> ((o * 3 + b) % 8))) << b; + } + print_char(current, o % 2 == 0, eof); + + /* circulate counters */ + if (o == 8) + o = 0; + } +} + +int +main(int argc, char *argv[]) +{ + char c; + int doencode = 1; + + while ((c = getopt(argc, argv, "dh")) != -1) { + switch (c) { + case 'd': doencode = 0; break; + case 'h': printf(usage); exit(0); break; + } + } + + if (doencode) + encode(); + else + decode(); +}