Skip to content

Instantly share code, notes, and snippets.

@jadudm
Last active August 29, 2015 14:06
Show Gist options
  • Save jadudm/227105e0c3dbf2488b70 to your computer and use it in GitHub Desktop.
Save jadudm/227105e0c3dbf2488b70 to your computer and use it in GitHub Desktop.
A Square Encoder Reading and Coding Exercise
(I recommend you turn on line wrap by going to View->Line Wrap.)
# The Challenge: Square Code
One classic method for composing secret messages is called a square code. The spaces are removed from the english text and the characters are written into a square (or rectangle). For example, the sentence "If man was meant to stay on the ground god would have given us roots" is 54 characters long, so it is written into a rectangle with 7 rows and 8 columns.
ifmanwas
meanttos
tayonthe
groundgo
dwouldha
vegivenu
sroots
The coded message is obtained by reading down the columns going left to right. For example, the message above is coded as:
imtgdvs fearwer mayoogo anouuio ntnnlvt wttddes aohghn sseoau
#################
# The Code
You've been given a starter template to work with.
#####
## square.c
This is where the majority of your code will go. You may introduce new functions, but you may not change the names of anything there, because this will break the test suite.
#####
## square_test.c
This file contains the test suite that will be run against your code.
To run it, type
make test
on the command line, and then execute the program square_test as follows:
./square_test
This will tell you if your C code is correct according to the tests your Evil Professor has provided you.
#####
## square.h
If you add any new functions to square.c, you will need to add headers for them here as well. I don't expect you to need to add new functions for this assignment, however.
#####
## Makefile
This is a good thing to look at; it takes care of defining how your programs should be compileted. We'll talk more about Makefiles as the term progresses.
#include <stdio.h>
#include "square.h"
int main () {
char *msg;
int length;
for (int i = 0 ; i < get_number_of_messages(); i++) {
msg = read_message(i);
length = get_message_length(i);
for (int i = 0; i < length; i++) {
printf("%c", msg[i]);
}
printf("\n");
}
return 0;
}
# QUESTIONS FOR CONSIDERATION
#
CFLAGS=-std=c99 -Wall -g
test: square
gcc ${CFLAGS} -o square_test square.o square_test.c
encoder: square
gcc ${CFLAGS} -o encoder square.o encoder.c
square:
gcc ${CFLAGS} -c square.c
clean:
rm -f square square_test encoder square.o
all: clean square test encoder
God has made of one blood all peoples of the earth
There is dignity in all labor
Imagination is more important than knowledge
Do not dwell in the past, do not dream of the future, concentrate the mind on the present moment
The best place to find a helping hand is at the end of your own arm
If your strength is small, don't carry heavy burdens. If your words are worthless, don't give advice
If you are patient in one moment of anger, you will escape a hundred days of sorrow
If you must play, decide upon three things at the start: the rules of the game, the stakes, and the quitting time
Learning is a treasure that will follow its owner everywhere
A change is as good as a rest
A known mistake is better than an unknown truth
Arrogance is a weed that grows mostly on a dunghill
A cutting word is worse than a bowstring, a cut may heal, but the cut of the tongue does not
A fool looks for dung where the cow never browsed
If you don't stand for something, you will fall for something
Adversity is the foundation of virtue
An excess of courtesy is discourtesy
Opinions founded on prejudice are always sustained with the greatest violence
In a country well governed, poverty is something to be ashamed of. In a country badly governed, wealth is something to be ashamed of
The cautious seldom err
#include <stdio.h>
#include <stdlib.h>
#include "square.h"
char IGNORE[] = {'.', ' ', ',', 0x27, ':'};
FILE *open_message_file () {
return fopen("SEKRETS.txt", "r");
}
void close_message_file(FILE *fp) {
if (fp != NULL) {
fclose(fp);
}
}
int get_number_of_messages () {
FILE *fp;
int line_count;
fp = open_message_file();
line_count = 0;
while (!feof(fp)) {
int c = getc(fp);
if (c == '\n') {
line_count++;
}
}
close_message_file(fp);
return line_count;
}
FILE *advance_to_msg (int msg_ndx) {
FILE *fp;
int line_count;
fp = open_message_file();
line_count = 0;
while (!feof(fp) && line_count < msg_ndx) {
int c = getc(fp);
if (c == '\n') {
line_count++;
}
}
return fp;
}
int get_message_length (int msg_ndx) {
FILE *fp;
int length = 0;
char c;
fp = advance_to_msg (msg_ndx);
while((c = getc(fp)) != '\n') {
int OK = 1;
for (int i = 0; i < sizeof(IGNORE); i++) {
if (c == IGNORE[i]) {
OK = 0;
}
}
if (OK) {
length++;
}
}
close_message_file(fp);
return length;
}
char *read_message (int msg_ndx) {
FILE *fp;
char *msg;
int ndx;
int length;
char c;
ndx = 0;
length = get_message_length(msg_ndx);
fp = advance_to_msg(msg_ndx);
msg = (char*) malloc(length * sizeof(char));
while((c = getc(fp)) != '\n') {
int OK = 1;
for (int i = 0; i < sizeof(IGNORE); i++) {
/* printf("CHECKING %c vs %c\n", c, IGNORE[i]); */
if (c == IGNORE[i]) {
OK = 0;
}
}
if (OK) {
msg[ndx] = c;
ndx += 1;
}
}
close_message_file(fp);
return msg;
}
#ifndef SQUARE_H
/* MinUnit Source Code */
/* http://www.jera.com/techinfo/jtns/jtn002.html */
/* BEGIN NO STUDENT COMMENTS */
#define mu_assert(message, test) do { if (!(test)) return message; } while (0)
#define mu_run_test(test) do { char *message = test(); tests_run++; \
if (message) return message; } while (0)
extern int tests_run;
/* END NO STUDENT COMMENTS */
int get_number_of_messages();
FILE *open_message_file();
void close_message_file(FILE *fp);
int get_message_length (int msg_ndx);
char *read_message (int msg_ndx);
FILE *advance_to_msg (int msg_ndx);
#endif /* SQUARE_H */
#include <stdio.h>
#include <stdlib.h>
#include "square.h"
/* BEGIN NO STUDENT COMMENTS */
int tests_run = 0;
/* END NO STUDENT COMMENTS */
static char * test_get_number_of_messages() {
int msgs;
msgs = get_number_of_messages();
mu_assert("There should be more than zero messages!", msgs > 0);
return 0;
}
static char * test_open_message_file() {
FILE *fp;
fp = open_message_file();
mu_assert("The message file pointer should not be NULL!", fp != NULL);
if (fp != NULL) {
fclose(fp);
}
return 0;
}
static char * test_advance_to_message () {
FILE *fp;
char correct[] = {'G', 'T', 'I', 'D', 'T'};
for (int i = 0 ; i < 5; i++) {
fp = advance_to_msg(i);
printf("\t... Checking ability to advance to message %d\n", i);
mu_assert("Found wrong message in first five.", getc(fp) == correct[i]);
close_message_file(fp);
}
return 0;
}
static char * test_get_message_length () {
int lengths[] = {40, 24, 39, 76, 52, 79, 66, 88, 51, 22, 39, 42, 71, 40, 49, 32, 31, 67, 106, 20};
/*
for (int i = 0 ; i < get_number_of_messages() ; i++) {
int length;
length = get_message_length(i);
printf("%d, ", length);
}
*/
for (int i = 0 ; i < get_number_of_messages() ; i++) {
int length;
length = get_message_length(i);
printf("\t... Checking length of message index %d (%d)\n", i, length);
mu_assert("Found wrong message length.", length == lengths[i]);
}
return 0;
}
static char * test_read_message () {
char * messages[] = {"Godhasmadeofonebloodallpeoplesoftheearth", \
"Thereisdignityinalllabor", \
"Imaginationismoreimportantthanknowledge", \
"Donotdwellinthepastdonotdreamofthefutureconcentratethemindonthepresentmoment", \
"Thebestplacetofindahelpinghandisattheendofyourownarm", \
"IfyourstrengthissmalldontcarryheavyburdensIfyourwordsareworthlessdontgiveadvice", \
"Ifyouarepatientinonemomentofangeryouwillescapeahundreddaysofsorrow", \
"Ifyoumustplaydecideuponthreethingsatthestarttherulesofthegamethestakesandthequittingtime", \
"Learningisatreasurethatwillfollowitsownereverywhere", \
"Achangeisasgoodasarest", \
"Aknownmistakeisbetterthananunknowntruth", \
"Arroganceisaweedthatgrowsmostlyonadunghill", \
"Acuttingwordisworsethanabowstringacutmayhealbutthecutofthetonguedoesnot", \
"Afoollooksfordungwherethecowneverbrowsed", \
"Ifyoudontstandforsomethingyouwillfallforsomething", \
"Adversityisthefoundationofvirtue", \
"Anexcessofcourtesyisdiscourtesy", \
"Opinionsfoundedonprejudicearealwayssustainedwiththegreatestviolence", \
"InacountrywellgovernedpovertyissomethingtobeashamedofInacountrybadlygovernedwealthissomethingtobeashamedof", \
"Thecautiousseldomerr" \
};
for (int i = 0 ; i < get_number_of_messages() ; i++) {
int message_length = get_message_length(i);
char *msg = read_message(i);
printf("\t... Checking correctness of message %d\n", i);
for (int pos = 0 ; pos < message_length ; pos++) {
/* printf("POS[%d] msg[%c] messages[%c]\n", pos, msg[pos], messages[i][pos]); */
mu_assert("Found wrong character in message.", msg[pos] = messages[i][pos]);
}
free(msg);
}
return 0;
}
static char * all_tests() {
mu_run_test(test_get_number_of_messages);
mu_run_test(test_open_message_file);
mu_run_test(test_advance_to_message);
mu_run_test(test_get_message_length);
mu_run_test(test_read_message);
return 0;
}
/* Standard main() for running all tests. */
int main(int argc, char **argv) {
char *result = all_tests();
if (result != 0) {
printf("%s\n", result);
}
else {
printf("ALL TESTS PASSED\n");
}
printf("Tests run: %d\n", tests_run);
return result != 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment