commit 047b8ec51537e095f226ffd7428975a1ad973594
Author: Remy Noulin <loader2x@gmail.com>
Date: Sat, 2 Nov 2019 11:26:17 +0100
base64 encode and decode
.gitignore | 63 +++++++++++++++++++++
base64.c | 183 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
base64.h | 9 +++
demo.c | 51 +++++++++++++++++
package.yml | 30 ++++++++++
5 files changed, 336 insertions(+)
Diffstat:
| A | .gitignore | | | 63 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | base64.c | | | 183 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | base64.h | | | 9 | +++++++++ |
| A | demo.c | | | 51 | +++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | package.yml | | | 30 | ++++++++++++++++++++++++++++++ |
5 files changed, 336 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1,63 @@
+# Vim
+*.sw*
+
+# Debug
+.gdb_history
+
+# Coverage
+*.gcov
+*.gcda
+*.gcno
+
+# Prerequisites
+*.d
+
+# Object files
+*.o
+*.ko
+*.obj
+*.elf
+
+# Linker output
+*.ilk
+*.map
+*.exp
+
+# Precompiled Headers
+*.gch
+*.pch
+
+# Libraries
+*.lib
+*.a
+*.la
+*.lo
+
+# Shared objects (inc. Windows DLLs)
+*.dll
+*.so
+*.so.*
+*.dylib
+
+# Executables
+*.exe
+*.out
+*.app
+*.i*86
+*.x86_64
+*.hex
+
+# Debug files
+*.dSYM/
+*.su
+*.idb
+*.pdb
+
+# Kernel Module Compile Results
+*.mod*
+*.cmd
+.tmp_versions/
+modules.order
+Module.symvers
+Mkfile.old
+dkms.conf
diff --git a/base64.c b/base64.c
@@ -0,0 +1,183 @@
+#include <string.h>
+#include <stdlib.h>
+
+int base64_encode(unsigned char *source, size_t sourcelen, char *target, size_t targetlen);
+size_t base64_encode_size(size_t sourcelen);
+void _base64_encode_triple(unsigned char triple[3], char result[4]);
+int _base64_char_value(char base64char);
+int _base64_decode_triple(char quadruple[4], unsigned char *result);
+size_t base64_decode(char *source, unsigned char *target, size_t targetlen);
+size_t base64_decode_size(char *source);
+
+const char *BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+void _base64_encode_triple(unsigned char triple[3], char result[4])
+{
+ int tripleValue, i;
+
+ tripleValue = triple[0];
+ tripleValue *= 256;
+ tripleValue += triple[1];
+ tripleValue *= 256;
+ tripleValue += triple[2];
+
+ for (i=0; i<4; i++)
+ {
+ result[3-i] = BASE64_CHARS[tripleValue%64];
+ tripleValue /= 64;
+ }
+}
+
+int base64_encode(unsigned char *source, size_t sourcelen, char *target, size_t targetlen)
+{
+ if ((sourcelen+2)/3*4 > targetlen-1)
+ return 0;
+
+ while (sourcelen >= 3)
+ {
+ _base64_encode_triple(source, target);
+ sourcelen -= 3;
+ source += 3;
+ target += 4;
+ }
+
+ if (sourcelen > 0)
+ {
+ unsigned char temp[3];
+ memset(temp, 0, sizeof(temp));
+ memcpy(temp, source, sourcelen);
+ _base64_encode_triple(temp, target);
+ target[3] = '=';
+ if (sourcelen == 1)
+ target[2] = '=';
+
+ target += 4;
+ }
+
+ target[0] = 0;
+
+ return 1;
+}
+
+size_t base64_encode_size(size_t sourcelen)
+{
+ return (sourcelen+2)/3*4+1;
+}
+
+int _base64_char_value(char base64char)
+{
+ if (base64char >= 'A' && base64char <= 'Z')
+ return base64char-'A';
+ if (base64char >= 'a' && base64char <= 'z')
+ return base64char-'a'+26;
+ if (base64char >= '0' && base64char <= '9')
+ return base64char-'0'+2*26;
+ if (base64char == '+')
+ return 2*26+10;
+ if (base64char == '/')
+ return 2*26+11;
+ return -1;
+}
+
+int _base64_decode_triple(char quadruple[4], unsigned char *result)
+{
+ int i, triple_value, bytes_to_decode = 3, only_equals_yet = 1;
+ int char_value[4];
+
+ for (i=0; i<4; i++)
+ char_value[i] = _base64_char_value(quadruple[i]);
+
+ for (i=3; i>=0; i--)
+ {
+ if (char_value[i]<0)
+ {
+ if (only_equals_yet && quadruple[i]=='=')
+ {
+ char_value[i]=0;
+ bytes_to_decode--;
+ continue;
+ }
+ return 0;
+ }
+ only_equals_yet = 0;
+ }
+
+ if (bytes_to_decode < 0)
+ bytes_to_decode = 0;
+
+ triple_value = char_value[0];
+ triple_value *= 64;
+ triple_value += char_value[1];
+ triple_value *= 64;
+ triple_value += char_value[2];
+ triple_value *= 64;
+ triple_value += char_value[3];
+
+ for (i=bytes_to_decode; i<3; i++)
+ triple_value /= 256;
+ for (i=bytes_to_decode-1; i>=0; i--)
+ {
+ result[i] = triple_value%256;
+ triple_value /= 256;
+ }
+
+ return bytes_to_decode;
+}
+
+size_t base64_decode(char *source, unsigned char *target, size_t targetlen)
+{
+ char *src, *tmpptr;
+ char quadruple[4];
+ unsigned char tmpresult[3];
+ int i, tmplen = 3;
+ size_t converted = 0;
+
+ src = (char *)malloc(strlen(source)+5);
+ if (src == NULL)
+ return -1;
+ strcpy(src, source);
+ strcat(src, "====");
+ tmpptr = src;
+
+ while (tmplen == 3)
+ {
+ for (i=0; i<4; i++)
+ {
+ while (*tmpptr != '=' && _base64_char_value(*tmpptr)<0)
+ tmpptr++;
+
+ quadruple[i] = *(tmpptr++);
+ }
+
+ tmplen = _base64_decode_triple(quadruple, tmpresult);
+
+ if (targetlen < tmplen)
+ {
+ free(src);
+ return -1;
+ }
+
+ memcpy(target, tmpresult, tmplen);
+ target += tmplen;
+ targetlen -= tmplen;
+ converted += tmplen;
+ }
+
+ free(src);
+ return converted;
+}
+
+size_t base64_decode_size(char *source) {
+
+ if (!source) return -1;
+
+ size_t len = strlen(source);
+
+ if (len < 4) /* invalid base64, minimum is 4 chars */ return -1;
+
+ if (source[len-1] != '=') return len*3/4;
+ if (source[len-2] != '=') return (len-1)*3/4;
+ else return (len-2)*3/4;
+}
+
+// vim: set expandtab ts=2 sw=2:
diff --git a/base64.h b/base64.h
@@ -0,0 +1,9 @@
+
+#include <stddef.h>
+
+size_t base64_encode_size( size_t sourcelen);
+int base64_encode (unsigned char *source, size_t sourcelen, char *target, size_t targetlen);
+size_t base64_decode_size( char *source);
+size_t base64_decode ( char *source, unsigned char *target, size_t targetlen);
+
+// vim: set expandtab ts=2 sw=2:
diff --git a/demo.c b/demo.c
@@ -0,0 +1,51 @@
+#! /usr/bin/env sheepy
+/* or direct path to sheepy: #! /usr/local/bin/sheepy */
+
+/* Libsheepy documentation: https://spartatek.se/libsheepy/ */
+#include "libsheepyObject.h"
+#include "base64.h"
+
+int argc; char **argv;
+
+/* enable/disable logging */
+/* #undef pLog */
+/* #define pLog(...) */
+
+int main(int ARGC, char** ARGV) {
+
+ argc = ARGC; argv = ARGV;
+
+ initLibsheepy(ARGV[0]);
+ setLogMode(LOG_DATE);
+ //setLogSymbols(LOG_UTF8);
+ //disableLibsheepyErrorLogs;
+
+ u8 bytes[] = {0x96,0x5c,0xbc,0x5d,0x00,0x00,0x00,0x00,0xd6,0x45,0xd3,0xd3,0xd0,0x84,0x98,0xaa,0x18,0xd1,0xf3,0xc7,0xef,0x9c,0x8b,0x5c,0x89,0x8b,0xee,0x23,0x86,0xff,0x35,0xf9};
+
+ u8 s[1024] = init0Var;
+
+ var r = base64_encode(bytes, sizeof(bytes), s, sizeof(s));
+
+ logVarG(sizeof(bytes));
+ logVarG(r);
+ logVarG(strlen(s));
+ logVarG(base64_encode_size(sizeof(bytes)));
+ logI(s);
+
+ /* char *base64String = "lly8XQAAAADWRdPT0ISYqhjR88fvnItciYvuI4b/Nfk="; */
+ char *base64String = s;
+
+ u8 decoded[40];
+
+ var size = base64_decode(base64String, decoded, sizeof(decoded));
+
+ logVarG(size);
+ logVarG(base64_decode_size(base64String));
+ logI("Source: 256bits");
+ loghex( bytes, MIN(sizeof(decoded), sizeof(bytes)));
+ put;
+ logI("Decoded: 256bits");
+ loghex(decoded, MIN(sizeof(decoded), sizeof(bytes)));
+
+}
+// vim: set expandtab ts=2 sw=2:
diff --git a/package.yml b/package.yml
@@ -0,0 +1,30 @@
+---
+ name: base64
+ version: 0.0.2
+ description: "encode bytes to base64 and decode base64 string to bytes"
+ bin: ./base64.c
+ #cflags: -DA -ggdb -std=gnu11 -fPIC -pipe
+ #lflags: -lpcre
+ repository:
+ type: git
+ url: git+https://github.com/USER/base64.git
+ keywords:
+ #- utility
+ - command
+ author: Remy
+ license: MIT
+ bugs:
+ url: https://github.com/USER/base64/issues
+ homepage: https://github.com/USER/base64#readme
+ #compileHelp: # text displayed when there is a compilation error
+ # Test configuration:
+ #testBin: ./testBase64.c
+ #testCflags: -ggdb -std=gnu11 -fPIC -pipe -fprofile-arcs -ftest-coverage -Wall -Wextra
+ #testLflags: -lcheck_pic -lrt -lm -lsubunit -fprofile-arcs -ftest-coverage -rdynamic
+ # Memcheck configuration:
+ #memcheckBin: ./memcheckBase64.c
+ #memcheckCmd: valgrind --leak-check=full --show-leak-kinds=all
+ #memcheckCflags: -ggdb -std=gnu11 -fPIC -pipe
+ #memcheckLflags: -rdynamic
+ #documentationCmd: # command for generating the documentation with spm doc
+ private: false # true for private package