/*
** @(#) 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 <u.h>
#include <libc.h>
#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
|