From 3a3c89ace2f11591cd91e43d33de9cc3f5233d18 Mon Sep 17 00:00:00 2001 From: Huck Boles Date: Sun, 18 Dec 2022 20:46:53 -0600 Subject: [PATCH] first working base converter --- Makefile | 23 +++++++++------- README.md | 17 +++++++++--- base.h | 11 ++++++++ function.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++ main.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ printbin.c | 59 ----------------------------------------- printbin.h | 8 ------ 7 files changed, 185 insertions(+), 79 deletions(-) create mode 100644 base.h create mode 100644 function.c create mode 100644 main.c delete mode 100644 printbin.c delete mode 100644 printbin.h diff --git a/Makefile b/Makefile index 92c605f..6105579 100644 --- a/Makefile +++ b/Makefile @@ -1,14 +1,19 @@ SHELL = /bin/bash -PROG = printbin +PROG = base +PREFIX = /usr +DESTDIR = /bin -debug: - gcc *.c *.h -Wall -lm -g -o printbin +CFILE = main.c function.c +HEADER = base.h -printbin: - gcc *.c *.h -Wall -lm -o printbin +header: ${HEADER} + gcc ${CFILE} ${HEADER} -lm -Wall -o ${PROG} -install: - gcc *.c *.h -Wall -lm -o /home/huck/.local/bin/printbin +install: ${CFILE} ${HEADER} + gcc ${CFILE} ${HEADER} -lm -Wall -o ${PREFIX}${DESTDIR}/${PROG} -clean: - rm /home/huck/.local/bin/printbin +debug: ${CFILE} + gcc ${CFILE} -lm -Wall -g -o ${PROG} + +clean: + rm ${PREFIX}${DESTDIR}/${PROG} diff --git a/README.md b/README.md index 70d6485..13784e7 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,18 @@ printbin - A quick utility to print a number in it's binary representation. Usage: + + Print binary representation: + $ printbin 555 + |> Print a 16 bit representation: - $ printbin -b 16 1234 + $ printbin -b 16 -n 1234 |> 00000100 11010010 Print an 8 bit representation of a base 16 number - $ printbin -b 8 -a 16 5a + $ printbin -b 8 -a 16 -n 5a |> 01011010 Accept input and output binary number; @@ -16,4 +20,11 @@ Usage: > 333 |> 00000000 00000000 00000000 00000000 00000000 00000000 00000001 01001101 -printbin always prints a base 10 number up to 64 bits, unless the number of bits is set with -b, or the base is set with -a. +printbin always prints a base 10 number up to 64 bits, unless the number of bits is set with -b, or the base is set with -a, if base or bits are specified, the number must be proceeded by -n. + +Installation (installs to /usr/bin by default): + + $ git clone "https://git.huck.website/huboles/printbin.git" + $ cd printbin + $ sudo make clean install + diff --git a/base.h b/base.h new file mode 100644 index 0000000..5aadfc0 --- /dev/null +++ b/base.h @@ -0,0 +1,11 @@ +#include +#include +#include +#include +#include + +void printbin(int, int); +void printnum(char *, int, int, int); +void printbase(int, int); +int getnum(char *, int); + diff --git a/function.c b/function.c new file mode 100644 index 0000000..8010959 --- /dev/null +++ b/function.c @@ -0,0 +1,69 @@ +#include "base.h" + +/* enumerate up to base 64 */ +static char digits[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + +void printnum(char *bin, int ibase, int obase, int len){ + + int out = getnum(bin,ibase); + + switch (obase) { + case (16): + printf("0x%x\n", out); + break; + case (10): + printf("%i\n", out); + break; + case (8): + printf("%o\n", out); + break; + case (2): + printbin(out,len); + break; + default: + printbase(out,obase); + break; + } +} + +void printbase(int num, int base){ + int n = 0; + char *s = malloc(100*sizeof(char)); + while (num > 0){ + s[n++] = digits[num%base]; + num /= base; + } + for (int i = n - 1; i >= 0; i--){ + printf("%c",s[i]); + printf("%s",(i%3==0) ? " " : ""); + } + printf("\n"); +} + +void printbin(int i, int n){ + unsigned long mask = pow(2,n-1); + + for (int t = n-1; t >= 0; t-- ){ + printf("%i",((i & mask) == 0) ? 0 : 1); + printf("%s",(t % 8 == 0) ? " " : ""); + mask = mask >> 1; + } + printf("\n"); + +} + +int getnum(char *num, int base){ + int out = 0; + int j = strlen(num) - 1; + + for (int i = 0; i < strlen(num); i++ ){ + /* get pointer to char in digit index */ + char *c = strchr(digits,num[i]); + /* gets int by finding offset in pointer values */ + int offset = c - digits; + int mag = pow(base,j--); + out += (mag * offset); + } + + return out; +} diff --git a/main.c b/main.c new file mode 100644 index 0000000..1309614 --- /dev/null +++ b/main.c @@ -0,0 +1,77 @@ +#include "base.h" + +void help(void); + +int main(int argc, char *argv[]){ + char *l = malloc(20*sizeof(char)); + char *i = malloc(20*sizeof(char)); + char *o = malloc(20*sizeof(char)); + char *n = malloc(60*sizeof(char)); + char c; + int len,ibase,obase; + + /* print stdin in binary if called alone */ + if (argc == 1) { + scanf("%s",n); + printbin(strtol(n, NULL, 10),64); + return 0; + /* print base 10 number in binary if given with no arguments */ + } else if (argc == 2) { + printbin(strtol(argv[1],NULL,10),64); + return 0; + } else { + while ((c = getopt (argc, argv, "ho:i:l:n:")) != -1){ + switch (c) { + case 'h': + help(); + return 0; + case 'l': + strcpy(l,optarg); + break; + case 'i': + strcpy(i,optarg); + break; + case 'o': + strcpy(o,optarg); + break; + case 'n': + strcpy(n,optarg); + break; + } + } + } + + /* get number from unassigned argv or stdin if it isnt set already */ + if ((strcmp(n,"") == 0) && argv[optind]) strcpy(n,argv[optind]); + if (strcmp(n,"") == 0) scanf("%s",n); + + if (strcmp(i,"") != 0) { + ibase = strtol(i,NULL,10); + } else { + ibase = 10; + } + + if (strcmp(o,"") != 0) { + obase = strtol(o,NULL,10); + } else { + obase = 2; + } + + if (strcmp(l,"") != 0) { + len = strtol(l,NULL,10); + } else { + len = 64; + } + + printnum(n,ibase,obase,len); + return 0; +} + +void help(void){ + printf("OPTIONS:\n"); + printf("\t-n number to convert (takes stdin if not specified)\n"); + printf("\t-i input base (10 if not specified)\n"); + printf("\t-o output base (2 if not specified)\n"); + printf("\t-l number of digits to print\n"); +} + diff --git a/printbin.c b/printbin.c deleted file mode 100644 index e0c1261..0000000 --- a/printbin.c +++ /dev/null @@ -1,59 +0,0 @@ -#include "printbin.h" - -int main(int argc, char *argv[]){ - char *a = malloc(20*sizeof(char)); - char *b = malloc(20*sizeof(char)); - char *n = malloc(60*sizeof(char)); - char c; - unsigned long num; - int bits,base; - int x = 0; - - while ((c = getopt (argc, argv, "a:b:")) != -1){ - switch (c) { - /* number base */ - case 'a': - strcpy(a,optarg); - x++; - break; - /* number bits */ - case 'b': - strcpy(b,optarg); - x++; - break; - } - } - - if (x != 0 && argc > 1) strcpy(n,argv[optind]); - if (strcmp(n,"") == 0) scanf("%s",n); - - if (strcmp(a,"") != 0) { - base = strtol(a,NULL,10); - } else { - base = 10; - } - - if (strcmp(b,"") != 0) { - bits = strtol(b,NULL,10); - } else { - bits = 64; - } - - num = strtol(n,NULL,base); - - printbin(num,bits); - return 0; -} - -void printbin(unsigned long i, int n){ - unsigned long mask = pow(2,n-1); - - for (int t = n-1; t >= 0; t-- ){ - printf("%i",((i & mask) == 0) ? 0 : 1); - printf("%s",(t % 8 == 0) ? " " : ""); - mask = mask >> 1; - } - printf("\n"); - -} - diff --git a/printbin.h b/printbin.h deleted file mode 100644 index 5cf0452..0000000 --- a/printbin.h +++ /dev/null @@ -1,8 +0,0 @@ -#include -#include -#include -#include -#include - -void printbin(unsigned long, int); -unsigned long getnum (int argc, char **argv); -- 2.45.2