/**
* Copyright (c) 2014 Matthias Jaenicke <matthias.jaenicke@student.kit.edu>,
* Matthias Plappert <undkc@student.kit.edu>,
* Julien Duman <uncyc@student.kit.edu>,
* Christian Dreher <uaeef@student.kit.edu>,
* Wasilij Beskorovajnov <uajkm@student.kit.edu> and
* Aydin Tekin <aydin.tekin@student.kit.edu>
*
* Released under the MIT license (refer to LICENSE.md)
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package edu.kit.iks.Cryptographics.Caesar.Experiment;
import org.xnap.commons.i18n.I18n;
import edu.kit.iks.CryptographicsLib.Configuration;
/**
* Model for the visualization of Caesar's cipher.
*
* @author Wasilij Beskorovajnov.
*
*/
public class CryptoModel {
// makes sure only one instance is being generated.
private static final CryptoModel model = new CryptoModel();
// ASCII lower case a code.
public final int ASCII_LC_A = 'a';
// ASCII upper case A code.
public final int ASCII_UC_A = 'A';
// The reach of the key interval.
private final int MODULO = 26;
private static I18n i18n = Configuration.getInstance().getI18n(
CryptoModel.class);
public static CryptoModel getInstance() {
return CryptoModel.model;
}
/**
* Constructor.
*/
private CryptoModel() {
}
/**
* Function for encrypting of all sort of String.<br>
* CAREFUL: If you want to encrypt html Strings, make sure all tags are closed!!!!<br>
*
* @param key
* the key parameter for encryption.
* @param text
* the text to encrypt.
* @return the encrypted text.
*/
public String enc(int key, String text) {
// TODO: Check if the String has valid HTML!
String cipher = "";
for (int i = 0; i < text.length(); i++) {
Character c = text.charAt(i);
if (Character.isLetter(c)) {
cipher += String.valueOf(this.shiftChar(key, c));
} else {
if (c != '<') {
cipher += c;
} else {
cipher += c;
while (c != '>') {
i++;
c = text.charAt(i);
cipher += c;
}
}
}
}
return cipher;
}
/**
* Function for decrypting all sort of Strings.
*
* @param key
* the key parameter for decryption.
* @param cipher
* the cipher to decrypt.
* @return decrypted cipher.
*/
public String dec(int key, String cipher) {
return this.enc(-key, cipher);
}
/**
* Generates a random Integer in the range of 1 and 26.
*
* @return the generated key.
*/
public int generateKey() {
return this.generateRandomInt(1, 26);
}
/**
* Generates a random integer in an interval of a and b.
*
* @param a
* the left border of the interval.
* @param b
* the right border of the interval.
* @return the generated integer.
*/
public int generateRandomInt(int a, int b) {
return (int) (a + ((b - a) * Math.random()));
}
/**
* Pulls 'randomly' a string from the local pool.
*
* @return a random string.
*/
public String genRandomBlamings() {
String[] blamingPool = {
CryptoModel.i18n.tr("Oh no. What a pity! It went wrong!"),
CryptoModel.i18n.tr("No my friend. This one doesn't work!"),
CryptoModel.i18n
.tr("Sorry, that was wrong. Don't give up now!") };
int index = this.generateRandomInt(0, blamingPool.length);
return blamingPool[index];
}
/**
* Pulls 'randomly' a plainText from the local pool of genRandomPlainSequence() and encrypts it
* with a given key.
*
* @param key
* @return 'random' cipher.
*/
public String genRandomCipher(int key) {
String plain = this.genRandomPlainSequence();
return this.enc(key, plain);
}
/**
* Pulls 'randomly' a string from the local pool.
*
* @return 'random' string.
*/
public String genRandomGrats() {
String[] gratulationsPool = {
CryptoModel.i18n.tr("Great work, oh mighty Caesar!"),
CryptoModel.i18n.tr("Very nice. I like!"),
CryptoModel.i18n.tr("No one could've done it better!") };
int index = this.generateRandomInt(0, gratulationsPool.length);
return gratulationsPool[index];
}
/**
* Pulls 'randomly' string from the local pool.
*
* @return 'random' string.
*/
public String genRandomPlainSequence() {
String[] plainTextPool = { CryptoModel.i18n.tr("ANNA"),
CryptoModel.i18n.tr("HANNAH"), CryptoModel.i18n.tr("BANANA"),
CryptoModel.i18n.tr("KOKOS"), CryptoModel.i18n.tr("SECRET"),
CryptoModel.i18n.tr("EPSILON") };
int index = this.generateRandomInt(0, plainTextPool.length);
return plainTextPool[index];
}
/**
* Pulls 'randomly' a bigger string from the local pool.
*
* @return the 'random' text.
*/
public String genRandomText() {
String[] textPool = { CryptoModel.i18n
.tr("The diagram you see here shows the frequency of each letter"
+ " in the text you are reading at the moment. It is called a"
+ " Histogram. If you would count all E's in this explanation"
+ " you would get the number you see in the diagram on the column"
+ " above the letter E. Now the program will encrypt this explanation"
+ " with an unknown key in a most awesome way and we will see the "
+ " histogram of the cipher. Click Proceed and see the magic!") } ;
return textPool[0];
}
/**
* Checks if the input is valid.
*
* @param input
* the input to check.
*/
public boolean isInputValid(String input) {
return (input.length() < 10 && input.length() > 0);
}
/**
* Checks if the key is valid.
*
* @param key
* the key to check.
* @return
*/
public boolean isKeyValid(int key) {
return (key > 0 && key <= this.MODULO);
}
private char shiftChar(int key, char charToShift) {
int offset = charToShift - this.ASCII_UC_A;
if (Character.isLowerCase(charToShift)) {
offset = charToShift - this.ASCII_LC_A;
return (char) ((((offset + this.MODULO) + key) % this.MODULO) + this.ASCII_LC_A);
}
return (char) ((((offset + this.MODULO) + key) % this.MODULO) + this.ASCII_UC_A);
}
}