add some untested base64
[libjh.git] / base64.c
diff --git a/base64.c b/base64.c
new file mode 100644 (file)
index 0000000..3d70903
--- /dev/null
+++ b/base64.c
@@ -0,0 +1,33 @@
+HEADER #include <stdlib.h>
+
+static char b64_encchr(unsigned char c) {
+  if (c<26) return 'A'+c;      c-=26;
+  if (c<26) return 'a'+c;      c-=26;
+  if (c<10) return '0'+c;      c-=10;
+  if (c==0) return '+';
+  return '/';
+}
+
+// Encodes `len` bytes from `src` into `dst`. `dst` must be  large enough to
+// hold the base64-encoded form of the input.
+PUBLIC_FN void base64_encode(char *dst, unsigned char *src, size_t len) {
+start:;
+  if (len == 0) return;
+  unsigned char a=src[0], b=0, c=0;
+  len--, src++;
+  int eqsigns = (len<2)?(2-len):0;
+  if (len) b=src[0], len--, src++;
+  if (len) c=src[0], len--, src++;
+  
+  unsigned char k =              a>>2;
+  unsigned char l = ((a&3)<<4) |(b>>4);
+  unsigned char m = ((b&15)<<2)|(c>>6);
+  unsigned char n = c&63;
+  
+  *(dst++) = b64_encchr(k);
+  *(dst++) = b64_encchr(l);
+  *(dst++) = (eqsigns==2)?'=':b64_encchr(m);
+  *(dst++) = eqsigns?'=':b64_encchr(n);
+  
+  goto start;
+}
\ No newline at end of file