Script started on Tue May %cat base32.c 7 11:27:56 2002 #include <stdio.h> #include <ctype.h> #include <string.h> /* * This library ignores incoming line breaks, but does not add line breaks to * encoded data. It also treats a null terminator as the end of input. */ /* Given a 5-bit binary value, get a base32 character. */ static char b32table[32] = "ABCDEFGHIJKMNPQRSTUVWXYZ23456789"; /* * Given a base32 character, return the original 5-bit binary value. We treat * a null in the input as the end of string and = as padding signifying the * end of string. Everything else is ignored. * * Notice that our decode is case insensitive. */ /* * A reverse lookup table; given an ASCII byte that should be * convert it to the proper 5 bits of binary. */ static char b32revtb[256] = { -3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 24, 25, 26, 27, 28, 29, 30, 31, -1, -1, -1, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, -1, 11, 12, -1, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, -1, 11, 12, -1, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, }; base32 encoded, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* * Accepts a binary buffer with an associated size. Returns a base32-encoded, * null-terminated string. */ unsigned char * base32_encode(unsigned char *input, int len) { unsigned char *output, *p; int mod = len % 5; int i = 0, j; char padchrs = 0; j = ((len / 5) + (mod ? 1 : 0)) * 8 + 1; p = output = (unsigned char *)malloc(j); while (i < len - mod) { *p++ = b32table[input[i] >> 3]; *p++ = b32table[(input[i] << 2 | input[i + 1] >> 6) & 0x1f]; *p++ = b32table[(input[i + 1] >> 1) & 0x1f]; *p++ = b32table[(input[i + 1] << 4 | input[i + 2] >> 4) & 0x1f]; *p++ = b32table[(input[i + 2] << 1 | input[i + 3] >> 7) & 0x1f]; *p++ = b32table[(input[i + 3] >> 2) & 0x1f]; *p++ = b32table[(input[i + 3] << 3 | input[i + 4] >> 5) & 0x1f]; *p++ = b32table[input[i + 4] & 0x1f]; i = i + 5; } if (!mod) { *p = 0; return output; } *p++ = b32table[input[i] >> 3]; if (mod == 1) { *p++ = b32table[(input[i] << 2) & 0x1f]; padchrs = 6; pad: while (padchrs--) { *p++ = '='; } return output; } *p++ = b32table[(input[i] << 2 | input[i + 1] >> 6) & 0x1f]; *p++ = b32table[(input[i + 1] >> 1) & 0x1f]; if (mod == 2) { *p++ = b32table[(input[i + 1] << 4) & 0x1f]; padchrs = 4; goto pad; } *p++ = b32table[(input[i + 1] << 4 | input[i + 2] >> 4) & 0x1f]; if (mod == 3) { *p++ = b32table[(input[i + padchrs = 3; goto pad; } *p++ = b32table[(input[i + 2] << *p++ = b32table[(input[i + 3] >> *p++ = b32table[(input[i + 3] << *p++ = '='; return output; } static void raw_base32_decode(unsigned char *in, 2] << 1) & 0x1f]; 1 | input[i + 3] >> 7) & 0x1f]; 2) & 0x1f]; 3) & 0x1f]; unsigned char *out, int *err, int *len) { unsigned char unsigned char char *err = 0; *len = 0; buf[5]; pad = 0; x; while (1) { ch1: switch (x = b32revtb[*in++]) { case -3: /* NULL TERMINATOR */ return; case -2: /* PADDING CHAR... INVALID HERE */ *err = 1; return; case -1: goto ch1; /* skip characters that aren't in the * alphabet */ default: buf[0] = x << 3; } ch2: switch (x = b32revtb[*in++]) { case -3: /* NULL TERMINATOR... INVALID HERE */ case -2: /* PADDING CHAR... INVALID HERE */ *err = 1; return; case -1: goto ch2; default: buf[0] |= (x >> 2); buf[1] = x << 6; } ch3: switch (x = b32revtb[*in++]) { case -3: /* NULL TERMINATOR... INVALID HERE */ *err = 1; return; case -2: /* Just assume the padding is okay. */ (*len)++; buf[1] = 0; pad = 4; goto assembled; case -1: goto ch3; default: buf[1] |= x << 1; } ch4: switch (x = b32revtb[*in++]) { case -3: /* NULL TERMINATOR... INVALID HERE */ case -2: *err = 1; return; case -1: goto ch4; default: buf[1] |= x >> 4; buf[2] = x << 4; } ch5: switch (x = b32revtb[*in++]) { case -3: *err = 1; return; case -2: (*len) += 2; buf[2] = 0; pad = 3; goto assembled; case -1: goto ch5; default: buf[2] |= x >> 1; buf[3] = x << 7; } ch6: switch (x = b32revtb[*in++]) { case -3: *err = 1; return; case -2: (*len) += 3; buf[3] = 0; pad = 2; goto assembled; case -1: goto ch6; default: buf[3] |= x << 2; } ch7: switch (x = b32revtb[*in++]) { case -3: case -2: *err = 1; return; case -1: goto ch7; default: buf[3] |= x >> 3; buf[4] = x << 5; } ch8: switch (x = b32revtb[*in++]) { case -3: *err = 1; return; case -2: (*len) += 4; buf[4] = 0; pad = 1; goto assembled; case -1: goto ch8; default: buf[4] |= x; } (*len) += 5; assembled: for (x = 0; x < 5 - pad; x++) { *out++ = buf[x]; } if (pad) { return; } } } /* * If err is nonzero on exit, then there was an incorrect padding error. We * allocate enough space for all circumstances, but when there is padding, or * there are characters outside the character set in the string (which we are * supposed to ignore), then we end up allocating too much space. You can * realloc to the correct length if you wish, or write a routine that first * calculates the correct output length before decoding. The variable len * will point to the actual length of the data in the buffer. */ unsigned char * base32_decode(unsigned char *buf, int *err, int *len) { unsigned char *outbuf; outbuf = (unsigned char *)malloc(5 * (strlen(buf) / 8 + 1)); raw_base32_decode(buf, outbuf, err, len); return outbuf; } void main() { unsigned char *input = "lo015abcde12345"; unsigned char *output; unsigned char *input1; int i, err; int len; printf("The original input is: \n"); for (i = 0; i < 15; i++) printf("%c", input[i]); printf("\n"); printf("The encrypted string is: \n"); output = base32_encode(input, 15); for (i = 0; i < 15; i++) printf("%c", output[i]); printf("\n"); printf("The decrypted string is: \n"); input1 = base32_decode(output, &err, &len); for (i = 0; i < 15; i++) printf("%c", input1[i]); printf("\n"); } % %a.out The original input is: lo015abcde12345 The encrypted string is: PTZVANJXNFTGG3D The decrypted string is: lo015abcde12345 % %^D exit script done on Tue May 7 11:28:20 2002