-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCaesarCipherDemo.java
More file actions
133 lines (117 loc) · 4.84 KB
/
Copy pathCaesarCipherDemo.java
File metadata and controls
133 lines (117 loc) · 4.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import java.util.Scanner;
/**
* This class encrypts strings with a keyphrase version of the classic
* Caesar Cipher.
* (as described in The Code Book by Simon Singh)
*
* @author gcschmit
* @version 21 September 2018
*/
public class CaesarCipherDemo
{
private static final String ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private String keyphrase;
/**
* Returns a string that describes the average time to crack the cipher,
* in several formats, based on the specified numbers of seconds per guess
*
* @param secPerGuess the number of seconds tro evaluate each attempt
* @return a string that describes the average time to crack the cipher
*/
public String getComplexityDescriptio(int secPerGuess){
/*
* Instead of using a "magic number" use constants defined by us or java standard library
* Declare a constant witht the final keyword
*/
final int SECONDS_FOR_EVERY_MINUTE = 60;
final int MINUTES_FOR_EVERY_HOUR = 60;
final int HOURS_FOR_EVERY_DAY = 24;
final int DAYS_FOR_EVERY_YEAR = 365;
String desc = "";
long totalSeconds = this.calculateAverageTimeToCrack(secPerGuess);
}
/**
* Encrypts the specified text using the specified keyphrase using a
* keyphrase-enhanced Caesar Cipher.
*
* @param text the text to encrypt
* @param keyphrase the keyphrase with which to encrypt the specified text
* @return the encrypted text
*/
public String encrypt(String text)
{
String encryptedText = "";
/*
* The keyphrase, after removing any repeated letters is used as the beginning of the
* jumbled cipher alphabet. The remainder of the cipher alphabet is merely the
* remaining letters of the alphabet, in their correct order, starting where the
* keyphrase ends.
*/
String cipherAlphabet = this.keyphrase;
for(int i = 0; i < CaesarCipher.ALPHABET.length(); i++)
{
char letter = CaesarCipher.ALPHABET.charAt(i);
if(this.keyphrase.indexOf(letter) == -1)
{
cipherAlphabet += letter;
}
}
/*
* For each letter in the text that is a letter, find the corresponding letter
* at the same position in the cipher alphabet as its replacement.
*/
for(int i = 0; i < text.length(); i++)
{
char letter = text.charAt(i);
// if the letter is between A and Z
if(letter >= 'A' && letter <= 'Z')
{
// 65 is the ASCII value of 'A'
int cipherIndex = letter - 65;
encryptedText += cipherAlphabet.charAt(cipherIndex);
}
else // don't substitute the letter; just use it as is
{
encryptedText += letter;
}
}
return encryptedText;
}
/**
* Calcualtes the average time to crack the cipher, based on the
* specified length of the keyphrase and seconds to evaluate
* each attempt, using a brute force approach. This calculation
* assumes that the cracker knows the length of the keyphrase.
* If the length is not know, it will take substantially longer
* to crack the cipher. Regardless, this calculation is only
* for a brute force approach; other techniques (e.g., frequency
* analysis) can crack the cipher extremely quickly.
*
* @param keyphraseLength the number of characters in the keyphrase
* @param secPerGuess the number of seconds to evaluate each attempt
* @return the average number of seconds to crack the cipher
*/
public long calculateAverageTimeToCrack(int secPerGuess)
{
final int NUMBER_OF_LETTERS_IN_ALPHABET = 26;
int lettersRemaining = NUMBER_OF_LETTERS_IN_ALPHABET;
int keyphraseLength = this.keyphrase.length();
long combinations = 1;
/*
* Calculate the number of combintations for the specified keyphrase length.
* For example, if the keyphrase is six characters long:
* 26 * 25 * 24 * 23 * 22 * 21
* would be the number of combinations of cipher alphabets for keyphrases
* that are six characters long.
*/
for(int i = 0; i < keyphraseLength; i++)
{
combinations *= lettersRemaining;
lettersRemaining -= 1;
}
long worstCaseTimeToCrack = combinations * secPerGuess;
// average time is half the worst time since the best time is cracking the
// cipher on the first attempt
return worstCaseTimeToCrack/2;
}
}