2 * Morse Code Translator Java class
4 * Copyright (C) 2015 Antonio Ospite <ao2@ao2.it>
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 * ---------------------------------------------------------------------------
21 * The code was initially based on:
23 * - Morse.java by Stephen C Phillips:
24 * http://morsecode.scphillips.com/Morse.java
25 * Copyright (C) 1999-2004 Stephen C Phillips <steve@scphillips.com>
27 * - NMorse.java by Michael R Ditto:
28 * http://www.omnicron.com/~ford/java/NMorse.java
29 * Copyright (C) 2001 Michael R Ditto <ford@omnicron.com>
31 * ---------------------------------------------------------------------------
33 * The specification of the International Morse Code is in ITU-R M.1677-1
36 * The terminology used here may differ from the one used in some other
37 * places, so here is some nomenclature:
39 * symbol: one of . (dot), - (dash), ' ' (signal separator),
40 * '/' (word separator)
42 * character: a letter of the alphabet, a number, a punctuation mark, or
43 * a ' ' (text word separator)
45 * signal: a sequence of . and - symbols which encode a character,
46 * or a '/' (Morse word separator)
48 * word: a sequence of characters not containing a ' ', or
49 * a sequence of signals not containing a '/'
51 * text: a sequence of characters
53 * morse: a sequence of signals separated by ' '
56 * signals are separated by a ' ' (signal separator), characters are not
57 * separated one from the other.
59 * This class defines a subset of the signals in Section 1 of the
60 * aforementioned specification, plus a word space, and it does not make
61 * assumptions about their actual transmission.
64 package it.ao2.util.morse;
66 import java.util.Arrays;
67 import java.util.Enumeration;
68 import java.util.Hashtable;
69 import java.util.Iterator;
70 import java.util.Locale;
72 public class MorseTranslator {
73 private Hashtable<Character, String> mSignalsTable;
74 private Hashtable<String, Character> mCharactersTable;
76 public MorseTranslator() {
77 mSignalsTable = new Hashtable<Character, String>();
80 mSignalsTable.put(Character.valueOf('a'), ".-");
81 mSignalsTable.put(Character.valueOf('b'), "-...");
82 mSignalsTable.put(Character.valueOf('c'), "-.-.");
83 mSignalsTable.put(Character.valueOf('d'), "-..");
84 mSignalsTable.put(Character.valueOf('e'), ".");
85 mSignalsTable.put(Character.valueOf('f'), "..-.");
86 mSignalsTable.put(Character.valueOf('g'), "--.");
87 mSignalsTable.put(Character.valueOf('h'), "....");
88 mSignalsTable.put(Character.valueOf('i'), "..");
89 mSignalsTable.put(Character.valueOf('j'), ".---");
90 mSignalsTable.put(Character.valueOf('k'), "-.-");
91 mSignalsTable.put(Character.valueOf('l'), ".-..");
92 mSignalsTable.put(Character.valueOf('m'), "--");
93 mSignalsTable.put(Character.valueOf('n'), "-.");
94 mSignalsTable.put(Character.valueOf('o'), "---");
95 mSignalsTable.put(Character.valueOf('p'), ".--.");
96 mSignalsTable.put(Character.valueOf('q'), "--.-");
97 mSignalsTable.put(Character.valueOf('r'), ".-.");
98 mSignalsTable.put(Character.valueOf('s'), "...");
99 mSignalsTable.put(Character.valueOf('t'), "-");
100 mSignalsTable.put(Character.valueOf('u'), "..-");
101 mSignalsTable.put(Character.valueOf('v'), "...-");
102 mSignalsTable.put(Character.valueOf('w'), ".--");
103 mSignalsTable.put(Character.valueOf('x'), "-..-");
104 mSignalsTable.put(Character.valueOf('y'), "-.--");
105 mSignalsTable.put(Character.valueOf('z'), "--..");
107 mSignalsTable.put(Character.valueOf('1'), ".----");
108 mSignalsTable.put(Character.valueOf('2'), "..---");
109 mSignalsTable.put(Character.valueOf('3'), "...--");
110 mSignalsTable.put(Character.valueOf('4'), "....-");
111 mSignalsTable.put(Character.valueOf('5'), ".....");
112 mSignalsTable.put(Character.valueOf('6'), "-....");
113 mSignalsTable.put(Character.valueOf('7'), "--...");
114 mSignalsTable.put(Character.valueOf('8'), "---..");
115 mSignalsTable.put(Character.valueOf('9'), "----.");
116 mSignalsTable.put(Character.valueOf('0'), "-----");
117 // Punctuation marks and miscellaneous signs
118 mSignalsTable.put(Character.valueOf('.'), ".-.-.-");
119 mSignalsTable.put(Character.valueOf(','), "--..--");
120 mSignalsTable.put(Character.valueOf(':'), "---...");
121 mSignalsTable.put(Character.valueOf('?'), "..--..");
122 mSignalsTable.put(Character.valueOf('\''), ".----.");
123 mSignalsTable.put(Character.valueOf('-'), "-....-");
124 mSignalsTable.put(Character.valueOf('/'), "-..-.");
125 mSignalsTable.put(Character.valueOf('('), "-.--.-");
126 mSignalsTable.put(Character.valueOf(')'), "-.--.-");
127 mSignalsTable.put(Character.valueOf('"'), ".-..-.");
128 mSignalsTable.put(Character.valueOf('='), "-...-");
129 mSignalsTable.put(Character.valueOf('+'), ".-.-.");
130 mSignalsTable.put(Character.valueOf('x'), "-..-");
131 mSignalsTable.put(Character.valueOf('@'), ".--.-.");
133 // Represent the word space as a signal with only one "/" symbol
134 mSignalsTable.put(Character.valueOf(' '), "/");
136 mCharactersTable = new Hashtable<String, Character>();
138 Enumeration<Character> list = mSignalsTable.keys();
139 while (list.hasMoreElements()) {
140 Character c = list.nextElement();
141 String s = mSignalsTable.get(c);
142 mCharactersTable.put(s, c);
146 public String sanitizeText(String text) {
147 String sanitizedText;
149 sanitizedText = text.toLowerCase(Locale.US);
150 sanitizedText = sanitizedText.replaceAll("[^a-z0-9.,:?\'/()\"=+;_$@ -]", "");
151 sanitizedText = sanitizedText.replaceAll("\\s+", " ");
152 return sanitizedText;
155 public String charToSignal(Character character) {
156 character = Character.toLowerCase(character);
158 if (mSignalsTable.containsKey(character)) {
159 return mSignalsTable.get(character);
165 public String textToMorse(String text, boolean sanitize) {
167 text = sanitizeText(text);
170 StringBuffer morse = new StringBuffer();
171 for (int i = 0; i < text.length(); i++) {
172 //Character ch = Character.valueOf(text.charAt(i));
173 Character character = text.charAt(i);
175 morse.append(charToSignal(character));
177 if (i < text.length() - 1) {
182 return morse.toString();
185 public String textToMorse(String text) {
186 return textToMorse(text, true);
189 public String sanitizeMorse(String morse) {
190 String sanitizedMorse;
192 sanitizedMorse = morse.replaceAll("_", "-");
193 sanitizedMorse = sanitizedMorse.replaceAll("[^\\-\\.\\/]", " ");
194 sanitizedMorse = sanitizedMorse.replaceAll("\\s+", " ");
195 sanitizedMorse = sanitizedMorse.replaceAll("( ?/ ?)+", " / ");
196 return sanitizedMorse;
199 public Character signalToCharacter(String signal) {
200 if (mCharactersTable.containsKey(signal)) {
201 return mCharactersTable.get(signal);
207 public String morseToText(String morse, boolean sanitize) {
209 morse = sanitizeMorse(morse);
212 StringBuffer text = new StringBuffer();
213 Iterator<String> signals = Arrays.asList(morse.split(" ")).iterator();
214 while (signals.hasNext()) {
215 String signal = signals.next();
216 text.append(signalToCharacter(signal));
219 return text.toString();
222 public String morseToText(String morse) {
223 return morseToText(morse, true);