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