endrilo

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

commit: 2a71881538c0c43d7c247221569262899280fdd4
parent: 
author: Chris Noxz <chris@noxz.tech>
date:   Thu, 27 Feb 2020 21:01:15 +0100
initial commit
A.gitignore2+
AMakefile37++++++
Aconfig.mk8++
Aendrilo.c134++++++++++++++++++++
4 files changed, 181 insertions(+)
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();
+}