This is my affine encryption and decryption code.
I have char array of 26 characters. The cipher text generated by
ax + b % 26
does not match with decryption formula
a - inverse(ciphertext[c]-b) % 26
For example, when a=3 and b=5, when I encrypt r. Location of r in the character array is 17 by encryption formula:
((3*17+5) %26) = (56%26) = 4
Character at position 4 in the array is e. When I decrypt the cipher text inverse value for 3 is 9. So, Math.abs(3(4-5)%26)=3 which is incorrect.
private static String affinecipher(String plainText) {
String encrypt = "";
int value = 0;
int location=0;
String text=plainText.toUpperCase();
Scanner inputData = new Scanner(System.in);
System.out.print("Enter a:");
a = inputData.nextInt();
System.out.print("Enter b:");
b = inputData.nextInt();
for(int p = 0; p < text.length(); p++){
for(int q =0 ; q<letter.length; q++){
if(text.charAt(p)==letter[q]){
// checking each plaintext character position to letter array position.
// if match found returning the letter position
location=q;
}
}
value= (((a*location)+b) % m);
// value of a multiplied by letter position adding to b and taking the mod.
// adding the string with value position from letter
encrypt = encrypt +letter[value];
}
return encrypt;
}
//decryption
private static String decryptAffineCipher(String encryptText){
String decrypt=" ";int location=0;
//calculating the inverse value
a %= 26;
for(int x = 1; x < 26; x++) {
if((a*x) % 26 == 1) {
inverse=x;
}
}
for (int p = 0; p < encryptText.length(); p++){
for(int q =0 ; q<letter.length; q++){
//finding the location of cipher character
if(encryptText.charAt(p)==letter[q]){
location=q;
}
}
//decryption formula a-inverse(c-b)%26
int step1=Math.abs(location-b);
int step2=inverse* step1;
int value=step2 %26;
//char letter[26] that stores value from A to Z
decrypt = decrypt +letter[value];
}
return decrypt;
}
Related
I am trying to encode a word, and I am not sure why my for loops aren't picking up the first instance, 0. The input for this method is "This" and 3. The output from this method is klv. So my loop must not be working properly as the letter T is getting skipped. What is wrong with my loops?
String encodeWord(String word, int Shift) {
//word = "This"
//Shift = 3, is how far the letter is shifted to the right of the original
char[] alphabet = "abcdefghijklmnopqrstuvwxyz".toCharArray();
char[] temp = word.toCharArray();
char[] FA = new char[temp.length];
String tempWord = "";
StringBuilder sb = new StringBuilder(64);
for (int x = 0; x < word.length(); x++) {
for (int y = 0; y < alphabet.length; y++) {
if (word.charAt(0) == alphabet[y]) {
FA[0] = alphabet[y + shift];
System.out.println(FA[0]);
}
}
}
for (int i = 0; i < word.length(); i++) {
for (int j = 0; j < alphabet.length; j++) {
if (word.charAt(i) == alphabet[j]) {
FA[i] = alphabet[j + shift];
sb.append(FA[i]);
System.out.println(FA[i]);
}
}
}
System.out.println(sb);
return sb.toString();
}
The letter 'T' is different from the letter 't', so since only the letter 't' is found in your array, the program won't find a match for the letter 'T'.
Another problem with your code is that you will get an Index out of bounds exception if the input contains the letters 'x', 'y' or 'z' because there aren't 3 letters after them in the array.
public static String encoder(String word, int shift)
{
static const int max_char = 122; //letter 'z'
static const int min_char = 97; //letter 'a'
char[] c_array = word.toCharArray();
char[] encoded_string = new char[c_arary.length()];
for(for i = 0; i < c_array.length(); i++)
{
if( ((int)c + shift) > max_char) //makes sure that the ascii isnt a non number
{
encoded_string[i] = (min_char + (int)c + shift - max_char ); // this will correct the overflow
}
c = c + shfit;
}
return encoded_string;
}
This is an easier way to do this... also your loops have a few logical errors.. the first one i caught was in the first loop... if there is a z in your word your going to overflow your alphabet array.
This is using the Ascii table way
Basically I've been trying to make my histogram display the asterisks vertically aligned above the letter that it is incrementing above. I've been trying to figure out the most efficient way to get the asterisks to align above the letter repeating. Any suggestions?
**My current output displays this horizontally**
asfklafjasjfk
A (3) ***
F (3) ***
J (2) **
K (2) **
L (1) *
S (2) **
ABCDEFGHIJKLMNOPQRSTUVWXYZ
I want it to display this
abcaaaabbzzzzz
*
* *
** *
** *
*** *
ABCDEFGHIJKLMNOPQRSTUVWXYZ
I have listed my code below
public class histogram {
public static void main(String[] args){
Scanner input = new Scanner(System.in);
String lettersInput = input.nextLine();
lettersInput=lettersInput.toUpperCase();
String map = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int[] count = new int[map.length()];
for(int x = 0; x < lettersInput.length();x++){
int letter = map.indexOf(lettersInput.charAt(x));
if(letter < 0){
continue;
}
count[letter]++;
}
for(int x = 0; x < count.length; x++){
if(count[x]< 1)
continue;
System.out.println(String.format("%s (%d) %s",
map.charAt(x),
count[x],
new String(new char[count[x]]).replace('\0','*')));
}
System.out.println("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
}
}
The approach I took was to use a sorted map, whose keys are letters of the alphabet and whose values are the number of occurrences of each letter. Simply iterate over the input string to populate the map. Then, iterate over each row of possible output and print out either a space or an asterisk for each letter. I used Collections.max() on the map's values to find the height of the histogram.
TreeMap<Character, Integer> map = new TreeMap<>();
String input = "abcaaaabbzzzzz".toUpperCase();
String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
for (int i=0; i < input.length(); ++i) {
Integer val = map.get(input.charAt(i));
map.put(input.charAt(i), val == null ? 1 : val + 1);
}
Collection<Integer> c = map.values();
int maxFrequency = Collections.max(c);
System.out.println("Input:\n" + input);
for (int i=maxFrequency; i > 0; --i) {
for (int j=0; j < alphabet.length(); ++j) {
Integer count = map.get(alphabet.charAt(j));
System.out.print((count != null && count >= i) ? "*" : " ");
}
System.out.println();
}
System.out.println(alphabet);
Output:
Input:
ABCAAAABBZZZZZ
* *
* *
** *
** *
*** *
ABCDEFGHIJKLMNOPQRSTUVWXYZ
Demo here:
Rextester
I have the problem when decrypting the text message. Example :
Plaintext : "halo brother"
Ciphertext : "žiÌ=ßOÌÅbO"
Plaintext : "haフo`bメothナメ"
k1 : 33 ->first key
k2 : 125 ->second key
I use ASCII printable & ASCII extended characters set total 224 characters.
Here is my code :
public class Affine {
//encyption method
public static String enkripsi(String pesan, int k1, int k2){
//change text message into array
char[] chars = pesan.toCharArray();
//getting ASCII code from each characters index
int[] ascii = new int[chars.length];
for (int i = 0; i < chars.length; i++) {
ascii[i] = (int) chars[i];
}
//Affine encryption formula
int[] c = new int[ascii.length];
for (int j = 0; j < ascii.length; j++) {
c[j] = ((k1*ascii[j])+k2) % 224 ;
}
//change the decimal (ASCII code) value back to characters
char[] charen = new char[c.length];
for (int i = 0; i < c.length; i++) {
charen[i] = (char)c[i];
}
//change characters to String
String pesan_en = String.valueOf(charen);
return pesan_en;
}
//decryption method
public static String dekripsi(String isipesanMasuk, int k1, int k2){
int j,g;
int[] c;
int[] f = new int [224];
//change text message into array
char[] chars = isipesanMasuk.toCharArray();
//getting ASCII code from each characters index
int[] ascii = new int[chars.length];
for (int i = 0; i < chars.length; i++) {
ascii[i] = (int) chars[i];
}
//getting inverse from encryption formula of Affine
//example 33f = 1 (mod) 224 -> f = (1+(224 * j)) / 5
//g = (33 * f) mod 224
//if g = 1 then stop
for (j = 1; j < 224; j++) {
f[j] = (1 +(224*j)) / k1;
g = (k1*f[j]) % 224 ;
if (g==1) {
break;
}
}
//Affine decrypion formula
c = new int[ascii.length];
for (int k = 0; k < ascii.length; k++) {
c[k] = (f[j]*(ascii[k]-k2)) % 224 ;
}
//change the decimal (ASCII code) value back to characters
char[] charde = new char[c.length];
for (int i = 0; i < c.length; i++) {
charde[i] = (char)c[i];
}
//change characters to String
String pesan_de = String.valueOf(charde);
return pesan_de;
}
}
The decryption formula breaks down if ascii[k]-k2 gives a negative value. To fix that use this:
c[k] = (f[j]*(ascii[k]-k2+224)) % 224;
Some other remarks:
you don't need an array to calculate the inverse of k1, a simple integer variable will do.
The encryption can result in control characters (\u0000 to \u000f and \u007f to \u009f) that might not be transported unaltered across all channels.
GOAL OF CODE :(using netbeans)
I was trying to write this code to apply the caesar cipher algorithm where multiple keys can be used in order e.g : key = [1,2,3] , text = test , where it will use key as "1" on "t" then key "2" on "e" then key "3" on "s" then return to key "1" on last t .
OUTPUT :
run:
Enter the text : mohammad rahmat
Enter the number of keys you want to use : 3
Enter 3 number of keys : 1
2
3
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
at caesar.Caesar.main(Caesar.java:68)
nqkbopbfbsckncw
Java Result: 1
BUILD SUCCESSFUL (total time: 9 seconds)
CODE :
package caesar;
import java.util.Scanner;
public class Caesar {
/**
* #param args the command line arguments
*/
static Scanner input = new Scanner(System.in);
public static void main(String[] args) {
// TODO code application logic here
char table[] = {'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',' ','.'};
String tmp;
System.out.print("Enter the text : ");
tmp = input.nextLine();
char text[] = tmp.toCharArray();
System.out.print("Enter the number of keys you want to use : ");
int keyNo = input.nextInt();
int key[] = new int[keyNo];
System.out.printf("Enter %d number of keys : ",keyNo);
for (int i = 0; i < keyNo; ++i){
key[i] = input.nextInt();
}
char entext[] = new char[text.length];
int k = 0;
int a = 0;
int count = 0;
while (k < text.length){
int j = 0;
while (text[a] != table[j])
j++;
if (key[count]+j >= table.length){
entext[a] = table[(j+key[count])%table.length];
}
else entext[a] = table[j+key[count]];
a++;
count++;
if (count == keyNo)
count = 0;
k++;
}
String answer = new String(entext);
System.out.printf("ENCRYPTION : %s \n\n",answer);
char detext[] = new char[text.length];
k = 0;
a = 0;
count = 0;
while (k < text.length){
int j = 0;
while (text[a] != table[j])
j++;
if (key[count]-j < 0){
detext[a] = table[table.length+(key[count]-j)];
}
else detext[a] = table[j-key[count]];
a++;
count++;
if (count == keyNo)
count = 0;
k++;
}
String answer2 = new String(detext);
System.out.printf("DECRYPTION : %s\n\n",answer2);
}
}
you should use a debugger to analyze your code.
detext[a] = table[table.length+(key[count]-j)];
you're incrementing j and subtracting it from count which is zero. increment count before you operate on finding finding array index.
i found it finally , while converting it back to original text I had to take the converted text , in other words :
replace
while (k < text.length){
int j = 0;
while (text[a] != table[j])
with
while (k < entext.length){
int j = 0;
while (entext[a] != table[j])
I am working on the RSA algorithm and have made some progress but it is not working. I have the following code.
public class RSA
{
public static void main(String args[])
{
String plainText = "ITS ALL GREEK TO ME";//temp local plaintext ignoring parameter
plainText = plainText.toUpperCase();
plainText = plainText.replaceAll("\\s","");
System.out.println(plainText);
String cipherText = "";
int p = 47; //has been provided
int q = 59; //has been provided
int d = 157; //has been provided
int n = p * q;//calculate n
int w = (p - 1)*(q - 1);// calculate W
int c = 0;//we will compute this = cipher variable
int m = 920;//hardcoded for now
int e = 17;//hardcoded for now
//start of euclids
ArrayList<Integer> remainderlist=new ArrayList<Integer>();//array list to hold the remainder values in euclids algorithm from the quotient
remainderlist.add(w);// step 1 of euclids algorithm starting with value of w as above
remainderlist.add(d);// step 2 of euclids algorithm to add value of d
int remainderposition1 = 0;
int remainderposition2 = 1;
int quotient = 0;
int remainder = 0;
while (remainderlist.get(remainderposition1)%(remainderlist.get(remainderposition2))>0){
quotient = remainderlist.get(remainderposition1)/remainderlist.get(remainderposition2);
remainder = remainderlist.get(remainderposition1)%remainderlist.get(remainderposition2);
remainderlist.add(remainder);
System.out.println("Q: " +quotient);
System.out.println("R: " +remainder);
System.out.println("");
remainderposition1++;
remainderposition2++;
}
//start string processing
//loop etc
if (plainText.length()%2!=0)
{
plainText = plainText + " ";
}
for (int i = 0, i < plainText.length(); i = i+2)
{
char plTChar1 = plainText.CharAt(i);
char plTChar2 = plainText.CharAt(i + 1);
// Convert the character into an ASCII table value.
int asciiValue1 = (int) plTChar1;
int asciiValue2 = (int) plTChar2;
String numStr1 = asciiValue1.parseInt;
String numStr2 = asciiValue2.parseInt;
if (numStr.length() < 2)
{
numStr = "0" + numStr;
}
String fullNum = numStr1 + numStr2;
int m = Integer.parse(fullNum);
//start of encryption algorithm
String binarystring = Integer.toBinaryString(e);// step 1
System.out.println(binarystring);
c = 1; // step 2 of the encryption algorithm - notes
for (int i = 0; i<binarystring.length();i++)
{
c = (c*c)%n;// setp 3a
System.out.println(binarystring.charAt(i));
// step 3b notes
if (binarystring.charAt(i)=='1') {
c = (c*m)%n;
}
}
System.out.println("Cipher"+c);
}
When I build the file I get errors on the line for (int i = 0, i < plainText.length(); i = i+2) saying that quotation marks are expected and that it is an illegal start to an expression. I'm lost
You have a comma instead of a semi-colon.
for (int i = 0, i < plainText.length(); i = i+2)
Should be
for (int i = 0; i < plainText.length(); i = i+2)
Often the smallest syntax error will confuse you for hours!