/* ** @(#) b64.c - ASCII-64 encoding and decoding ** @(#) $Id: b64.c,v 1.2 2003/11/24 17:44:52 lucio Exp $ */ /* ** ================================================================== ** ** $Logfile:$ ** $RCSfile: b64.c,v $ ** $Revision: 1.2 $ ** $Date: 2003/11/24 17:44:52 $ ** $Author: lucio $ ** ** ================================================================== ** ** $Log: b64.c,v $ ** Revision 1.2 2003/11/24 17:44:52 lucio ** Checkpoint after some progress ** ** Revision 1.1.1.1 2003/11/10 10:34:31 lucio ** ASN.1 developments. ** ** ================================================================== */ #include #include #include "b64.h" static char b64[] = { 'A','B','C','D','E','F','G','H','I','J','K','L','M', 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z', 'a','b','c','d','e','f','g','h','i','j','k','l','m', 'n','o','p','q','r','s','t','u','v','w','x','y','z', '0','1','2','3','4','5','6','7','8','9','+','/', }; long eb64e (uchar *t, uchar *te, char *s) { uchar *pt = t; char *ps = s; int c; while (pt < te) { ps[0] = b64[(pt[0] & 0xFF) >> 2]; c = ((pt[0] & 0x03) << 4); if (pt + 1 >= te) { ps[1] = b64[c]; ps[2] = ps[3] = '='; } else { c |= (pt[1] & 0xFF) >> 4; ps[1] = b64[c]; c = ((pt[1] & 0x0F) << 2); ps[2] = b64[c]; if (pt + 2 >= te) { ps[2] = b64[c]; ps[3] = '='; } else { c |= (pt[2] & 0xFF) >> 6; ps[2] = b64[c]; ps[3] = b64[pt[2] & 0x3F]; } } pt += 3; ps += 4; *ps = '\0'; } return ps - s; } long eb64 (char *t, char *s) { return eb64e ((uchar *) t, (uchar *) (t + strlen (t)), s); } long eb64n (uchar *t, int n, char *s) { return eb64e (t, t + n, s); } long feb64n (char *fmt, uchar *t, long sz, int w) { uchar *t0 = t, *te = t + sz; char *s= malloc (1 + ((w + 2) / 3) * 4); long c = 0L; while (t0 + w < te) { eb64e (t0, t0 += w, s); c += print (fmt, s); } eb64e (t0, te, s); c += print (fmt, s); free (s); return c; } static int u64[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0.. 15 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 16.. 31 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, // 32.. 47 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, // 48.. 63 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, // 64.. 79 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, // 80.. 95 -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, // 96..111 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, // 112..127 }; long db64e (char *s, char *se, uchar *t) { char *ps = s; uchar *pt = t; int c0, c1, c2, c3; while (ps < se) { c0 = u64[ps[0]]; c1 = u64[ps[1]]; pt[0] = (c0 << 2) | ((c1 & 0xFF) >> 4); pt[1] = c1 << 4; if (ps[2] == '=') { pt++; break; } c2 = u64[ps[2]]; pt[1] |= (c2 & 0xFF) >> 2; pt[2] = c2 << 6; if (ps[3] == '=') { break; } c3 = u64[ps[3]]; pt[2] |= c3; ps += 4; pt += 3; } return pt - t; } long db64 (char *s, uchar *t) { return db64e (s, s + strlen (s), t); } long db64n (char *s, int n, uchar *t) { return db64e (s, s + n, t); } long db64v (uchar *t, char *s) { int l = strlen (s); return db64e (s, s + l, t); } #undef TEST #ifdef TEST main (int argc, char *argv) { uchar t[512], *t0; char s[512], *s0; long n; s0 = strdup ("MIIBlTCCAScCAWUwDQYJKoZIhvcNAQECBQAwUTELMAkGA1UEBhMCVVMxIDAeBgNV"); // s0 = strdup ("5XUXGx7qusDgHQGs7Jk9W8CW1fuSWUgN4w=="); n = db64 (s0, t); print ("Decoded: "); for (t0 = t; t0 < t + n; t0++) { print (" %02X", *t0 & 0xFF); } print ("\n"); memcpy (t0, t, n); // print ("%s\n", t0); n = eb64e (t0, t0 + n, s); print ("Encoded: "); for (s0 = s; s0 < s + n; s0++) { print (" %02X", *s0 & 0xFF); } print ("\n"); print ("%s\n", s); // print ("%s\n", db64 ("DQo=")); } #endif