## Character Data

Goals: To gain experience working with character data in Scheme.

Preparation: Reread the material on characters of the Revised Report(4) on the Algorithmic Language Scheme, and pages 9 and 10 of the text.

Character Data: Scheme differentiates between symbols and characters. Quoted characters like 'a are treated as symbols and are not recognized as character data:

```
'a --> a
(symbol? 'a) --> #t
(char? 'a) --> #f
```
Character data in Scheme must be entered using the #\name notation instead of quoting, where name is the name of a character:
```
#\a --> #\a
(symbol? #\a) --> #f
(char? #\a) --> #t
(char? #\space) --> #t
```
For practice, let's write some Scheme functions that will allow us to convert lists of characters into ``secret messages'' that can be decoded only by somebody who knows the right trick. Scheme already provides the char->integer function, that converts an individual character into its corresponding integer representation. For our secret code, we could just convert lists of characters into lists of integers with the help of this function. The person at the other end could convert the integers back to characters via the integer->char function.

This coding scheme is simple to implement, but not very secret, as the encoding is easily guessed. To make our code more difficult to crack, we'll add a fixed value to each of the integers in our coded message. The person decoding the message must also know the fixed value we used during the encoding or they'll get a garbled message back.

For example, we can use the following function to encode a given character c, where key is the value we'll add to each coded integer:

```
(define encrypt-char
(lambda (c key)
(+ key (char->integer c))
)
)

(encrypt-char #\h 0) --> 104    ;; 104 is the integer rep. of "h"
(encrypt-char #\h 5) --> 109    ;; A non-zero "key" added in
```

Steps for this Lab:

1. Write a function decrypt-char that will "undo" the encoding performed by encrypt-char.
```
(decrypt-char 104 0) --> #\h
(decrypt-char 109 5) --> #\h
```
2. Write a recursive routine encrypt-chars that takes a list of characters and encodes each of them by calling encrypt-char above. The function will take two arguments: The list of characters to be encoded, and the secret "key" to be added to each coded integer.
```
(encrypt-chars '(#\h #\e #\l #\l #\o) 0) --> (104 101 108 108 111)
(encrypt-chars '(#\h #\e #\l #\l #\o) 5) --> (109 106 113 113 116)
(encrypt-chars '() 5) --> ()
```
3. Write a recursive routine decrypt-chars that takes a "secret message" (a list of integers) and returns the corresponding list of characters. (This function will end up looking very much like the encrypt-chars function, with a couple of minor differences.)
```
(decrypt-chars '(104 101 108 108 111) 0) --> (#\h #\e #\l #\l #\o)
(decrypt-chars '(109 106 113 113 116) 5) --> (#\h #\e #\l #\l #\o)
(decrypt-chars '(109 106 113 113 116) 0) --> (#\m #\j #\q #\q #\t)
```
4. The integer->char function produces an error if its argument is negative. This means that decrypt-chars could generate an error if the user specifies a incorrect key that is much larger than the key used during encoding:
```
(decrypt-chars '(104 101 108 108 111) 150) --> ERROR
```
Modify decrypt-char so that it catches the condition that causes this error and returns the character #\X instead of producing an error. The resulting behavior for decrypt-chars should be:
```
(decrypt-chars '(104 101 108 108 111) 150) --> (#\X #\X #\X #\X #\X)
```
5. Scheme guarantees that the ranges of digits, uppercase letters, and lowercase letters do not overlap, but it does not specify how these ranges are ordered with respect to each other. Show the results of three calls to the char function that determine how the ranges are ordered in our Scheme implementation. (For example, do the numbers come before all letters, between the uppercase and lowercase letters, or after all letters in the character ordering?)

This document is available on the World Wide Web as

```http://www.math.grin.edu/~walker/courses/151/lab-char-data.html
```

created February 26, 1997
last revised March 3, 1997