Base32Encoding

advertisement
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
Download