-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTranspositionScheme.java
More file actions
144 lines (120 loc) · 3.55 KB
/
TranspositionScheme.java
File metadata and controls
144 lines (120 loc) · 3.55 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
134
135
136
137
138
139
140
141
142
143
144
package DiffieHellman;
import java.util.Arrays;
public class TranspositionScheme {
/**
*Empty Spaces in matrix causes problems.
*Therefore, it needs to be filled with ~
*/
private static final char MATRIX_FILLER_CHAR = '~';
/**
*Key required to encrypt and decrypt the message.
*/
private final int[] Key;
public TranspositionScheme(int[] Key)
{
this.Key = Key;
}
/**
*Arranges the text into a matrix, then transposes the matrix using the key.
*/
public String encrypt(String text)
{
char[][] matrix = createEncryptedMatrix(text);
return getTextFromMatrix(matrix);
}
private char[][] createEncryptedMatrix(String text)
{
int numberOfColumns = Key.length;
int numberOfRows = getNumberOfRows(text);
char[][] matrix = buildMatrix(numberOfRows, numberOfColumns, text);
char[][] transposedMatrix = new char[matrix[0].length][matrix.length];
int numberOfRowsTransposedMatrix = matrix.length;
int i = 0;
for (int col : Key)
{
for (int row = 0; row < numberOfRowsTransposedMatrix; row++)
{
transposedMatrix[i][row] = matrix[row][col];
}
i++;
}
return transposedMatrix;
}
/**
*Build the matrix with the specified number of rows and columns.
*/
private char[][] buildMatrix(int rows, int columns, String text)
{
char[][] matrix = new char[rows][columns];
for (char[] row : matrix)
{
Arrays.fill(row, MATRIX_FILLER_CHAR);
}
char[] chars = text.toCharArray();
for (int i = 0; i < text.length(); i++)
{
matrix[i / columns][i % columns] = chars[i];
}
return matrix;
}
/**
*Calculate the number of rows needed for the matrix, given the length of
*the text and the length of the transposition key.
*/
private int getNumberOfRows(String text)
{
int fullRows = text.length() / Key.length;
int remainder = text.length() % Key.length;
return (remainder == 0) ? fullRows : ++fullRows;
}
/**
*Iterates over the matrix left to right and top to bottom, returning the
*text.
*/
private String getTextFromMatrix(char[][] matrix)
{
String text = "";
for (char[] row : matrix)
{
for (char c : row)
{
if (c != Character.MIN_VALUE) text += c;
}
}
return text;
}
/**
*Reverses the process of {@link #encrypt(String)}, decrpyting the *ciphertext.
*/
public String decrypt(String ciphertext)
{
char[][] matrix = createDecryptedMatrix(ciphertext);
return getTextFromMatrix(matrix);
}
private char[][] createDecryptedMatrix(String ciphertext)
{
int numberOfRows = Key.length;
int numberOfColumns = getNumberOfRows(ciphertext);
char[][] matrix = buildMatrix(numberOfRows, numberOfColumns, ciphertext);
char[][] detransposedMatrix = new char[matrix[0].length][matrix.length];
int numberOfRowsDetransposedMatrix = matrix.length;
int numberOfColumnsDetransposedMatrix = matrix[0].length;
for (int row = 0; row < numberOfRowsDetransposedMatrix; row++)
{
for (int col = 0; col < numberOfColumnsDetransposedMatrix; col++)
{
detransposedMatrix[col][Key[row]] = matrix[row][col];
}
}
for (int col = detransposedMatrix[0].length - 1; col > 0; col--)
{
if (detransposedMatrix[detransposedMatrix.length - 1][col] ==
MATRIX_FILLER_CHAR)
{
detransposedMatrix[detransposedMatrix.length - 1][col] =
Character.MIN_VALUE;
}
}
return detransposedMatrix;
}
}