Bases2 64
From C
Contents |
Bases 2-64
This code is something convenient which I recently whipped up for some other project. I'm pretty sure it would benefit from some kibitizing. --PoppaVic 15:55, 28 Dec 2006 (UTC)
bases.h
/* bases.h */
void* isbaseable (char c);
char* bin2text (char *dest, unsigned n, int base);
unsigned text2bin (char *src, char **stopped);
#define BASES_MIN 2
#define BASES_MAX 64
#define BASES_PREFIX '#'
#define BASES_POSTFIX ':'
bases.c
/* bases.c */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include "bases.h"
static char pseudohex[]= /* NOTE: this is NOT "base-64" _or_ MIME !! */
"0123456789"
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"_."; /* need 2 more sym; these are handy */
static char map(int digit)
{
return pseudohex[digit%(1+BASES_MAX)];
}
static int unmap(char c)
{
return (((char*)isbaseable(c))-pseudohex);
}
static void* bin2text_(char *dest, unsigned n, int base)
{
if( n < base )
{
sprintf(dest, "%c", map(n) );
}
else
{
dest= bin2text_(dest, n/base, base);
sprintf(dest, "%c", map(n%base) );
}
return ++dest;
}
/***************************************************/
void* isbaseable(char c)
{
return strchr(pseudohex, c);
}
/***************************************************/
char* bin2text(char *dest, unsigned n, int base)
{ char *from=dest;
if(!dest || base<BASES_MIN || base>BASES_MAX)
return NULL;
*dest=0;
from+=sprintf(from, "%c%d%c", BASES_PREFIX, base, BASES_POSTFIX);
bin2text_(from, n, base);
return dest;
}
unsigned text2bin(char *src, char **stopped)
{ unsigned ret=0;
int oldbase;
if(src && *src==BASES_PREFIX)
{
/* Fetch the '#'<base> */
oldbase=(int)strtol(++src, &src, 10);
if(stopped) *stopped= src;
if(oldbase<BASES_MIN || oldbase>BASES_MAX)
return 0;
/* Eat ':'<any intervening whitespace> */
if(*src==BASES_POSTFIX)
{
src++;
while(isspace(*src)) src++;
}
else
return 0;
/* Fetch actual <value> - in the above BASE */
if(*src) for(;*src && isbaseable(*src); src++)
{
ret*= oldbase%(1+BASES_MAX);
ret+= unmap(*src);
}
if(stopped) *stopped= src;
}
return ret;
}
/***************************************************/
int main()
{ char buff[256];
int i,j;
unsigned N= 0xFEDCBA;
for(i=BASES_MIN; i<=BASES_MAX; i++)
{
printf("Given: 0x%x: base(%d)= %n",
N, i, &j);
printf("%-*s\"%s\":=0x%x\n",
30-j, "",
bin2text(buff, N, i),
text2bin(buff, NULL) );
}
return 0;
}
