Hey I'm making a simple caesar cipher in Java using the formula [x-> (x+shift-1) mod 127 + 1] I want to have my encrypted text to have the ASCII characters except the control characters(i.e from 32-127). How can I avoid the control characters from 0-31 applying in the encrypted text. Thank you.
How about something like this:
public String applyCaesar(String text, int shift)
{
char[] chars = text.toCharArray();
for (int i=0; i < text.length(); i++)
{
char c = chars[i];
if (c >= 32 && c <= 127)
{
// Change base to make life easier, and use an
// int explicitly to avoid worrying... cast later
int x = c - 32;
x = (x + shift) % 96;
if (x < 0)
x += 96; //java modulo can lead to negative values!
chars[i] = (char) (x + 32);
}
}
return new String(chars);
}
Admittedly this treats 127 as a non-control character, which it isn't... you may wish to tweak it to keep the range as [32, 126].
Map your characters from [32..127] to [0..95], do a mod 95+1 and map the result back to [32..127].
Usually cipher text is base64 encoded, base16 (hex) also works well. Base64 is used most often for cipher text because it takes up less space than hex, hex is most commonly used for message digests. In the java.util.prefs.Base64 library you will find byteArrayToBase64() and base64ToByteArray().
On a side note you should NEVER write your own encryption algorithm for security reasons, you should be using a block cipher or stream cipher. I hope this is for fun!
there! Is there any way to consider the whole range of characters? For example, "á", "é", "ö", "ñ", and not consider " " (the [Space])? (For example, my String is "Hello World", and the standard result is "Khoor#Zruog"; I want to erase that "#", so the result would be "KhoorZruog")
I'm sure my answer is in this piece of code:
if (c >= 32 && c <= 127)
{
// Change base to make life easier, and use an
// int explicitly to avoid worrying... cast later
int x = c - 32;
x = (x + shift) % 96;
chars[i] = (char) (x + 32);
}
... But I've tried some things, and the didn't work :S So, I'll wait for your answers :D See you!
Why not try
for(int i = 0; i < length; i++)
{
char c = chars[i]
if(Character.isLetter(c))
{
int x = c - 32;
x = (x + shift) % 96;
chars[i] = (char) (x+32);
}
}
Copy paste this in NetBeans with name "caesar":
//package caesar;
import java.io.*;
public class caesar {
int offset=3;
public String encrypt(String s) throws IOException
{
StringBuilder sb=new StringBuilder();
for(int i=0;i<s.length();i++)
{
char t=s.charAt(i);
if(t>='A' && t<='Z')
{
int t1=t-'A'+offset;
t1=t1%26;
sb.append((char)(t1+'A'));
}
else if(t>='a' && t<='z')
{
int t1=t-'a'+offset;
t1=t1%26;
sb.append((char)(t1+'a'));
}
}
return sb.toString();
}
public String decrypt(String s) throws IOException
{
StringBuilder sb=new StringBuilder();
for(int i=0;i<s.length();i++)
{
char t=s.charAt(i);
if(t>='A' && t<='Z')
{
int t1=t-'A'-offset;
if(t1<0)t1=26+t1;
sb.append((char)(t1+'A'));
}
else if(t>='a' && t<='z')
{
int t1=t-'a'-offset;
if(t1<0)t1=26+t1;
sb.append((char)(t1+'a'));
}
}
return sb.toString();
}
public static void main(String[] args) {
try
{
System.out.println("Caesar encrypion technique");
BufferedReader b;
String oriTxt,encTxt,decTxt;
System.out.println("Enter string to encrypt:");
b=new BufferedReader(new InputStreamReader(System.in));
oriTxt=b.readLine();
caesar c=new caesar();
encTxt=c.encrypt(oriTxt);
System.out.println("Encrypted text :"+encTxt);
decTxt=c.decrypt(encTxt);
System.out.println("Derypted text :"+decTxt);
}
catch(Exception e)
{
System.out.println(e.toString());
}
}
}
import java.util.Scanner;
//caeser
public class Major_Assingment {
public static final String ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZhh";
public static String encrypt(String plainText,int shiftKey)
{
plainText = plainText.toUpperCase();
String cipherText= " ";
for(int i=0; i<plainText.length(); i++)
{
int charPosition = ALPHABET.indexOf(plainText.charAt(i));
int keyVal = (shiftKey + charPosition)% 26 ;
char replaceVal = ALPHABET.charAt(keyVal);
cipherText += replaceVal;
}
return cipherText;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter the string for Encryption:");
String message = new String();
message = sc.next();
System.out.println(encrypt(message,3));
sc.close();
}
}
Related
However I had an assignment of programming in java related to a text i already have under (text).
the function is supposed to as below
getEncryptedText(int shift)
return a string representation of ciphertext given that the text to be manipulated is the plaintext using Caesar Cipher.
The number of rotation is depend on the shift value;
positive shift value represent the right rotation while negative shift value represent left
rotation. However, unlike explain in Wikipedia, this method used following string as
plain:
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
Other characters than above will be treated as it is (i.e. will not been encrypted)
*Further reading: https://en.wikipedia.org/wiki/Caesar_cipher
So this is the class method I have made so far and wanted to know how can i keep the text chars which aren't included in the plaintext i have such as "!,#,#,$,%... and so on". So far i tried everything but couldn't make it but the rest seems fine!
public String getEncryptedText(int shift) {
String ALPHABET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
String cipherText = "";
for (int i = 0; i < text.length(); i++){
{
int charPosition = ALPHABET.indexOf(text.charAt(i));
if(text.charAt(i) == ' ') {
cipherText += " ";
}
else
{
int keyVal = (shift + charPosition) % 62;
char replaceVal = ALPHABET.charAt(keyVal);
cipherText += replaceVal;
}
}
}
return cipherText;
}
Consider modifying your if statement and using the StringBuilder class:
class Main {
public static void main(String[] args) {
CesarCypherHelper cesarCypherHelper = new CesarCypherHelper();
System.out.println(cesarCypherHelper.getEncryptedText("Hello World!", 2));
System.out.println(cesarCypherHelper.getEncryptedText("Hello World!", 64));
}
}
class CesarCypherHelper {
public String getEncryptedText(String text, int shift) {
String ALPHABET =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
StringBuilder encryptedText = new StringBuilder();
for (int i = 0; i < text.length(); i++) {
char ch = text.charAt(i);
int charPosition = ALPHABET.indexOf(ch);
if (charPosition == -1) {
encryptedText.append(ch);
} else {
int keyVal = (shift + charPosition) % ALPHABET.length();
encryptedText.append(ALPHABET.charAt(keyVal));
}
}
return encryptedText.toString();
}
}
Output:
Jgnnq Yqtnf!
Jgnnq Yqtnf!
For my CPSC class, I need to make encryption code using caesar cipher. That is done. The next part is taking the encrypted message and cycling the secretKey to be added to the encrypted message. For example, if I encrypt "Hello!" using a shift of 13, it will turn into "Uryyb!". Then I must shift "U" by one, "r" by three, "y" by one, etc... which will encrpt into "Vuzbc!" I am in a beginner class so I do not know all the cool tips and tricks. Only possible solution I know is to take the outcome of the caesar cipher and somehow index the secret key to be added to the outcome.
Here is my code that I have so far:
public class Cipher {
private int secretKey;
private int superSecretKey;
public static void main(String [] args)
{
Cipher cipher = new Cipher(1);
}
public Cipher(int myKey) {
secretKey = myKey;
}
public String caesarEncrpyt (String s) {
String r = "";
for(int i = 0; i < s.length(); i++) {
char c = (char) (s.charAt(i));
if(Character.isLetter(c)) {
if (Character.isUpperCase(c)) {
r += (char) ('A' + (c - 'A' + secretKey) % 26);
}
else {
r += (char) ('a' + (c - 'a' + secretKey) % 26);
}
}
else {
r += c;
}
}
return r;
}
public String caesarDecrypt (String s) {
String r = "";
for(int i = 0; i < s.length(); i++) {
char c = (char) (s.charAt(i));
if(Character.isLetter(c)) {
if (Character.isUpperCase(c)) {
r += (char) ('A' + (c - 'A' - secretKey) % 26);
}
else {
r += (char) ('a' + (c - 'a' - secretKey) % 26);
}
}
else {
r += c;
}
}
return r;
}
public String augustusEncrypt (String s) {
String r = "";
for(int i = 0; i < s.length(); i++) {
char c = (char) (s.charAt(i));
if(Character.isLetter(c)) {
if (Character.isUpperCase(c)) {
r += (char) ('A' + (c - 'A' + secretKey) % 26);
}
else {
r += (char) ('a' + (c - 'a' + secretKey) % 26);
}
}
else {
r += c;
}
}
return r;
}
augustusEncrypt is a copy and paste of caesarEncrypt. I've been moving some stuff around hoping for a solution. Thanks in advance!
Edit: I may not have explained this correctly, if you have a question, I'll be here.
Write a function, call it toDigits which will take an int (or a long) and return an array of ints corresponding to the digits of the input. to toDigits(13)=>{1,3} and toDigits(4834)=>{4,8,3,4}, etc
Then write a function encryptChar, taking a char and an int and encrypting the char by that int. (encryptChar('e', 1)=>'f', encryptChar('a',28)=>c, etc)
Then you can loop over the characters of the message and the digits in this array, passing the values to encryptChar and use the results to assemble your encrypted message. In a loose sort of pseudocode:
fn encryptMessage(message, key):
key_array = toDigits(key)
output = ""
for i in length (message):
output.append(encryptChar(message[i], key_array[i % length(key_array)]))
Best practices and conventions for encrypting aside, the solution is simple.
You have letters A-Z and a-z which already perform the correct loop when we step off of the alphabet, and you believe you have that working correctly. All you need to do is add 1 before you loop around.
It would be something like this (warning: untested):
('A' + ((c+1) - 'A' + secretKey) % 26)
I'm stuck on some code for a class of mine. My professor encourages asking questions on forums such as this, especially since it gives him less questions :), so I figured I'd ask all of you for help.
The purpose of my assignment is to encrypt and decrypt and input string by shifting, or offseting, the characters over how of many times the user tells it to. My code is below.
For some reason, I got an error when I decrypt my encrypted text, and the error only occurs with numbers of 6 or more when run my code, so if used professor's example and encrypted "subterfuge" to offset 6 characters to make "yahzkxlamk" and then try to decrypt the text to offset 6 characters again to make "subterfuge", it gives me an error. The error is
java.lang.StringIndexOutOfBoundsException: String index out of range: -6
When I run the code with the same input string, "subterfuge", but with an offset of 5 or less, it works. The error is said to occur at the 65th line of the below code where it says
sb.append(alphabet.charAt(offset));
at the end of my Decrypt() method in the last else statement.
import javax.swing.*;
public class Encryptor {
private String plainText;
private int shift;
public String cipherText;
public Encryptor() {
plainText = null;
shift = 0;
}
public static void main(String[] args) {
//encryption block
Encryptor e = new Encryptor();
String strCipherText = e.Encrypt();
System.out.println("encrypted text");
System.out.println(strCipherText);
//decrypt block
Encryptor d = new Encryptor();
//cipher text becomes the input text to the Decrypt method
d.cipherText = strCipherText;
String strPlainText = d.Decrypt();
System.out.println("decrypted text");
System.out.println(strPlainText);
System.exit(0);
}//end of main method
public String Decrypt()
{
plainText = cipherText;
shift = Integer.parseInt(JOptionPane.showInputDialog("enter offset"));
int offset=0;
int newOffset=0;
String alphabet ="abcdefghijklmnopqrstuvwxyz";
StringBuffer sb = new StringBuffer();
int index = plainText.length();
for(int i=0;i<index;i++)
{
String temp = "" + plainText.charAt(i);
offset = alphabet.indexOf(temp);
offset -= shift;
if(offset > 25)
{
newOffset = offset % 26;
sb.append(alphabet.charAt(newOffset));
}
else
{
sb.append(alphabet.charAt(offset));
}
}//end of for loop
return sb.toString();// return encrypted string
}
public String Encrypt()
{
plainText = ((String)JOptionPane.showInputDialog("enter words " + "to encrypt")).toLowerCase().trim();
shift = Integer.parseInt(JOptionPane.showInputDialog("enter offset"));
int offset=0;
int newOffset=0;
String alphabet = "abcdefghijklmnopqrstuvwxyz";
StringBuffer sb = new StringBuffer();
int index = plainText.length();
for(int i=0;i<index;i++)
{
String temp = "" + plainText.charAt(i);
offset = alphabet.indexOf(temp);
offset += shift;
if(offset > 25)
{
newOffset = offset % 26;
sb.append(alphabet.charAt(newOffset));
}
else
{
sb.append(alphabet.charAt(offset));
}
}//end of for loop
return sb.toString();// return encrypted string
}
}
Here is your problem:
offset = alphabet.indexOf(temp);
offset -= shift;
if(offset > 25)
{
newOffset = offset % 26;
sb.append(alphabet.charAt(newOffset));
}
else
{
sb.append(alphabet.charAt(offset));//< New offset is less than 0
}
What you want is a positive-only mod function. So just add do this after you do your modular division:
while(newOffset < 0)
newOffset += 26;
What I tend to do is just make a function for this:
/* Positive modular division. */
public static int pmod(int num, int mod)
{
num %= mod;
if(num < 0) num += mod;
return num;
}
I am attempting to, in java, write a program that will encode a string like a vigenere cipher. An example run would be
java Encrypt -e lemon < in.txt > out.txt
in.txt should read ATTACKATDAWN, and out.txt should read LXFOPVEFRNHR, and if an insufficient # of args are used it should print the usage statement; However, when I run the encryption method on this, it returns "??¡????¡??£?", and if i run the decryption method on THAT, it returns "?? ???? ????", and if I put in less than the required two args, it returns
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
at Encrypt.main(Encrypt.java:22)
here is my code
import java.util.Scanner;
public class Encrypt
{
public static void main(String[] args)
{
Scanner scan = new Scanner (System.in);
String msg = scan.nextLine();
String key = args[1];
if (args.length < 2)
{
System.out.println("Encryption program by ----");
System.out.println("Usage: java Encrypt [-e, -d] < inputFile > outputFile");
System.exit(0);
}
else if (args[0].equals ("-e"))
{
String emsg = encrypt(args[1], msg);
System.out.println(emsg);
}
else if (args[0].equals ("-d"))
{
String dmsg = decrypt(args[1], msg);
System.out.println(dmsg);
}
}
public static void usage(String[] args)
{
if (args.length < 2)
{
System.out.println("Encryption program by --------");
System.out.println("Usage: java Encrypt [-e, -d] < inputFile > outputFile");
System.exit(0);
}
}
public static String encrypt(String key, String msg)
{
String emsg = "";
for (int i = 0; i < msg.length(); i++)
{
int m = msg.charAt(i);
int k = key.charAt(i % key.length());
int e = (m + (k - 32));
char s = (char) e;
if (e > 126)
e = (e - (127 - 32));
emsg += s;
}
return emsg;
}
public static String decrypt(String key, String msg)
{
String dmsg = "";
for (int i = 0; i < msg.length(); i++)
{
int m = msg.charAt(i);
int k = key.charAt(i%key.length());
int e = (m - (k - 32));
char s = (char) e;
if (e > 126)
e = (e - (127 - 32));
dmsg += s;
}
return dmsg;
}
}
I honestly dont know what I am doing wrong; ANY assistance would be very welcome!
You get an ArrayIndexOutOfBoundsException because you access the second element of the array:
String key = args[1];
before you've tested the length of args. Get rid of this line entirely, since you don't refer to key anywhere else in your application. (A good IDE should have told you this already).
For your encryption code, I think you'll find this quite challenging unless you limit yourself to only upper-case (or lowercase) letters. Assuming you go for upper-case, then subtracting 65 from the ASCII value will give you a convenient 0-25 value work with with. Then you can use addition, modulo-26 to achieve your goal.
I've fixed up your encryption, now try doing the decryption:
public static String encrypt(String key, String msg) {
String emsg = "";
final int offset = 'A'; // 65
for (int i = 0; i < msg.length(); i++) {
int m = msg.charAt(i) - offset;
int k = key.charAt(i % key.length()) - offset;
int e = (m + k) % 26;
char s = (char) (e + offset);
emsg += s;
}
return emsg;
}
Hello evrybody who reads this!
I need to realize Vigenere cipher on Java.
I have a .txt document, which I'm going to read, encode and decode. Here it is:
ASCII abcde xyz
German äöü ÄÖÜ ß
Polish ąęźżńł
Russian абвгдеж эюя
CJK 你好
My problem is that I don't know how to shift chars correctly, According to this table latin letters have codes from 0061 to 007A. German ones that I need: 00C0 - 00FF, polish: 0100-017F, russian 0430-044F and I didn't gind chineese.
How can I specify unshiftChar and shiftChar to make it correst?
Now my input looks like this:
The original text from file is:
ASCII abcde xyz
German äöü ÄÖÜ ß
Polish ąęźżńł
Russian абвгдеж эюя
CJK 你好
String that will be encoded is:
asciiabcdexyzgermanäöüäöüßpolishąęźżńłrussianабвгдежэюяcjk你好
The encrypted string is:
äckkwdfaqmzjökcbucäbdslhwfssjvåjoxfbsltfvwgnvboegbrnboeghxöb
The decrypted phrase is:
asciiab¥dexyzgrmanäöäöuupo○ibmjcåäldhtciwmtdåawmtddpw
Here is a Java code:
public class VigenereCipher
{
public static void main(String[] args) throws IOException
{
String key = "Unicode";
File file = new File("G:\\unicode.txt");
FileInputStream fis = new FileInputStream(file);
byte[] fileBArray = new byte[fis.available()];
fis.read(fileBArray);
String text = new String(fileBArray, "UTF-8");
//String text = "Some simple text to check the decoding algorythm";
System.out.println("The original text from file is: \n" + text);
String enc = encrypt(text, key);
System.out.println(enc + "\n");
System.out.println("The decrypted phrase is: ");
System.out.println(decrypt(enc, key));
}
// Encrypts a string
public static String encrypt(String message, String key)
{
message = StringToLowerCaseWithAllSymbols(message);
System.out.println("String that will be encoded is: \n" + message);
char messageChar, keyChar;
String encryptedMessage = "";
for (int i = 0; i < message.length(); i++)
{
messageChar = shiftChar(message.charAt(i));
keyChar = shiftChar(key.charAt(i % key.length()));
messageChar = (char) ((keyChar + messageChar) % 29);
messageChar = unshiftChar(messageChar);
encryptedMessage += messageChar;
}
System.out.println("\nThe encrypted string is: ");
return encryptedMessage;
}
// Decrypts a string
public static String decrypt(String cipher,String key)
{
char cipherChar, keyChar;
cipher = StringToLowerCaseWithAllSymbols(cipher);
String decryptedMessage = "";
cipher = cipher.toLowerCase();
for (int i = 0; i < cipher.length(); i++)
{
cipherChar = shiftChar(cipher.charAt(i));
keyChar = shiftChar(key.charAt(i % key.length()));
cipherChar = (char) ((29 + cipherChar - keyChar) % 29);
cipherChar = unshiftChar(cipherChar);
decryptedMessage += cipherChar;
}
return decryptedMessage;
}
// Prunes all characters not in the alphabet {A-Öa-ö} from a string and changes it to all lower case.
public static String StringToLowerCaseWithAllSymbols(String s)
{
//s = s.replaceAll("[^A-Za-zåäöÅÄÖ]", "");
// 's' contains all the symbols from my text
s = s.replaceAll("[^A-Za-zäöüÄÖÜßąęźżńłабвгдежэюя你好]", "");
return s.toLowerCase();
}
// Assigns characters a,b,c...å,ä,ö the values 1,2,3...,26,28,29.
private static char shiftChar(char c)
{
if (96 < c && c < 123)
{
c -= 97;
}
else if (c == 229)
{
c = 26;
}
else if (c == 228)
{
c = 27;
}
else if (c == 246)
{
c = 28;
}
return c;
}
// Undoes the assignment in shiftChar and gives the characters back their UTF-8 values.
private static char unshiftChar(char c)
{
if (0 <= c && c <= 25)
{
c += 97;
}
else if (c == 26)
{
c = 229;
}
else if (c == 27)
{
c = 228;
}
else if (c == 28)
{
c = 246;
}
return c;
}
}
First of all, you don't want to shift: You want to rotate. Suppose we're working with the English alphabet. If 'A'+2 is 'C', what's 'Z'+2? When you're implementing a Vigenere cipher, you want 'Z'+2=='B'.
I would would not use Unicode in a Vigenere cipher program: I would use my own encoding in which the first letter of the alphabet is represented by zero, the second letter is represented by one, and so on. So, for my English example, code('A')==>0, code('B')==>, ... code('Z')==>26.
Then my rotation function looks like this:
int rotate(Alphabet alphabet, int code, int amount) {
return (code + amount) % alphabet.getLength();
}
So:
rotate(english, code('A'), 2) ==> (0 + 2)%26 == 2, (the code for 'C'), and
rotate(english, code('Z'), 2) ==> (25 + 2)%26 == 1, (the code for 'B').