mason@tmsoft.uucp (Dave Mason) (12/12/89)
/* c-news-stamp - Written 89.12.11 Dave Mason <mason@tmsoft.uucp> released to the Public Domain (although I'd appreciate acknowledgement of authorship) For use with C News to generate a unique Message-ID: Claimed advantages over other implementations? very small (<1k executable) fast dense believed to be general purpose bit extractor Breaks the 32 bit date/time + 16 bit parent process id into 9 or 10 characters chosen from a 5 bit (32 element) character set. While slightly denser coding is possible, larger character sets are required: Character Set Size Number of Characters to encode 48 bits 32 10 (9 for now) - easy. 41 9 - but requires messy divide on 32bit machines 64 8 - no way without Upper & Lower Case (should be fine, but I'm untrusting) 116 7 - no way with 7 bit ASCII 256 6 - get serious (but easy :-) 777 5 - ugly AND implausible 4096 4 - maybe in Japan 65536 3 - not even in Japan The bit mapping is as follows: 4 3 2 1 0 7654321098765432 1098765432109876 5432109876543210 xxx.....xxxxx... ..xxxxx.....xxxx x.....xxxxx..... (first character is removed if '0' - which it will be until ~2000) */ /* to change to N bit encoding, just change these 2 defines */ #define BITS 5 #define BIT_MASK 31 #define MAX_CHARS ((48+BITS-1)/BITS) /* of course if BITS is more than 6, you'll have to change this too */ char enc[]="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-"; main() { unsigned short sh[4]; long l; static char rep[MAX_CHARS+1]; extern long time(); register long w=0,bit=48%BITS,p=0; register char *op=rep,*fp=rep; l=time((long *)0); sh[0]=l>>16; sh[1]=l; sh[2]=getppid(); while (op<&rep[MAX_CHARS]) { if (bit<0) { w=sh[p++]<<(-bit); bit+=16; } else if (bit<BITS) w|=sh[p]>>bit; *op++ = enc[(w>>(16-BITS))&BIT_MASK]; w<<=BITS; bit-=BITS; } *op++='\n'; while (*fp==enc[0]) ++fp; write(1,fp,op-fp); }