HOME | 6. IO | Try Sather | 8. Parameterized Classes | download | Post Messages |
As shown in The Online Sather Code Browser, most of inheritances are done using abstract classes and conventional ones are used only at the end of the inheritance.
You can make a flexible data type by combining the abstract classes and parametrized classes which I mention in the next chapter.
Encryption algorithm should have at least two methods, encrypt and decrypt.
An abstract class $CRYPT is defied in the [code 1] and these two methods are
declared in it.
For simplification, I just define two algorithms:
one is PLAIN which does nothing.
The other is XOR which output a XOR-ed stream from the input and the key.
I defined another abstract class named $MESSAGE which have two methods,
send and receive.
Finally, I defined two communication methods, one is USUAL which uses plain text
and the other is IMPORTANT which uses cypher.
[code 1]
01: -- an example of abstract class; $CRYPT and $MESSAGE
02:
03:
04: -- algorithm for cryptogram
05: abstract class $CRYPT is -- The abstract class for cypher algorithm. The names of the abstract classes starts with $ and consists of all capital.
06: encrypt(s:STR):STR; -- method for encryption
07: decrypt(s:STR):STR; -- for decryption
08: end; -- end $CRYPT
09:
10: -- cipher message
11: abstract class $MESSAGE is -- The abstract class of message
12: send(s:STR):STR;
13: receive(s:STR):STR;
14: end; -- end $MESSAGE
15:
16: -- Plain text
17: class PLAIN < $CRYPT is -- do nothing algorithm.
18: create:SAME is
19: return new;
20: end;
21:
22: encrypt(s:STR):STR is
23: return s;
24: end;
25:
26: decrypt(s:STR):STR is
27: return s;
28: end;
29: end; -- end PLAIN
30:
31: -- Simple XOR cryptogram
32: class XOR < $CRYPT is -- the XOR algorithm
33:
34: private attr keylist:ARRAY{INT};
35:
36: create(key:STR):SAME is
37: return new.init(key);
38: end;
39:
40: private init(key:STR):SAME is
41: keylist:=#(key.size);
42: loop
43: keylist.set!(key.elt!.int); -- store the key as an array of integer
44: end;
45: return self;
46: end;
47:
48: private key_rotate!:INT is -- It return the next element when called.
49: i:INT:=0;
50: n:INT:=keylist.size-1;
51: loop
52: yield keylist[i];
53: if i=n then
54: i:=0;
55: else
56: i:=i+1;
57: end;
58: end;
59: end;
60:
61: encrypt(s:STR):STR is
62: fs:FSTR:=#(s.size); -- FSTR is mutable strings
63: loop
64: fs := fs + s.elt!.int.bxor(key_rotate!).char; -- appending the XOR-ed character at the end of fs.
65: end;
66: return fs.str;
67: end;
68:
69: decrypt(s:STR):STR is -- In the XOR algorithm, encryption and description procedures are same.
70: return encrypt(s);
71: end;
72: end; -- end of XOR
73:
74: partial class MESSAGE < $MESSAGE is -- defining the common part of message
75: stub cry:$CRYPT; -- encryption algorithm, should be defined in child classes.
76:
77: send(s:STR):STR is
78: return cry.encrypt(s);
79: end;
80:
81: receive(s:STR):STR is
82: return cry.decrypt(s);
83: end;
84: end; -- end MESSAGE
85:
86: -- Plain Message
87: class USUAL < $MESSAGE is
88: include MESSAGE;
89: private const cry:PLAIN:=PLAIN::create; -- cannot use #PLAIN here.
90:
91: create:SAME is
92: return new;
93: end;
94: end; -- end USUAL
95:
96: -- Cipher Message
97: class IMPORTANT < $MESSAGE is
98: include MESSAGE;
99: private attr cry:XOR;
100:
101: create(key:STR):SAME is
102: return new.init(key);
103: end;
104:
105: private init(key:STR):SAME is
106: cry:=#(key);
107: return self;
108: end;
109: end; -- end IMPORTANT
110:
111: class MAIN is
112:
113: private const key:STR:= "qwertyuiop@asdfghjkl;zxcvbnm,"; -- key for XOR
114:
115: main(av: ARRAY{STR}) is
116: if av.size=2 then
117: plain:USUAL:= #;
118: sixor:IMPORTANT:=#(key);
119: msg:STR:=av[1]; -- encrypt the first argument.
120: plain_send:STR:=plain.send(msg);
121: plain_receive:STR:=plain.receive(plain_send);
122: xor_send:STR:=sixor.send(msg);
123: xor_receive:STR:=sixor.receive(xor_send);
124: #OUT + "Cipher Test using \"" + msg + "\"\n\n";
125: #OUT + "Plain send: " + plain_send + "\n";
126: #OUT + "Plain receive: " + plain_receive + "\n\n";
127: #OUT + "XOR send: " + xor_send + "\n";
128: #OUT + "XOR receive: " + xor_receive + "\n\n";
129: else
130: #ERR + "Usage: crypt \'STRING\'\n";
131: end;
132: end;
133: end; -- end of MAIN
Following shows the result.
$ sacomp crypt.sa -o crypt
$ ./crypt 'Welcome to Sather World.'
Cipher Test using "Welcome to Sather World."
Plain send: Welcome to Sather World.
Plain receive: Welcome to Sather World.
XOR send: (non graphical string)
XOR receive: Welcome to Sather World.
As the encryption algorithm is an abstract class, you can change the algorithm without changing other parts of the program.
If you wants AES, for instance, just modify line 99 like as follows.
99: private attr cry:AES;
3. Equipped abstract classes
Following table shows frequently used abstracted classes equipped in Sather.
See
The Online Sather Code Browser.
You can find a detailed explanation and a graph that shows class relations.
Class Name | Interface | Explanation |
---|---|---|
$OB | All classes are children of $OB. | |
$IS_EQ | is_eq(e:$OB):BOOL; | It returns true if self and e are equal. |
$IS_LT | is_lt(e:T):BOOL; | It returns true if self is smaller than e. This is a subclass of $IS_EQ. |
$IS_NIL | is_nil:BOOL; | It returns true if self is nil. |
$NIL | nil:SAME; | It makes self nil. |
$STR | str:STR | It converts self to a string. Most classes are subclass of $STR. |
$NEF{NTP} | abs, plus, minus, tiems, div, ... | It is a class of algebra. Classes $NUMBER{NTP} and $CPX_NUMBER{ETP} are subclass of this. |
$ELT | elt!:$OB | It defines iterator elt!. It is the parent of $ELT{T}. |
$ELT{T} | elt!:T | It defines iterator elt! in practice. |
$CONTAINER{ETP} | copy, has, size | It is a container class. Most of parameterized classes are subclass of this. |
$HASH | hash | It calculates hash values. Only subclasses of $HASH can be keys of hash tables. |
I will explain about parameterized classes in the next chapter.
HOME | 6. IO | Try Sather | 8. Parameterized classes | download | Post Messages |