Reputation: 311
I want to implement a Caesar Cipher shift to increase each letter in a string by 3.
I am receiving this error:
possible loss of precision required char; found int
Here is my code so far:
import java.util.Scanner;
import java.io.*;
public class CaesarCipher
{
public static void main (String [] args) {
char[] letters = {'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'};
char[] message = "onceuponatime".toCharArray();
char[] eMessage = new char[message.length];
char shift = 3;
//encrypting message
for(int i = 0; i <= message.length; ++i)
{
eMessage[i] = (message[i] + shift) % (char) letters.length;
System.out.println(x);
}
}
}
What causes this error? How can I implement a caesar Cipher shift to increase each letter in a string by 3?
Upvotes: 7
Views: 156826
Reputation: 24443
Here is my Java Stream API implementation of a program that can encrypt using Caesar cipher:
public String encrypt(String plaintext) {
return plaintext.toLowerCase().chars()
.mapToObj(plaintextLetter -> plaintextLetter == ' ' ? ' ' : applyEncryptionAlgorithm(plaintextLetter))
.collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
.toString()
.toUpperCase(); // convention - ciphertext is in uppercase
}
private int applyEncryptionAlgorithm(int plaintextLetter) {
plaintextLetter -= 'a';
int ciphertextLetter = (plaintextLetter + 3) % 26;
return ciphertextLetter + 'a';
}
And a unit test:
@Test
public void testEncrypt() {
String plaintext = "meet me after the toga party";
String ciphertext = "PHHW PH DIWHU WKH WRJD SDUWB";
String result = caesarCipher.encrypt(plaintext);
assertEquals(ciphertext, result);
}
Upvotes: 0
Reputation: 41
//we can use char as integer as Java store every character as ascii integer
String rotationalCipher(String input, int rotationFactor){
char [] inputArr = input.toCharArray();
String resultStr = "";
for (char ch: inputArr ) {
if(ch < 58 && ch>48){
int withRotetionFactor = ch + rotationFactor;
if(withRotetionFactor < 57){
resultStr = resultStr + (char) withRotetionFactor;
}else {
int looprotation = withRotetionFactor - 10;
resultStr = resultStr + (char)looprotation;
}
}else if(ch < 91 && ch>63){
int withRotetionFactor = ch + rotationFactor;
if(withRotetionFactor < 91){
resultStr = resultStr + (char) withRotetionFactor;
}else {
int looprotation = withRotetionFactor - 26;
resultStr = resultStr + (char)looprotation;
}
}else if(ch < 123 && ch>96){
int withRotetionFactor = ch + rotationFactor;
if(withRotetionFactor < 123){
resultStr = resultStr + (char) withRotetionFactor;
}else {
int looprotation = withRotetionFactor - 26;
resultStr = resultStr + (char)looprotation;
}
}else {
resultStr = resultStr + ch;
}
}
return resultStr;
}
Upvotes: 0
Reputation: 1
Hello...I have created a java client server application in swing for caesar cipher...I have created a new formula that can decrypt the text properly... sorry only for lower case..!
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.net.*;
import java.util.*;
public class ceasarserver extends JFrame implements ActionListener {
static String cs = "abcdefghijklmnopqrstuvwxyz";
static JLabel l1, l2, l3, l5, l6;
JTextField t1;
JButton close, b1;
static String en;
int num = 0;
JProgressBar progress;
ceasarserver() {
super("SERVER");
JPanel p = new JPanel(new GridLayout(10, 1));
l1 = new JLabel("");
l2 = new JLabel("");
l3 = new JLabel("");
l5 = new JLabel("");
l6 = new JLabel("Enter the Key...");
t1 = new JTextField(30);
progress = new JProgressBar(0, 20);
progress.setValue(0);
progress.setStringPainted(true);
close = new JButton("Close");
close.setMnemonic('C');
close.setPreferredSize(new Dimension(300, 25));
close.addActionListener(this);
b1 = new JButton("Decrypt");
b1.setMnemonic('D');
b1.addActionListener(this);
p.add(l1);
p.add(l2);
p.add(l3);
p.add(l6);
p.add(t1);
p.add(b1);
p.add(progress);
p.add(l5);
p.add(close);
add(p);
setVisible(true);
pack();
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == close)
System.exit(0);
else if (e.getSource() == b1) {
int key = Integer.parseInt(t1.getText());
String d = "";
int i = 0, j, k;
while (i < en.length()) {
j = cs.indexOf(en.charAt(i));
k = (j + (26 - key)) % 26;
d = d + cs.charAt(k);
i++;
}
while (num < 21) {
progress.setValue(num);
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
}
progress.setValue(num);
Rectangle progressRect = progress.getBounds();
progressRect.x = 0;
progressRect.y = 0;
progress.paintImmediately(progressRect);
num++;
}
l5.setText("Decrypted text: " + d);
}
}
public static void main(String args[]) throws IOException {
new ceasarserver();
String strm = new String();
ServerSocket ss = new ServerSocket(4321);
l1.setText("Secure data transfer Server Started....");
Socket s = ss.accept();
l2.setText("Client Connected !");
while (true) {
Scanner br1 = new Scanner(s.getInputStream());
en = br1.nextLine();
l3.setText("Client:" + en);
}
}
The client class:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.net.*;
import java.util.*;
public class ceasarclient extends JFrame {
String cs = "abcdefghijklmnopqrstuvwxyz";
static JLabel l1, l2, l3, l4, l5;
JButton b1, b2, b3;
JTextField t1, t2;
JProgressBar progress;
int num = 0;
String en = "";
ceasarclient(final Socket s) {
super("CLIENT");
JPanel p = new JPanel(new GridLayout(10, 1));
setSize(500, 500);
t1 = new JTextField(30);
b1 = new JButton("Send");
b1.setMnemonic('S');
b2 = new JButton("Close");
b2.setMnemonic('C');
l1 = new JLabel("Welcome to Secure Data transfer!");
l2 = new JLabel("Enter the word here...");
l3 = new JLabel("");
l4 = new JLabel("Enter the Key:");
b3 = new JButton("Encrypt");
b3.setMnemonic('E');
t2 = new JTextField(30);
progress = new JProgressBar(0, 20);
progress.setValue(0);
progress.setStringPainted(true);
p.add(l1);
p.add(l2);
p.add(t1);
p.add(l4);
p.add(t2);
p.add(b3);
p.add(progress);
p.add(b1);
p.add(l3);
p.add(b2);
add(p);
setVisible(true);
b1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
PrintWriter pw = new PrintWriter(s.getOutputStream(), true);
pw.println(en);
} catch (Exception ex) {
}
;
l3.setText("Encrypted Text Sent.");
}
});
b3.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String strw = t1.getText();
int key = Integer.parseInt(t2.getText());
int i = 0, j, k;
while (i < strw.length()) {
j = cs.indexOf(strw.charAt(i));
k = (j + key) % 26;
en = en + cs.charAt(k);
i++;
}
while (num < 21) {
progress.setValue(num);
try {
Thread.sleep(100);
} catch (InterruptedException exe) {
}
progress.setValue(num);
Rectangle progressRect = progress.getBounds();
progressRect.x = 0;
progressRect.y = 0;
progress.paintImmediately(progressRect);
num++;
}
}
});
b2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
pack();
}
public static void main(String args[]) throws IOException {
final Socket s = new Socket(InetAddress.getLocalHost(), 4321);
new ceasarclient(s);
}
}
Upvotes: 0
Reputation: 3091
Below code handles upper and lower cases as well and leaves other character as it is.
import java.util.Scanner;
public class CaesarCipher
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int length = Integer.parseInt(in.nextLine());
String str = in.nextLine();
int k = Integer.parseInt(in.nextLine());
k = k % 26;
System.out.println(encrypt(str, length, k));
in.close();
}
private static String encrypt(String str, int length, int shift)
{
StringBuilder strBuilder = new StringBuilder();
char c;
for (int i = 0; i < length; i++)
{
c = str.charAt(i);
// if c is letter ONLY then shift them, else directly add it
if (Character.isLetter(c))
{
c = (char) (str.charAt(i) + shift);
// System.out.println(c);
// checking case or range check is important, just if (c > 'z'
// || c > 'Z')
// will not work
if ((Character.isLowerCase(str.charAt(i)) && c > 'z')
|| (Character.isUpperCase(str.charAt(i)) && c > 'Z'))
c = (char) (str.charAt(i) - (26 - shift));
}
strBuilder.append(c);
}
return strBuilder.toString();
}
}
Upvotes: 8
Reputation: 153842
shift
spaces.Restrictions:
Pseudocode:
Function:
String cipher(String msg, int shift){
String s = "";
int len = msg.length();
for(int x = 0; x < len; x++){
char c = (char)(msg.charAt(x) + shift);
if (c > 'z')
s += (char)(msg.charAt(x) - (26-shift));
else
s += (char)(msg.charAt(x) + shift);
}
return s;
}
How to invoke it:
System.out.println(cipher("abc", 3)); //prints def
System.out.println(cipher("xyz", 3)); //prints abc
Upvotes: 14
Reputation: 47
Two ways to implement a Caesar Cipher:
Option 1: Change chars to ASCII numbers, then you can increase the value, then revert it back to the new character.
Option 2: Use a Map map each letter to a digit like this.
A - 0
B - 1
C - 2
etc...
With a map you don't have to re-calculate the shift every time. Then you can change to and from plaintext to encrypted by following map.
Upvotes: 1
Reputation: 5930
The warning is due to you attempting to add an integer (int shift = 3
) to a character value. You can change the data type to char
if you want to avoid that.
A char
is 16 bits, an int
is 32.
char shift = 3;
// ...
eMessage[i] = (message[i] + shift) % (char)letters.length;
As an aside, you can simplify the following:
char[] message = {'o', 'n', 'c', 'e', 'u', 'p', 'o', 'n', 'a', 't', 'i', 'm', 'e'};
To:
char[] message = "onceuponatime".toCharArray();
Upvotes: 1