Here is a couple of message about my phone encoding format (giving progressively more info to a person trying to guess the format) followed by the complete source... Use it well. (TABsize was 3.) Okay, well without giving you the source... heres the biggest hint I can think of...
From /etc/magic: 0 string \037\235 compressed data
Translating that to decimal and in 4 byte unsigned long we get (\037\235\0\0 == 31,157,0,0 == 0,530,382,848 ^^^^^
From the start of my posted list of phone numbers: (503) 241-9796 ext: 09 ^^^ ^ ?? ?
If you know the rules for forming (valid looking) phone numbers... Anyway, to finially give the whole thing away... The file that is hidden starts with these 4 bytes... 1f 9d 90 54 == 0,530,419,796 Well.. I like puzzles... (as long as the answer is eventually revealed) so I'll let you think it over for a bit, before I send you the source... ;-) Okay well... lets assume that all valid phone numbers must be in the form [2-9][0-1][0-9] [2-9][0-9][0-9] [0-9][0-9][0-9][0-9] This is the form of my encoding... now if you take a sample number, like 1,234,567,890 and try encode it into a phone number, you would get (123) 456-7890 ^^ And you notice that the 1 and the two are out of range... Well.. as it happens, for 32 bit unsigned numbers the range is 0 to 4,294,967,294... The first digit will always be 0-4, half of which are illegal in that position, so I decided to swap the first two digits... That doesn't fix all of the range problems, thus whenever there is an invalid digit in position 1,2 or 4 I move it to the extension and put a special indicator value (the higest of the legal range) in its place. Thats the whole secret... Code will follow soon... :-) /* pe.c phone encode Written by: Nickey MacDonald July 7, 1993 Encode a message as a list of phone numbers... There are some tricks used to make the phone numbers appear more realistic, and there is a caveate... If the input file has 4 null bytes aligned of a 4 byte boundry, then the program will think its the EOF and stop... This could be fixed easily... I just didn't. */ #include <stdio.h> unsigned long getbytes(FILE *fp); int main(void) { unsigned short i, ei; /* i=work counter, ei=ext. counter */ unsigned char pn[10], ext[4], v=0; /* Digits of phone num, ext and a */ /* pseudo random value */ unsigned long b; /* 4 bytes compress to a unsigned long */ char tpnumbuf[11]; /* a sprinft buffer for b */ /* Read until EOF or 4 properly aligned null bytes */ while((b=getbytes(stdin)) != 0) { ei=0; /* Convert the unsigned long into a string */ sprintf(tpnumbuf, "%010lu", b); /* Pick up the digits of the unsigned long */ /* Because of the distribution, swap the first two digits... */ pn[0]=tpnumbuf[1]-'0'; pn[1]=tpnumbuf[0]-'0'; for(i=2; i<10; i++) { pn[i]=tpnumbuf[i]-'0'; v+=pn[i]; } /* The first digit of the area code must be [2-9] */ if (pn[0]<3) { ext[ei++]=pn[0]; pn[0]=2; } /* Currently the middle digit of area code must be 0 or 1 */ if (pn[1]>0) { ext[ei++]=pn[1]; pn[1]=1; } /* The first digit of prefix must be [2-9] */ if (pn[3]<3) { ext[ei++]=pn[3]; pn[3]=2; } /* Generate the output phone number */ fprintf(stdout, "(%d%d%d) %d%d%d-%d%d%d%d", pn[0], pn[1], pn[2], pn[3], pn[4], pn[5], pn[6], pn[7], pn[8], pn[9]); /* Generate the extension if needed */ if (ei>0) { ext[ei++]=v%10; fprintf(stdout, " ext: "); for (i=0; i<ei; i++) fprintf(stdout, "%d", ext[i]); } fprintf(stdout, "\n"); } return(0); } /* Input 4 bytes, convert EOF to null and encode as an unsigned long */ unsigned long getbytes(FILE *fp) { int b[4]; unsigned short i; for(i=0; i<4; i++) { b[i]=fgetc(fp); if (b[i]==EOF) b[i]=0; } return(((unsigned long)b[0])<<24 | ((unsigned long)b[1])<<16 | ((unsigned long)b[2])<< 8 | ((unsigned long)b[3])); } /* pd.c phone decode Written by: Nickey MacDonald July 7, 1993 Decodes a message hidden in a list of phone numbers. */ #include <stdio.h> void putbytes(FILE *fp, unsigned long val); int main(void) { unsigned short i, ei; /* i=work counter, ei=extention work counter */ unsigned char pn[10]; /* The digits of the phone number */ unsigned long b; /* The finally decoded value from the phone num */ char pnline[30]; /* Input line buffer */ int flg=0; /* The error message is only output once */ /* Read lines until end of file */ while((fgets(pnline, 30, stdin)) != NULL) { /* error checking */ if ((pnline[0] != '(') || (pnline[4] != ')') || (pnline[9] != '-')) { if (flg==0) { fprintf(stderr, "Input not in correct format, output will be garbage!\n"); flg=1; } } /* Extract the digits of the phone number, and convert from ASCII */ pn[0]=pnline[1]-'0'; pn[1]=pnline[2]-'0'; pn[2]=pnline[3]-'0'; pn[3]=pnline[6]-'0'; pn[4]=pnline[7]-'0'; pn[5]=pnline[8]-'0'; pn[6]=pnline[10]-'0'; pn[7]=pnline[11]-'0'; pn[8]=pnline[12]-'0'; pn[9]=pnline[13]-'0'; /* The first digit of the extension should be the 21st loc of input buf */ ei=21; /* The first digit of an area code is always [2-9] */ if (pn[0]==2) { pn[0]=pnline[ei++]-'0'; } /* Currently, the middle digit of area code is always 0 or 1 */ if (pn[1]==1) { pn[1]=pnline[ei++]-'0'; } /* The first digit of a prefix is always [2-9] */ if (pn[3]==2) { pn[3]=pnline[ei++]-'0'; } /* Swap first two digits */ i=pn[0]; pn[0]=pn[1]; pn[1]=i; /* Encode the individualt digits into a unsigned long */ b=0; for(i=0; i<10; i++) b=b*10+pn[i]; /* output the decoded bytes */ putbytes(stdout, b); } return(0); } /* Simple encoding... 4 bytes to the longword... seperate them here */ void putbytes(FILE *fp, unsigned long val) { int b[4]; b[0]=(int)(val>>24 & 255); b[1]=(int)(val>>16 & 255); b[2]=(int)(val>> 8 & 255); b[3]=(int)(val & 255); fprintf(fp, "%c%c%c%c", b[0], b[1], b[2], b[3]); } -- Nick MacDonald | NMD on IRC i6t4@jupiter.sun.csd.unb.ca | PGP 2.1 Public key available via finger i6t4@unb.ca | (506) 457-1931 ^{1024/746EBB 1993/02/23}