This page was mutated from its original content to reduce and change some links that could confuse integrity.
This was an html rendering of an original raw plaintext email numbered 004981.

Some source code for phone number coding...

Nickey MacDonald i6t4 at jupiter.sun.csd.unb.ca
Wed Jul 7 22:04:10 PDT 1993


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 at jupiter.sun.csd.unb.ca  | PGP 2.1 Public key available via finger
i6t4 at unb.ca                  | (506) 457-1931    ^{1024/746EBB 1993/02/23}








More information about the cypherpunks-legacy mailing list