Skip to content

C challenge Mystery Cache

This cache has been locked, but it is available for viewing.
Hidden : 9/11/2008
Difficulty:
4 out of 5
Terrain:
1 out of 5

Size: Size:   micro (micro)

Join now to view geocache location details. It's free!

Watch

How Geocaching Works

Please note Use of geocaching.com services is subject to the terms and conditions in our disclaimer.

Geocache Description:

A little C programming exercise.

Original coordinates leads to the middle of the meadow. Surprisingly, cache is not there. The right coordinates (message which tells you them) are encrypted in the following binary file. Here comes the hex dump:

0x8D 0x85 0x5F 0x2F 0x60 0x35 0x35 0x42
0x25 0x73 0x9E 0x2A 0x2A 0x9E 0x09 0xC0
0x74 0x11 0xD9 0x4A 0x9F 0x79 0x22 0x8F
0xBF 0xB0 0x9B 0xFD 0x09 0x9C 0xCC 0xE1
0xA5 0x55 0x55 0x63 0xE7 0x14 0xA5 0xA5
0x5F 0x3D 0x90 0x9C 0xA7 0x5D 0x52 0x5E
0x3C 0x55 0x55 0xDD 0xC4 0x11 0x4B 0xBF
0x3B 0x46 0x34 0xA6 0x0D 0x35 0x18 0x43
0x6A 0xF5 0xDB 0xE5 0x3E 0x86 0x20 0x18
0x20 0x4B 0x7B 0x50 0xCE 0xB5 0x2A 0x6A
0x1C 0x1C 0x9A 0x5A 0x2A 0x0B 0xBD 0x12
0x60 0xA9 0x34 0xF9 0x7B 0xAB 0x29 0xF9
0x6A 0x3F 0x44 0x6F 0x2F 0x04 0xD8 0xEA
0x23 0x5D 0x5E 0xEF 0x5B 0xA9 0x0B 0x3C
0x3C 0xB8 0xDC 0xEB 0x26 0x6A 0x60 0xFD
0xE0 0x35 0x60 0x50 0x0C 0xB5 0x29 0x20
0x20 0x5A 0x2A 0xF2 0x5D 0xAE 0x44 0x6F
0x2F 0xEB 0xA0 0x14 0x80 0x71 0xB0 0x11
0xAC 0x4B 0x8F 0x20 0x5B 0xA9 0x0B 0x96
0xDB 0x42 0x9B 0x65 0x5A 0x9E 0x1B 0xC8
0xD7 0x2A 0x9E 0x73 0x44 0x6F 0x2F 0x2B
0x26 0x65 0x34 0xE0 0x53 0xA4 0x8D 0x76
0xC7 0x7B 0xCE 0x96 0x46 0x86 0x7B 0x3B
0x0C 0x1C 0x4B 0x29 0xDB 0x08 0xFB 0x8C

As the work will not be too difficult for you, I've prepared myself the skeleton of decoder in my favorite language (guess what =]). So implement it and decode the message. Good luck fellas.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

/*
 * Computes XOR key from the message lenght.
 * For implementation, use factorial function but ensure that result
 * of factorial is number that fits into unsigned char! Use modulo
 * function visely for this (before calling factorial).
 */
unsigned char get_xor_key(int len)
{
        return 0; /* return desired value instead */
}

/*
 * XOR the message using key
 */
void xor(unsigned char *data, int len, unsigned char key)
{
        /* write your code here */
}

/*
 * Substitutes all set bits by cleared and vice versa.
 */
void change_ones_and_zeroes(unsigned char *data, int len)
{
        /* write your code here */
}

/*
 * Rotates each byte right by the number of set bits in it.
 */
void rotate_right_by_num_of_set_bits(unsigned char *data, int len)
{
        /* write your code here */
}


/*
 * Function does the opposite of following:
 * Take byte by byte and increment it by the next one and repeat till the end
 * of the string. The last byte stays untouched.
 */
void decr_by_next(unsigned char *data, int len)
{
        /* write your code here */
}

/*
 * Takes bytes from message by two and swap them. In case that len is odd number,
 * leave the last byte as it is.
 */
void swap_neighbours(unsigned char *data, int len)
{
        /* write your code here */
}

/*
 * Simply does the reverse of string passed
 */
void reverse(unsigned char *data, int len)
{
        /* write your code here */
}

void decode_message(unsigned char *data, int len)
{
        decr_by_next(data, len);
        reverse(data, len);
        swap_neighbours(data, len);
        rotate_right_by_num_of_set_bits(data, len);
        change_ones_and_zeroes(data, len);
        xor(data, len, get_xor_key(len));
}

int main(int argc, char *argv[])
{
        unsigned char *message;
        int len;
        FILE *f;
        struct stat st;
        int j;

        if (argc != 2) {
                printf("You must filename as a first argument\n");
                return 1;
        }

        f = fopen(argv[1], "r");
        if (!f) {
                printf("Cannot open file \"%s\" for read\n", argv[1]);
                return 2;
        }
        fstat(fileno(f), &st);
        len = st.st_size;

        message = (unsigned char *) malloc(len);
        if (!message) {
                printf("Unable to alocace memory for message\n");
                fclose(f);
                return 3;
        }
        if (fread(message, 1, len, f) != len) {
                printf("Error reading file\n");
                fclose(f);
                free(message);
                return 4;
        }
        fclose(f);

        decode_message(message, len);
        for(j = 0; j < len; j++){
                putchar(message[j]);
        }
        free(message);
        return 0;
}




Additional Hints (No hints available.)