/*
 * Steganography encoding attempt 0
 * tjf, 23/12/01
 * TODO: semantic compressions, e.g. s/and/&
 */

#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define PUNCTC 8
#define LEADING 5

int iscount(int c);

int main(int argc, char *argv[])
{
	int input, count, prev, i, j;
	struct in_addr ip;
	static char *punct[PUNCTC] = { ". ", ", ", " - ", "! ", ": ", " & ", "! ", "? " };	/* must be a power of 2 */

	/* parse arguments */
	if(argc != 2) {
		fprintf(stderr, "Usage: %s <ip>\n(Reads text from stdin)\n", argv[0]);
		return 1;
	}
	if(inet_aton(argv[1], &ip) != 1)
		return 1;

	count = 0;
	prev = (int)' ';
	while((input = getchar()) != EOF) {
		/* use punctuation */
		if(iscount(count) && ispunct((char)input)) {
			/* find maximum number of bits we can store here */
			for(i = 0; i <= count - LEADING; i++)
				if(pow(2, (double)i) > (PUNCTC - 1) / 2)
					break;
			/* read IP into int */
			for(j = 0 ; i >= 0; i--)
				if(((in_addr_t)pow(2, (double)(count++ - LEADING))) & ip.s_addr)
					j += pow(2, (double)i);
			/* convert */
			puts(punct[j]);
		} else if(iscount(count) && isspace(prev)) {
			/*
			 * use capitalisation of the first letter in each word
			 * Hello this Is An example -> 10110
			 */
			/* beginning of word */
			if(!isspace(input) && isalpha(input)) {
				prev = input;
				if((in_addr_t)(pow(2, (double)(count - LEADING))) & ip.s_addr)
					putchar(toupper(input));	/* 1 */
				else
					putchar(tolower(input));	/* 0 */
				count++;
			}
		} else {
			/* inside or at end of word */
			prev = input;
			putchar(input);
			count += !iscount(count);	/* LEADING */
		}
	}
	if(count - LEADING != 1 && prev != '\n')
		putchar('\n');
	if(iscount(count))
		fprintf(stderr, "%s: buffer underflow\n", argv[0]);

	return ((count - LEADING) == 32);
}

/* check if count is in range */
int iscount(int c)
{
	return ((c - LEADING) <= 32 && (c - LEADING) >= 0);
}


