Problem
The problem at hand is decoding a string. This is done by converting code from Pascal into the C language.
1. Define the decoded string as a global array of char's and the coded string as a global array of int's:
Code:
char plain[4];
int coded[3] = {0xdd9134c7,0xa5438229,0xcfbcb417,0};
2. Implement three functions
¤ int codgen(int *seed:_addr) this function should take an address to seed
as an argument.
¤ int decode(int *wordarr, char *bytearr, int *seed_addr): this function should take addresses to wordarr, bytearr, and seed as arguments.
¤ int main(void): this is the main funtion, the entry point of the program. The main function should initialize seed as a local variable and invoke decode(coded, plain, &seed)
3. To test the implementation
Include the header file stdio.h and add a print-out using printf() at the end of the main function. Compile the program using gcc (gcc -o lab4 lab4.c) and execute it (./lab4).
Pseudocode (given in the instruction)
Codeword Generator Subroutine (pseudocode)
(remember: "seed" is a global variable 0x624d24b8, UNSIGNED INTEGER;
FUNCTION cogen(): UNSIGNED INTEGER;
LOCAL SIGNED INTEGER n;
LOCAL UNSIGNED INTEGER x, y:
BEGIN n := [right-justify the five bits "seed"<24:20>, and zero-extend];
WHILE (n >= 0) LOOP
x := [shift "seed" left-logical by 3 bits];
y := [divide "seed" (unsigned!) by the constant 16];
seed := x - y; [ignore overflow condition]
n := n - 1;
ENDLOOP
RETURN(seed XOR 0x0176f7df);
END
hint: if "seed" is initialized to 0x34a7ac2c, the first five calls will generate these values:
0x1d21502a, 0x4a0a7254, 0x9168b479, 0xb97433fe, 0xb5e30319,...
Recursive Decoding Subroutine (pseudocode)
FUNCTION decode(wordarr,bytearr): UNSIGNED INTEGER;
(wordarr, bytearr passed by reference)
LOCAL UNSIGNED INTEGER m, r, x, y;
BEGIN
x := ONE'S - COMPLEMENT of codgen();
IF ([contents of word at "wordarr"] = 0) THEN
[byte pointed to by "bytearr"] := 0;
r := x;
ELSE
y := decode(wordarr+,bytearr+);
m = (x XOR y) - [contents of word at "wordarr"];
[byte pointed to by "bytearr"] := [the eight bits at "m"<21:14>];
r := TWO'S - COMPLEMENT OF codgen();
r = x + y + m + r + 5;
ENDIF
RETURN(r);
END
[B]My code
Actually, I get the first function working just fine, the problem is with the second function.
Code:
/* define data */
#include <stdio.h>
char plain[4];
int coded[3] = {0xdd9134c7,0xa5438229,0xcfbcb417,0};
int a;
int b;
unsigned int seed;
int* pseed;
unsigned int codgen( int *seed_addr );
unsigned int decode( int *wordarr, char *bytearr, int *seed_addr);
/* main function */
int main ( void )
{
seed = 0x624d24b8;
pseed = &seed;
decode( coded, plain, &seed);
}
/* codgen function */
unsigned int codgen ( int *seed_addr )
{
unsigned int x;
unsigned int y;
int n = seed >> 20; /* shift "seed" right-logical by 20 bits */
n = n & 0x1f; /* isolate the 5 bits to the very right */
while( n >= 0){
x = seed << 3; /* shift "seed" left-logical by 3 bits */
y = seed >> 4; /* shift '"seed" right-logical by 4 bits */
seed = x - y; /* calculate the new seed */
n--;
}
unsigned int v = seed ^ 0x0176f7df; /* seed XOR 0x0176f7df */
printf( "\n v = %08x \n \n",v ); /*print v */
return v;
}
/* decode function */
unsigned int decode( int *wordarr, char *bytearr, int *seed_addr )
{
unsigned int m;
unsigned int r;
unsigned int x;
unsigned int y;
x = ~ codgen(seed); /* ONE'S COMPLEMENT OF codgen() */
if ( coded[a] == 0) {
plain[b] = 0;
r = x;
}
else {
a++;
b++;
y = decode( coded + 1, plain + 1, seed);
}
while ( b >= 0 ) {
m = x ^ y - plain[b];
m = m >> 14;
m = m & 0xff;
printf( "\n m = %08x \n \n", m )
plain = m;
x = ~ codgen(seed);
r = x + 1;
r = x + y + m + r + 5;
b--;
}
return r;
}
Comments
The codgen function is working properly, I get the correct reference values when initializing the seed to 0x34a7ac2c.
In the decode function I want to write the decoded values to the plain array, but it seems like the variable m in my code is an integer and I don't know how to deal with it. I checked the "integer to string conversion" but it does not seem to apply in my case. I know that the results should be a string with the content "abc" but I get nowhere near that.