Lab03

advertisement
CS449, Introduction to Systems Software, Spring 2007
TA: Ricardo Villamarín-Salomón
Lab #3
Note: Exercises 1-3 are for testing your understanding of the concepts and to allow you
to practice. Exercise 4 is a bit more difficult. If you prefer, you can do just exercise 4
which will give you points for a graded Lab that we are going to have during the next
weeks.
Exercise 1: Array Declarations (theory)
All of these declarations have a problem: identify it and then write down the correct
version
char usernames[] = {“lcnsi”, “billg”, “hjt43”};
int primes = {1, 2, 3, 5};
double weights[][] = {{80.5, 76.9, 94.3}, {115.0, 102.6, 120.1}};
short matrix[][][2] = {{ {4, 1}, {5, 3} }, { {4, 1}, {5, 3} }};
Exercise 2: Static Arrays
a) What is the output of the program shown in Listing 1?
Listing 1
#include <stdio.h>
void statarray( int incr )
{
static int arr[5] = {1,2,3,4,5};
int k;
for (k=0; k<5; k++)
{
printf("%d\t", arr[k]);
-1/6-
arr[k] = arr[k] + incr;
}
printf("\n");
}
int main()
{
int i;
for (i=1; i<=3; i++)
statarray(i);
return 0;
}
b) Remove the word static from Listing 1 and run the program again. Are the outputs
of the two versions similar? Explain why they are similar or why they are different
Exercise 3: Arrays as parameters (practice)
a. Write a program that declares and initializes an array of N integers (say N=10) and
then pass this array to a function that returns the sum of its element. You can either
initialize the array in your code or ask the user for the initial values.
b. Modify your program of the previous point and declare an additional array of the
same size and then, after initializing the first array (either directly or asking the user
for the values) and copy the first array’s the elements to the second array. Pass this
second array to the sum function and print the sum that is returned.
In the first case the array is passed by reference while in the second case, it would what
the program will have to do to pass it by value. Which program seems to be more
efficient?
Exercise 4. Crytography1
Write a program that encrypts and decrypts a text entered by the user following these
steps:

Asks the user to enter a text with alphanumeric characters (A-Z, a-z, 0-9), no spaces
or any other character is allowed
1
Please read below some definitions (encryption, decryption) if you are not familiar at all with
cryptography
-2/6-



