/* * Morse Code Translator Java class * * Copyright (C) 2015 Antonio Ospite * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * --------------------------------------------------------------------------- * * The code was initially based on: * * - Morse.java by Stephen C Phillips: * http://morsecode.scphillips.com/Morse.java * Copyright (C) 1999-2004 Stephen C Phillips * * - NMorse.java by Michael R Ditto: * http://www.omnicron.com/~ford/java/NMorse.java * Copyright (C) 2001 Michael R Ditto * * --------------------------------------------------------------------------- * * The specification of the International Morse Code is in ITU-R M.1677-1 * (10/2009), Annex 1. * * The terminology used here may differ from the one used in some other * places, so here is some nomenclature: * * symbol: one of . (dot), - (dash), ' ' (signal separator), * '/' (word separator) * * character: a letter of the alphabet, a number, a punctuation mark, or * a ' ' (text word separator) * * signal: a sequence of . and - symbols which encode a character, * or a '/' (Morse word separator) * * word: a sequence of characters not containing a ' ', or * a sequence of signals not containing a '/' * * text: a sequence of characters * * morse: a sequence of signals separated by ' ' * * NOTE: * signals are separated by a ' ' (signal separator), characters are not * separated one from the other. * * This class defines a subset of the signals in Section 1 of the * aforementioned specification, plus a word space, and it does not make * assumptions about their actual transmission. */ package it.ao2.util.morse; import java.util.Arrays; import java.util.Enumeration; import java.util.Hashtable; import java.util.Iterator; import java.util.Locale; public class MorseTranslator { private Hashtable mSignalsTable; private Hashtable mCharactersTable; public MorseTranslator() { mSignalsTable = new Hashtable(); // Letters mSignalsTable.put(Character.valueOf('a'), ".-"); mSignalsTable.put(Character.valueOf('b'), "-..."); mSignalsTable.put(Character.valueOf('c'), "-.-."); mSignalsTable.put(Character.valueOf('d'), "-.."); mSignalsTable.put(Character.valueOf('e'), "."); mSignalsTable.put(Character.valueOf('f'), "..-."); mSignalsTable.put(Character.valueOf('g'), "--."); mSignalsTable.put(Character.valueOf('h'), "...."); mSignalsTable.put(Character.valueOf('i'), ".."); mSignalsTable.put(Character.valueOf('j'), ".---"); mSignalsTable.put(Character.valueOf('k'), "-.-"); mSignalsTable.put(Character.valueOf('l'), ".-.."); mSignalsTable.put(Character.valueOf('m'), "--"); mSignalsTable.put(Character.valueOf('n'), "-."); mSignalsTable.put(Character.valueOf('o'), "---"); mSignalsTable.put(Character.valueOf('p'), ".--."); mSignalsTable.put(Character.valueOf('q'), "--.-"); mSignalsTable.put(Character.valueOf('r'), ".-."); mSignalsTable.put(Character.valueOf('s'), "..."); mSignalsTable.put(Character.valueOf('t'), "-"); mSignalsTable.put(Character.valueOf('u'), "..-"); mSignalsTable.put(Character.valueOf('v'), "...-"); mSignalsTable.put(Character.valueOf('w'), ".--"); mSignalsTable.put(Character.valueOf('x'), "-..-"); mSignalsTable.put(Character.valueOf('y'), "-.--"); mSignalsTable.put(Character.valueOf('z'), "--.."); // Figures mSignalsTable.put(Character.valueOf('1'), ".----"); mSignalsTable.put(Character.valueOf('2'), "..---"); mSignalsTable.put(Character.valueOf('3'), "...--"); mSignalsTable.put(Character.valueOf('4'), "....-"); mSignalsTable.put(Character.valueOf('5'), "....."); mSignalsTable.put(Character.valueOf('6'), "-...."); mSignalsTable.put(Character.valueOf('7'), "--..."); mSignalsTable.put(Character.valueOf('8'), "---.."); mSignalsTable.put(Character.valueOf('9'), "----."); mSignalsTable.put(Character.valueOf('0'), "-----"); // Punctuation marks and miscellaneous signs mSignalsTable.put(Character.valueOf('.'), ".-.-.-"); mSignalsTable.put(Character.valueOf(','), "--..--"); mSignalsTable.put(Character.valueOf(':'), "---..."); mSignalsTable.put(Character.valueOf('?'), "..--.."); mSignalsTable.put(Character.valueOf('\''), ".----."); mSignalsTable.put(Character.valueOf('-'), "-....-"); mSignalsTable.put(Character.valueOf('/'), "-..-."); mSignalsTable.put(Character.valueOf('('), "-.--.-"); mSignalsTable.put(Character.valueOf(')'), "-.--.-"); mSignalsTable.put(Character.valueOf('"'), ".-..-."); mSignalsTable.put(Character.valueOf('='), "-...-"); mSignalsTable.put(Character.valueOf('+'), ".-.-."); mSignalsTable.put(Character.valueOf('x'), "-..-"); mSignalsTable.put(Character.valueOf('@'), ".--.-."); // Represent the word space as a signal with only one "/" symbol mSignalsTable.put(Character.valueOf(' '), "/"); mCharactersTable = new Hashtable(); Enumeration list = mSignalsTable.keys(); while (list.hasMoreElements()) { Character c = list.nextElement(); String s = mSignalsTable.get(c); mCharactersTable.put(s, c); } } public String sanitizeText(String text) { String sanitizedText; sanitizedText = text.toLowerCase(Locale.US); sanitizedText = sanitizedText.replaceAll("[^a-z0-9.,:?\'/()\"=+;_$@ -]", ""); sanitizedText = sanitizedText.replaceAll("\\s+", " "); return sanitizedText; } public String charToSignal(Character character) { character = Character.toLowerCase(character); if (mSignalsTable.containsKey(character)) { return mSignalsTable.get(character); } else { return ""; } } public String textToMorse(String text, boolean sanitize) { if (sanitize) { text = sanitizeText(text); } StringBuffer morse = new StringBuffer(); for (int i = 0; i < text.length(); i++) { //Character ch = Character.valueOf(text.charAt(i)); Character character = text.charAt(i); morse.append(charToSignal(character)); if (i < text.length() - 1) { morse.append(" "); } } return morse.toString(); } public String textToMorse(String text) { return textToMorse(text, true); } public String sanitizeMorse(String morse) { String sanitizedMorse; sanitizedMorse = morse.replaceAll("_", "-"); sanitizedMorse = sanitizedMorse.replaceAll("[^\\-\\.\\/]", " "); sanitizedMorse = sanitizedMorse.replaceAll("\\s+", " "); sanitizedMorse = sanitizedMorse.replaceAll("( ?/ ?)+", " / "); return sanitizedMorse; } public Character signalToCharacter(String signal) { if (mCharactersTable.containsKey(signal)) { return mCharactersTable.get(signal); } else { return '*'; } } public String morseToText(String morse, boolean sanitize) { if (sanitize) { morse = sanitizeMorse(morse); } StringBuffer text = new StringBuffer(); Iterator signals = Arrays.asList(morse.split(" ")).iterator(); while (signals.hasNext()) { String signal = signals.next(); text.append(signalToCharacter(signal)); } return text.toString(); } public String morseToText(String morse) { return morseToText(morse, true); } }