Morse Code Encoder/Decoder
A Programming Adventure
Samuel Morse
Introduction
Every once in a while I think of interesting and odd programming tasks/projects. I wake up in the morning and some random idea comes to mind. I write it down, throw some requirements on paper and write a few sentences on how I plan to write it. After some well writen words I begin.Samuel Morse
This time around I decided to read up on Samuel Morse; after all, computing in general shares allot with Morse code. I consider Samuel Morse to be one of the earliest computer language architects; he unknowingly created a basic language of communication with two symbols dot (.) and dash (-) (a synonym with binary 1s and 0s). The symbols in sequence and in specific order can create a wide range of codes that are mapped to individual alphabetic characters; I think of them as another translation mechanism such as ASCII. There is a great book by Charles Petzold that describes Morse code in very cool detail:Code by Charles Petzold
The Morse code system is quite impressive.
Morse Code Encoder/Decoder Implementation
My objective was to write an Morse code encoder and decoder. Since the translation table is available on the net, I took the tables and created some functions that would be capable of reading a character or code and output its relevant value. This way, any string could be encoded or decoded quickly.I knew that the Morse code would probably be dependent on the character. I first created a translation table based on a switch block that would check for an ASCII code and then output the relevant Morse code. This was bad; when I needed to decode back to an alphabetic character, it caused some issues: I was unable to decode easily because the ASCII code was not in a particularly easy order (A=65, etc).
I decided to write two tables:
char alpha_codes[] = {
'*',
'A', 'B', 'C', 'D',
'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L',
'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X',
'Y', 'Z', '1', '2',
'3', '4', '5', '6',
'7', '8', '9', '.',
',', '?', '\\', '!',
'/', '(', ')', '&',
':', ';', '=', '+',
'-', '_', '"', '$',
'@', ' '
};
char *morse_codes[] = {
"undef",
".-", "-...", "-.-.", "-..",
".", "..-.", "--.", "....",
"..", ".---", "-.-", ".-..",
"--", "-.", "---", ".--.",
"--.-", ".-.", "...", "-",
"..-", "...-", ".--", "-..-",
"-.--", "--..", "-----", "..---",
"...--", "....-", ".....", "-....",
"--...", "---..", "----.", ".-.-.-",
"--..--", "..--..", ".----.", "-.-.--",
"-..-.", "-.--.", "-.--.-", ".-...",
"---...", "-.-.-.", "-...-", ".-.-.",
"-....-", "..--.-", ".-..-.", "...-..-",
".--.-.", " "
};
Then four functions:
char *GetMorseCode(int index){
return morse_codes[index];
}
char GetAlphaCode(int index){
return alpha_codes[index];
}
int GetAlphaCodeIndex(const char c){
unsigned int ret = 0;
unsigned count = (sizeof(alpha_codes) / sizeof(alpha_codes[0]));
for(int i = 0; i < count; i++){
if(c == GetAlphaCode(i)){
ret = i;
break;
}
}
return ret;
}
int GetMorseCodeIndex(const char *morse){
unsigned int ret = 0;
unsigned int count = (sizeof(morse_codes) / sizeof(morse_codes[0]));
for(int i = 0; i < count; i++){
if(strcmp(GetMorseCode(i), morse) == 0){
ret = i;
break;
}
}
return ret;
}
The first function simply returns a string of Morse code based on an index. This allows a Morse code to be called easily from index 0 to it's max; the same is performed for alphabetic characters. The third/forth functions take a character/morse code as their argument which in turn returns the index of the character/morse code within the array. The comparison of the character is made with a strcmp() function instead of the ASCII code. This is far more flexible than the switch() translation table. With these tables in place, it simplified both encoding and decoding since all I needed was to know each table's index value.
Translating from an alpha character to Morse is:
GetMorseCode(GetAlphaCodeIndex('A'));
And from Morse code to Alpha:
GetAlphaCode(GetMorseCodeIndex(".-"));
No comments:
Post a Comment