Check that only alphanumeric characters have been entered. If not, print an error and
exit.
If the text contains only alphanumeric characters then call a function that encrypts the
text2. Print the encrypted text.
Call a function that decrypts the text produced in the previous step. Print the
decrypted text and check (visually) that the decrypted text produced by your function
matches the text entered by the user.
The method you are going to use is called the Caesar cipher3 with a shift of 3 characters.
A couple of examples are given below (assumes that your executable is called encdec):
$ ./encdec
Enter the text: abcxyz01789
Encrypted text: defabc34012
Decrypted text: abcxyz01789
$ ./encdec
Enter the text: JOSEPH
Encrypted text: MRVHSK
Decrypted text: JOSEPH
You can use the program in Listing 2 as a starting point.
Listing 2
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MAX_CHARS 20
const char base_Upper = 'A';
const char base_Lower = 'a';
const char base_Digit = '0';
int mod(int a, int n)
{
int modulus = a % n;
if (modulus < 0)
modulus = n + modulus;
return modulus;
}
int validate_entry(char *text_to_validate)
{
int j;
/* you may replace this with something more efficient
if you like */
2
3
You are not allowed to use global arrays
Explained below
-3/6-
for (j=0; j<strlen(text_to_validate); j++)
{
if ( !isalnum(text_to_validate[j]) )
return (j+1);
}
return 0;
}
/*
write your encryption & decryption functions here
*/
int main()
{
char entry[MAX_CHARS];
char enc_entry[MAX_CHARS];
char dec_entry[MAX_CHARS];
printf("Enter the text: ");
/* Warning: we are using 'gets' here for simplicity,
but in general you should avoid this function */
gets(entry);
int result = validate_entry(entry);
if (!result) /* if (result == 0) */
{
/*
call your enc/dec functions here
*/
}
else
{
printf("Invalid text entered.");
printf("Illegal character at position: %d\n", (result-1));
}
return 0;
}
You need to know this to solve the exercise:
The behavior of the modulus operator (%) in C is undefined for negative results. Use the function mod
provided to you instead of %
int modulus1 = -3 % 26; /* result is implementation-specific */
int modulus2 = mod(-3, 26); /* gives the correct result. See Listing 2 */
These ASCII codes are important:
65 = 'A'
97 = 'a'
48 = '0'
You must take into consideration the above codes before applying a modulus for the Caesar cipher
-4/6-
algorithm
There is a correspondence between chars and ints in C. For example:
int upperA = 'A'; /* upperA == 65 */
int B = 'A' + 1; /* B == 66 */
printf("%d %c", B, B); /* prints: 66 B */
int modA = 'A' % 64; /* modA == 1 */
The following functions are declared in ctype.h (you can pass them a char instead of an int as
parameter):
int
int
int
int
int
isalpha(int
isupper(int
islower(int
isdigit(int
isalnum(int
c);
c);
c);
c);
c);
//
//
//
//
//
returns 1 if c
returns 1 if c
returns 1 if c
function tests
returns 1 if c
is the code of a character A-Z or a-z
is the code of a letter in uppercase
is the code of a letter in lowercase
for any decimal-digit character: 0-1
is the code of a character A-Z or a-z,0-1
There are 26 letters in the alphabet, but only 10 numbers, so you have to take that detail into consideration.
Cryptography4
The word cryptography comes from the greek word kryptós ("hidden"), and the verb
gráfo ("write"). More generally people think of cryptography as the art of mangling
information into apparent intelligibility in a manner allowing a secret method of
unmangling.
A text in its original form is called “plaintext” while the mangled text is called
“ciphertext”. The process of producing ciphertext from plaintext is called “encryption”.
The reverse of encryption is called decryption.
Caesar cipher5
Caesar cipher is one of the simplest and most widely-known encryption techniques. It is a
“substitution” cipher in which each letter in the plaintext is replaced (substituted) by a
letter some fixed number of positions further down the alphabet. For example, with a
shift of 3, A would be replaced by D, B would become E, and so on. The method is
named after Julius Caesar, who used it to communicate with his generals.
The image below illustrates this idea:
This section come from the book “Network Security: Private Communication in a Public World,” 2nd ed.,
by Kaufman, R. Perlman, and M. Speciner
5
This section comes from Wikipedia
4
-5/6-
Example
The transformation can be represented by aligning two alphabets; the cipher alphabet is
the plain alphabet rotated left or right by some number of positions. For instance, here is
a Caesar cipher using a right rotation of three places (the shift parameter, here 3, is used
as the key):
Plain:
ABCDEFGHIJKLMNOPQRSTUVWXYZ
Cipher: DEFGHIJKLMNOPQRSTUVWXYZABC
To encipher a message, simply look up each letter of the message in the "plain" line and
write down the corresponding letter in the "cipher" line. To decipher, do the reverse.
Plaintext:
THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG
Ciphertext: WKH TXLFN EURZQ IRA MXPSV RYHU WKH ODCB GRJ
The encryption can also be represented using modular arithmetic by first transforming the
letters into numbers, according to the scheme, A = 06, B = 1,..., Z = 25. Encryption of a
letter x by a shift n can be described mathematically as,
Decryption is performed similarly,
Notes:
There are different definitions for the modulo operation. In the above, the result is in the
range 0..25. i.e., if x+n or x-n are not in the range 0..25, we have to subtract or add 26.
For the case of digits (0-9), remember that you should use 10 instead of 26.
6
Note that A = 65 in ASCII, not 0
-6/6-
Download