So I've been working on this bit of code for awhile now. It's about encrypting and decrypting a message and producing the two keys used alternatively to encrypt a message using the Caesar Cipher method of changing letters with corresponding letters from a shifted alphabet. For example "Fruit" would be "Hwwnv" according to the shifted alphabets found by implementing +2 to every other letter starting with the first letter, and implementing +5 to every other letter starting with the second letter. I've been using an instance of another class called BreakCaesarThree to find these two keys, dkey_0 and dkey_1 and a decrypted message. I would rather use my method breakCaesarTwo instead, because of the ease of having all my necessary code in one class. How would I go about doing this? How do I change it so that I'm using breakCaesarTwo method instead of BreakCaesarThree class, and still be able to print out the dkey_0 and dkey_1 and a decrypted message? I am hoping that changing to using the breakCaesarTwo method will yield the right results.
Note: Right now calling BreakCaesarThree doesn't yield a decrypted message or give the right keys (I get 0s).
Here's my TestCaesarCipherTwo code which includes the breakCaesarTwo method:
import edu.duke.*;
public class TestCaesarCipherTwo {
private String alphabetLower;
private String alphabetUpper;
private String shiftedAlphabetLower1;
private String shiftedAlphabetUpper1;
private String shiftedAlphabetLower2;
private String shiftedAlphabetUpper2;
private int mainKey1;
private int mainKey2;
private int dkey_0;
private int dkey_1;
/**
*
*/
public void simplebreaker()
{
FileResource fr = new FileResource();
String encrypted = fr.asString();
BreakCaesarThree bct = new BreakCaesarThree();
String broken = bct.decrypt(encrypted);
System.out.println("Keys found: " + bct.dkey_0 + ", " + bct.dkey_1 + "\n" + broken);
}
public String halfOfString(String message, int start) {
StringBuilder halfString = new StringBuilder();
for (int index=start;index < message.length();index += 2) {
halfString.append(message.charAt(index));
}
return halfString.toString();
}
public String decrypt(String input) {
CaesarCipherTwoKeys cctk= new CaesarCipherTwoKeys(26 - mainKey1, 26 - mainKey2);
String decrypted = cctk.encrypt(input);
return decrypted;
}
public int[] countOccurrencesOfLetters(String message) {
//snippet from lecture
String alph = "abcdefghijklmnopqrstuvwxyz";
int[] counts = new int[26];
for (int k=0; k < message.length(); k++) {
char ch = Character.toLowerCase(message.charAt(k));
int dex = alph.indexOf(ch);
if (dex != -1) {
counts[dex] += 1;
}
}
return counts;
}
public int maxIndex(int[] values) {
int maxDex = 0;
for (int k=0; k < values.length; k++) {
if (values[k] > values[maxDex]) {
maxDex = k;
}
}
return maxDex;
}
public void simpleTests()
{
int key1 = 17;
int key2 = 3;
FileResource fr = new FileResource();
String message = fr.asString();
CaesarCipherTwoKeys cctk = new CaesarCipherTwoKeys(key1, key2);
String encrypted = cctk.encrypt(message);
System.out.println(encrypted);
String decrypted = cctk.decrypt(encrypted);
System.out.println(decrypted);
BreakCaesarThree bct = new BreakCaesarThree();
String broken = bct.decrypt(encrypted);
System.out.println("Keys found: " + bct.dkey_0 + ", " + bct.dkey_1 + "\n" + broken);
}
public String breakCaesarTwo(String input) {
String in_0 = halfOfString(input, 0);
String in_1 = halfOfString(input, 1);
// Find first key
// Determine character frequencies in ciphertext
int[] freqs_0 = countOccurrencesOfLetters(in_0);
// Get the most common character
int freqDex_0 = maxIndex(freqs_0);
// Calculate key such that 'E' would be mapped to the most common ciphertext character
// since 'E' is expected to be the most common plaintext character
int dkey_0 = freqDex_0 - 4;
// Make sure our key is non-negative
if (dkey_0 < 0) {
dkey_0 = dkey_0+26;
}
// Find second key
int[] freqs_1 = countOccurrencesOfLetters(in_1);
int freqDex_1 = maxIndex(freqs_1);
int dkey_1 = freqDex_1 - 4;
if (freqDex_1 < 4) {
dkey_1 = dkey_1+26;
}
CaesarCipherTwoKeys cctk = new CaesarCipherTwoKeys(dkey_0, dkey_1);
return cctk.decrypt(input);
}
}
I'd like to implement the changes here:
public void simplebreaker()
{
FileResource fr = new FileResource();
String encrypted = fr.asString();
BreakCaesarThree bct = new BreakCaesarThree();
String broken = bct.decrypt(encrypted);
System.out.println("Keys found: " + bct.dkey_0 + ", " + bct.dkey_1 + "\n" + broken);
}
and here:
public void simpleTests()
{
int key1 = 17;
int key2 = 3;
FileResource fr = new FileResource();
String message = fr.asString();
CaesarCipherTwoKeys cctk = new CaesarCipherTwoKeys(key1, key2);
String encrypted = cctk.encrypt(message);
System.out.println(encrypted);
String decrypted = cctk.decrypt(encrypted);
System.out.println(decrypted);
BreakCaesarThree bct = new BreakCaesarThree();
String broken = bct.decrypt(encrypted);
System.out.println("Keys found: " + bct.dkey_0 + ", " + bct.dkey_1 + "\n" + broken);
I have something like
a = "बिक्रम मेरो नाम हो"
I want to achieve something like in Java
a[0] = बि
a[1] = क्र
a[3] = म
Java internally stores each character of any language in UTF-16(2 bytes) so you can safely access the characters individually.
Try This:
String a = "बिक्रम मेरो नाम हो";
int strLen = a.length();
char array[] = new char[strLen];
String strArray1[] = new String[strLen];
for (int i=0 ; i< strLen ; i++)
{
array[i] = a.charAt(i);
strArray1[i] = Character.toString(a.charAt(i));
System.out.println ("Index = " + i + "* Char = " +array[i] + "** String =" +strArray1[i] );
}
Output:
Index = 0* Char = ब** String =ब
Index = 1* Char = ि** String =ि
Index = 2* Char = क** String =क
Index = 3* Char = ्** String =्
Index = 4* Char = र** String =र
Index = 5* Char = म** String =म
Index = 6* Char = ** String =
Index = 7* Char = म** String =म
Index = 8* Char = े** String =े
Index = 9* Char = र** String =र
Index = 10* Char = ो** String =ो
Index = 11* Char = ** String =
Index = 12* Char = न** String =न
Index = 13* Char = ा** String =ा
Index = 14* Char = म** String =म
Index = 15* Char = ** String =
Index = 16* Char = ह** String =ह
Index = 17* Char = ो** String =ो
Note:
In order to allow eclipse to allow you to save your java program with foreign characters(Hindi alphabets), do the following:
Go to:
"Windows > Preferences > General > Content Types > Text > {Choose file type}
{Selected file type} > Default encoding > UTF-8" and click Update.
Did you try icu4j?
BreakIterator character instance has a possibility to split String to characters
My code is not at all optimized, sorry about that but it works!
Just change the path of the file in which you are going to enter the devnagri sentence and it should work.
public static void main(String[] args) throws IOException
{
BufferedReader br = new BufferedReader(new FileReader("/home/ubuntu/Documents/trainforjava.txt")); //PLEASE ENTER PATH HERE
String[] devFull = new String[]{
"अ","आ", "इ", "ई", "उ", "ऊ", "ऋ"
, "ऌ" ,"ऍ", "ए", "ऐ", "ऑ", "ओ", "औ",
"क", "ख", "ग", "घ" ,"ङ",
"च" ,"छ" ,"ज"," झ"," ञ",
"ट","ठ", "ड"," ढ"," ण",
"त", "थ", "द", "ध", "न",
"प", "फ", "ब"," भ","म",
"य", "र", "ल", "ळ",
"व", "श" ,"ष","स" ,"ह"
};
String[] uniDev = new String[]
{
"905","906","907","908","909","90a","90b",
"90c","90d","90f","910","911","913","914",
"915","916","917","918","919",
"91a","91b","91c","91d","91e",
"91f","920","921","922","923",
"924","925","926","927","928",
"92a","92b","92c","92d","92e",
"92f","930","932","933",
"935","936","937","938","939"
};
String[] devHalf = new String[]
{
"$़","ऽ","$ा","$ि" ,
"$ी", "$ ु","$ू","$ृ","$ॄ","$ॅ",
"$े","$ै","$ॉ",
"$ो","$ौ"
};
String[] gujHalf = new String[]
{
"$઼","ઽ","$ા","$િ" ,
"$ી","$ુ","$ૂ","$ૃ","$ૄ","$ૅ",
"$ે","$ૈ","$ૉ",
"$ો","$ૌ"
};
try
{
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while( (line = br.readLine() ) != null)
{
line=line.replaceAll(" ", ""); //remove white spaces if any
System.out.println();
//System.out.println(line);
int strLength = line.length();
// String a = "बिक्रम मेरो नाम हो";
int strLen = line.length();
char array[] = new char[strLen];
String strArray1[] = new String[strLen];
int mark[] = new int[strLen+1];
String unis[]=new String[strLen];
int cnt=0;
String newCharD[]=new String [strLen];
String newCharG[]=new String [strLen];
String tempD=null;
String tempG=null;
String arr = null;
String next =null;
String temp=null;
String uniNext=null;
int hold=0;
int j=0;
for (int i=0 ; i< strLen ; i++)
{
j=i+1;
array[i] = line.charAt(i);
strArray1[i] = Character.toString(line.charAt(i));
if(i<(strLen-1))
{
char nbit = line.charAt(j);
next=Character.toString(line.charAt(j));
uniNext=Integer.toHexString(nbit);
//System.out.print("\nUninext:\t"+uniNext);
}
unis[i]=Integer.toHexString(array[i]);
mark[strLen]=1;
if((Arrays.asList(devFull).contains(Character.toString(array[i]))) && (!uniNext.equalsIgnoreCase("94d")) )
{
mark[i]=1;
}
else
{
mark[i]=0;
}
//
//System.out.println();
//System.out.println ("Index = " + i + "* Char = " +array[i] + "** String =" +strArray1[i]+ "Unicode="+unis[i]+"Mark="+mark[i]);
//System.out.print(unis[i].toString());
}
int start=0;
start=0;
for(int l1=0;l1<=strLen;l1++)
{
//start=0;
if(l1==0)
{
temp=Character.toString(array[l1]);
}
else
{
if(mark[l1]==0)
{
temp=temp+Character.toString(array[l1]);
}
else
{
System.out.print(" "+temp);
newCharD[start]=temp;
start++;
temp=null;
if(l1!=strLen)
{
temp=Character.toString(array[l1]);
}
}
}
}
/* for(int s=0;s<start;s++)
{
System.out.print(" "+newCharD[s]);
}*/
for(int s=0;s<start;s++)
{
}
}
}
finally {
br.close();
}
//PrintStream out = new PrintStream(new //FileOutputStream("/home/ubuntu/Documents/trainforjavaoutput.txt"));
//System.setOut(out);
}
Try this for Hindi :-
import java.io.*;
import java.text.BreakIterator;
import java.util.Locale;
public class Test {
public static void main(String[] args) throws IOException
{
String text = "बिक्रम मेरो नाम हो";
Locale hindi = new Locale("hi", "IN");
BreakIterator breaker = BreakIterator.getCharacterInstance(hindi);
breaker.setText(text);
int start = breaker.first();
for (int end = breaker.next();
end != BreakIterator.DONE;
start = end, end = breaker.next()) {
System.out.println(text.substring(start,end));
}
}
}
OUTPUT:-
बि
क्र
म
मे
रो
ना
म
हो
BreakIterator Java Documentation: https://docs.oracle.com/javase/tutorial/i18n/text/about.html
In order to split the string by letters rather than characters, going by dvasanth's suggestion, you can try below:
String x = "बिक्रम मेरो नाम हो";
x=x.replaceAll(" ", ""); // Remove all spaces
int strLength = x.length();
String [] letterArray = new String (strLength /2);
String combined = "";
for (int i=0, j=0; i < strLength ; i=i+2,j++)
{
strArray1[i] = Character.toString(x.charAt(i));
if (i+1 < strLength)
{
strArray1[i+1] = Character.toString(x.charAt(i+1));
combined = strArray1[i]+strArray1[i+1]; // This line provides the letters.
// Assumption is that each letter is 2 unicode characters long.
}
else
{
combined = strArray1[i];
}
letterArray [j] = combined;
System.out.println("Split string by letters is : "+combined);
System.out.println("Split string by letters in array is : "+letterArray [j]);
}
Output is:
Split string by letters is : बि
Split string by letters is : क्
Split string by letters is : रम
Split string by letters is : मे
Split string by letters is : रो
Split string by letters is : ना
Split string by letters is : मह
Split string by letters is : ो
Note:
In order to allow eclipse to allow you to save your java program with foreign characters(Hindi alphabets), do the following:
Go to:
"Windows > Preferences > General > Content Types > Text > {Choose file type}
{Selected file type} > Default encoding > UTF-8" and click Update.
I'm stuck with some code here and what I'm trying to do is convert a string into its ASCII value, subtract 30 from it and then convert back to a string.
E.g. Enter - hello
Convert to - 104 101 108 108 111
Subtract - 74 71 78 78 81
display - JGNNQ
Code:
import javax.swing.*;
public class practice {
public static void main (String[] args) {
String enc = "";
String encmsg = "";
String msg = JOptionPane.showInputDialog("Enter your message");
int len = msg.length();
for (int i = 0; i< len ; i++) {
char cur = msg.charAt(i);
int val = (int) cur;
val = val -32;
enc = "" + val;
encmsg = encmsg + enc;
}
JOptionPane.showMessageDialog(null, encmsg);
}
}
Thanks in advance
Couple things:
Change val = val -32; to val = val -30; to get the proper subtraction you want in the original problem statement.
Next, change
enc = "" + val; to enc = (char)val;
so that you can convert the value to a proper character. Before, you were just concatenating it to a string, which won't do any conversion. You also need to declare enc as a char at the top of your file.
The full working code should be as follows:
char enc;
String encmsg = "";
String msg = JOptionPane.showInputDialog("Enter your message");
int len = msg.length();
for (int i = 0; i < len; i++) {
char cur = msg.charAt(i);
int val = (int) cur;
val = val - 30;
enc = (char) val;
encmsg = encmsg + enc;
}
JOptionPane.showMessageDialog(null, encmsg);
Sample input:
abc def ghi
Sample output:
Cba Fed Ihg
This is my code:
import java.util.Stack;
public class StringRev {
static String output1 = new String();
static Stack<Character> stack = new Stack<Character>();
public static void ReverseString(String input) {
input = input + " ";
for (int i = 0; i < input.length(); i++) {
boolean cap = true;
if (input.charAt(i) == ' ') {
while (!stack.isEmpty()) {
if (cap) {
char c = stack.pop().charValue();
c = Character.toUpperCase(c);
output1 = output1 + c;
cap = false;
} else
output1 = output1 + stack.pop().charValue();
}
output1 += " ";
} else {
stack.push(input.charAt(i));
}
}
System.out.print(output1);
}
}
Any better solutions?
Make use of
StringBuilder#reverse()
Then without adding any third party libraries,
String originalString = "abc def ghi";
StringBuilder resultBuilder = new StringBuilder();
for (String string : originalString.split(" ")) {
String revStr = new StringBuilder(string).reverse().toString();
revStr = Character.toUpperCase(revStr.charAt(0))
+ revStr.substring(1);
resultBuilder.append(revStr).append(" ");
}
System.out.println(resultBuilder.toString()); //Cba Fed Ihg
Have a Demo
You can use the StringBuffer to reverse() a string.
And then use the WordUtils#capitalize(String) method to make first letter of the string capitalized.
String str = "abc def ghi";
StringBuilder sb = new StringBuilder();
for (String s : str.split(" ")) {
String revStr = new StringBuffer(s).reverse().toString();
sb.append(WordUtils.capitalize(revStr)).append(" ");
}
String strReversed = sb.toString();
public static String reverseString(final String input){
if(null == input || isEmpty(input))
return "";
String result = "";
String[] items = input.split(" ");
for(int i = 0; i < items.length; i++){
result += new StringBuffer(items[i]).reverse().toString();
}
return result.substring(0,1).toupperCase() + result.substring(1);
}
1) Reverse the String with this
StringBuffer a = new StringBuffer("Java");
a.reverse();
2) To make First letter capital use
StringUtils class in apache commons lang package org.apache.commons.lang.StringUtils
It makes first letter capital
capitalise(String);
Hope it helps.
Edited
Reverse the string first and make the first character to uppercase
String string="hello jump";
StringTokenizer str = new StringTokenizer(string," ") ;
String finalString ;
while (str.hasMoreTokens()) {
String input = str.nextToken() ;
String reverse = new StringBuffer(input).reverse().toString();
System.out.println(reverse);
String output = reverse .substring(0, 1).toUpperCase() + reverse .substring(1);
finalString=finalString+" "+output ;
}
System.out.println(finalString);
import java.util.*;
public class CapatiliseAndReverse {
public static void reverseCharacter(String input) {
String result = "";
StringBuilder revString = null;
String split[] = input.split(" ");
for (int i = 0; i < split.length; i++) {
revString = new StringBuilder(split[i]);
revString = revString.reverse();
for (int index = 0; index < revString.length(); index++) {
char c = revString.charAt(index);
if (Character.isLowerCase(revString.charAt(0))) {
revString.setCharAt(0, Character.toUpperCase(c));
}
if (Character.isUpperCase(c)) {
revString.setCharAt(index, Character.toLowerCase(c));
}
}
result = result + " " + revString;
}
System.out.println(result.trim());
}
public static void main(String[] args) {
//System.out.println(reverseCharacter("old is GlOd"));
Scanner sc = new Scanner(System.in);
reverseCharacter(sc.nextLine());
}
}