Bases2 64

From C

Jump to: navigation, search

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;
}


Category Snippets

Personal tools