_ALGORITHM ALLEY_ by Gene Callahan edited by Bruce Schneier Listing One /* given an ASCII character, what is its value in the base? */ #define MAX_BASE 256 typedef struct baserep { int Radix; int NumValues[MAX_BASE]; char CharValues[MAX_BASE + 1]; } BaseRep; BaseRep Base36DigitsLower = { { 36 }, /* 0 - 47 */ {-1, -1, -1, /* ...and so on, until 48 negative ones in all */ /* 48 ('0') - 57 ('9') */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* 58 - 96: another run of -1 */ /* 97 ('a') - 122 ('z') */ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, /* 123 - 255: whole bunch o' negative ones go here */}, {"0123456789abcdefghijklmnopqrstuvwxyz"} }; Listing Two long BaseXToLong(char* number, BaseRep* br) { long PowerOfRadix; long ret = 0; int i; int digits = strlen(number); for(i = digits - 1, base_power = 1; i >= 0; i--, PowerOfRadix *= br->Radix) ret += (br->NumValues[(int)number[i]] * PowerOfRadix); return ret; } Listing Three char* LongToBaseX(long number, char* buf, int buf_len, BaseRep* br) { int i; for(i = buf_len - 1; i >= 0; i--) { buf[i] = br->CharValues[number % br->Radix]; number /= br->Radix; } if(number) return 0; /* null: error return */ return buf; /* so function will generate rvalue */ } Example 1: char* BaseXIncr(char* number, BaseRep* br) { return LongToBaseX(BaseXToLong(number, br) + 1, number, strlen(number), br); } Example 2: int LessThan(char* num1, BaseRep* br1, char* num2, BaseRep* br2) { return BaseXToLong(num1, br1) < BaseXToLong(num2, br2); }