mirror of
https://github.com/TheAlgorithms/Java.git
synced 2025-07-23 04:20:16 +08:00
@ -2395,9 +2395,7 @@ public class AES {
|
||||
|
||||
// apply S-Box to all 8-Bit Substrings
|
||||
for (int i = 0; i < 4; i++) {
|
||||
StringBuilder currentByteBits = new StringBuilder(
|
||||
rBytes.substring(i * 2, (i + 1) * 2)
|
||||
);
|
||||
StringBuilder currentByteBits = new StringBuilder(rBytes.substring(i * 2, (i + 1) * 2));
|
||||
|
||||
int currentByte = Integer.parseInt(currentByteBits.toString(), 16);
|
||||
currentByte = SBOX[currentByte];
|
||||
@ -2407,8 +2405,7 @@ public class AES {
|
||||
currentByte = currentByte ^ RCON[rconCounter];
|
||||
}
|
||||
|
||||
currentByteBits =
|
||||
new StringBuilder(Integer.toHexString(currentByte));
|
||||
currentByteBits = new StringBuilder(Integer.toHexString(currentByte));
|
||||
|
||||
// Add zero padding
|
||||
while (currentByteBits.length() < 2) {
|
||||
@ -2416,12 +2413,8 @@ public class AES {
|
||||
}
|
||||
|
||||
// replace bytes in original string
|
||||
rBytes =
|
||||
new StringBuilder(
|
||||
rBytes.substring(0, i * 2) +
|
||||
currentByteBits +
|
||||
rBytes.substring((i + 1) * 2)
|
||||
);
|
||||
rBytes = new StringBuilder(
|
||||
rBytes.substring(0, i * 2) + currentByteBits + rBytes.substring((i + 1) * 2));
|
||||
}
|
||||
|
||||
// t = new BigInteger(rBytes, 16);
|
||||
@ -2438,16 +2431,16 @@ public class AES {
|
||||
public static BigInteger[] keyExpansion(BigInteger initialKey) {
|
||||
BigInteger[] roundKeys = {
|
||||
initialKey,
|
||||
BigInteger.ZERO,
|
||||
BigInteger.ZERO,
|
||||
BigInteger.ZERO,
|
||||
BigInteger.ZERO,
|
||||
BigInteger.ZERO,
|
||||
BigInteger.ZERO,
|
||||
BigInteger.ZERO,
|
||||
BigInteger.ZERO,
|
||||
BigInteger.ZERO,
|
||||
BigInteger.ZERO,
|
||||
BigInteger.ZERO,
|
||||
BigInteger.ZERO,
|
||||
BigInteger.ZERO,
|
||||
BigInteger.ZERO,
|
||||
BigInteger.ZERO,
|
||||
BigInteger.ZERO,
|
||||
BigInteger.ZERO,
|
||||
BigInteger.ZERO,
|
||||
BigInteger.ZERO,
|
||||
BigInteger.ZERO,
|
||||
};
|
||||
|
||||
// initialize rcon iteration
|
||||
@ -2455,23 +2448,18 @@ public class AES {
|
||||
|
||||
for (int i = 1; i < 11; i++) {
|
||||
// get the previous 32 bits the key
|
||||
BigInteger t =
|
||||
roundKeys[i - 1].remainder(new BigInteger("100000000", 16));
|
||||
BigInteger t = roundKeys[i - 1].remainder(new BigInteger("100000000", 16));
|
||||
|
||||
// split previous key into 8-bit segments
|
||||
BigInteger[] prevKey = {
|
||||
roundKeys[i - 1].remainder(new BigInteger("100000000", 16)),
|
||||
roundKeys[i - 1].remainder(
|
||||
new BigInteger("10000000000000000", 16)
|
||||
)
|
||||
roundKeys[i - 1]
|
||||
.remainder(new BigInteger("10000000000000000", 16))
|
||||
.divide(new BigInteger("100000000", 16)),
|
||||
roundKeys[i - 1].remainder(
|
||||
new BigInteger("1000000000000000000000000", 16)
|
||||
)
|
||||
roundKeys[i - 1]
|
||||
.remainder(new BigInteger("1000000000000000000000000", 16))
|
||||
.divide(new BigInteger("10000000000000000", 16)),
|
||||
roundKeys[i - 1].divide(
|
||||
new BigInteger("1000000000000000000000000", 16)
|
||||
),
|
||||
roundKeys[i - 1].divide(new BigInteger("1000000000000000000000000", 16)),
|
||||
};
|
||||
|
||||
// run schedule core
|
||||
@ -2527,9 +2515,7 @@ public class AES {
|
||||
public static BigInteger mergeCellsIntoBlock(int[] cells) {
|
||||
StringBuilder blockBits = new StringBuilder();
|
||||
for (int i = 0; i < 16; i++) {
|
||||
StringBuilder cellBits = new StringBuilder(
|
||||
Integer.toBinaryString(cells[i])
|
||||
);
|
||||
StringBuilder cellBits = new StringBuilder(Integer.toBinaryString(cells[i]));
|
||||
|
||||
// Append leading 0 for full "8-bit" strings
|
||||
while (cellBits.length() < 8) {
|
||||
@ -2545,10 +2531,7 @@ public class AES {
|
||||
/**
|
||||
* @return ciphertext XOR key
|
||||
*/
|
||||
public static BigInteger addRoundKey(
|
||||
BigInteger ciphertext,
|
||||
BigInteger key
|
||||
) {
|
||||
public static BigInteger addRoundKey(BigInteger ciphertext, BigInteger key) {
|
||||
return ciphertext.xor(key);
|
||||
}
|
||||
|
||||
@ -2669,14 +2652,10 @@ public class AES {
|
||||
cells[i * 4 + 3],
|
||||
};
|
||||
|
||||
outputCells[i * 4] =
|
||||
MULT2[row[0]] ^ MULT3[row[1]] ^ row[2] ^ row[3];
|
||||
outputCells[i * 4 + 1] =
|
||||
row[0] ^ MULT2[row[1]] ^ MULT3[row[2]] ^ row[3];
|
||||
outputCells[i * 4 + 2] =
|
||||
row[0] ^ row[1] ^ MULT2[row[2]] ^ MULT3[row[3]];
|
||||
outputCells[i * 4 + 3] =
|
||||
MULT3[row[0]] ^ row[1] ^ row[2] ^ MULT2[row[3]];
|
||||
outputCells[i * 4] = MULT2[row[0]] ^ MULT3[row[1]] ^ row[2] ^ row[3];
|
||||
outputCells[i * 4 + 1] = row[0] ^ MULT2[row[1]] ^ MULT3[row[2]] ^ row[3];
|
||||
outputCells[i * 4 + 2] = row[0] ^ row[1] ^ MULT2[row[2]] ^ MULT3[row[3]];
|
||||
outputCells[i * 4 + 3] = MULT3[row[0]] ^ row[1] ^ row[2] ^ MULT2[row[3]];
|
||||
}
|
||||
return mergeCellsIntoBlock(outputCells);
|
||||
}
|
||||
@ -2697,26 +2676,13 @@ public class AES {
|
||||
cells[i * 4 + 3],
|
||||
};
|
||||
|
||||
outputCells[i * 4] =
|
||||
MULT14[row[0]] ^
|
||||
MULT11[row[1]] ^
|
||||
MULT13[row[2]] ^
|
||||
MULT9[row[3]];
|
||||
outputCells[i * 4 + 1] =
|
||||
MULT9[row[0]] ^
|
||||
MULT14[row[1]] ^
|
||||
MULT11[row[2]] ^
|
||||
MULT13[row[3]];
|
||||
outputCells[i * 4 + 2] =
|
||||
MULT13[row[0]] ^
|
||||
MULT9[row[1]] ^
|
||||
MULT14[row[2]] ^
|
||||
MULT11[row[3]];
|
||||
outputCells[i * 4 + 3] =
|
||||
MULT11[row[0]] ^
|
||||
MULT13[row[1]] ^
|
||||
MULT9[row[2]] ^
|
||||
MULT14[row[3]];
|
||||
outputCells[i * 4] = MULT14[row[0]] ^ MULT11[row[1]] ^ MULT13[row[2]] ^ MULT9[row[3]];
|
||||
outputCells[i * 4 + 1]
|
||||
= MULT9[row[0]] ^ MULT14[row[1]] ^ MULT11[row[2]] ^ MULT13[row[3]];
|
||||
outputCells[i * 4 + 2]
|
||||
= MULT13[row[0]] ^ MULT9[row[1]] ^ MULT14[row[2]] ^ MULT11[row[3]];
|
||||
outputCells[i * 4 + 3]
|
||||
= MULT11[row[0]] ^ MULT13[row[1]] ^ MULT9[row[2]] ^ MULT14[row[3]];
|
||||
}
|
||||
return mergeCellsIntoBlock(outputCells);
|
||||
}
|
||||
@ -2780,9 +2746,7 @@ public class AES {
|
||||
|
||||
public static void main(String[] args) {
|
||||
try (Scanner input = new Scanner(System.in)) {
|
||||
System.out.println(
|
||||
"Enter (e) letter for encrpyt or (d) letter for decrypt :"
|
||||
);
|
||||
System.out.println("Enter (e) letter for encrpyt or (d) letter for decrypt :");
|
||||
char choice = input.nextLine().charAt(0);
|
||||
String in;
|
||||
switch (choice) {
|
||||
|
@ -1,10 +1,10 @@
|
||||
package com.thealgorithms.ciphers;
|
||||
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.GCMParameterSpec;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
|
||||
/**
|
||||
* This example program shows how AES encryption and decryption can be done in
|
||||
@ -29,12 +29,8 @@ public class AESEncryption {
|
||||
String decryptedText = decryptText(cipherText, secKey);
|
||||
|
||||
System.out.println("Original Text:" + plainText);
|
||||
System.out.println(
|
||||
"AES Key (Hex Form):" + bytesToHex(secKey.getEncoded())
|
||||
);
|
||||
System.out.println(
|
||||
"Encrypted Text (Hex Form):" + bytesToHex(cipherText)
|
||||
);
|
||||
System.out.println("AES Key (Hex Form):" + bytesToHex(secKey.getEncoded()));
|
||||
System.out.println("Encrypted Text (Hex Form):" + bytesToHex(cipherText));
|
||||
System.out.println("Descrypted Text:" + decryptedText);
|
||||
}
|
||||
|
||||
@ -45,8 +41,7 @@ public class AESEncryption {
|
||||
* @return secKey (Secret key that we encrypt using it)
|
||||
* @throws NoSuchAlgorithmException (from KeyGenrator)
|
||||
*/
|
||||
public static SecretKey getSecretEncryptionKey()
|
||||
throws NoSuchAlgorithmException {
|
||||
public static SecretKey getSecretEncryptionKey() throws NoSuchAlgorithmException {
|
||||
KeyGenerator aesKeyGenerator = KeyGenerator.getInstance("AES");
|
||||
aesKeyGenerator.init(128); // The AES key size in number of bits
|
||||
return aesKeyGenerator.generateKey();
|
||||
@ -63,7 +58,8 @@ public class AESEncryption {
|
||||
* @throws IllegalBlockSizeException (from Cipher)
|
||||
*/
|
||||
public static byte[] encryptText(String plainText, SecretKey secKey)
|
||||
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
|
||||
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
|
||||
IllegalBlockSizeException, BadPaddingException {
|
||||
// AES defaults to AES/ECB/PKCS5Padding in Java 7
|
||||
aesCipher = Cipher.getInstance("AES/GCM/NoPadding");
|
||||
aesCipher.init(Cipher.ENCRYPT_MODE, secKey);
|
||||
@ -76,8 +72,8 @@ public class AESEncryption {
|
||||
* @return plainText
|
||||
*/
|
||||
public static String decryptText(byte[] byteCipherText, SecretKey secKey)
|
||||
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
|
||||
IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException {
|
||||
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
|
||||
IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException {
|
||||
// AES defaults to AES/ECB/PKCS5Padding in Java 7
|
||||
Cipher decryptionCipher = Cipher.getInstance("AES/GCM/NoPadding");
|
||||
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128, aesCipher.getIV());
|
||||
|
@ -15,8 +15,7 @@ class AffineCipher {
|
||||
{here x is msg[i] and m is 26} and added 'A' to
|
||||
bring it in range of ascii alphabet[ 65-90 | A-Z ] */
|
||||
if (msg[i] != ' ') {
|
||||
cipher =
|
||||
cipher + (char) ((((a * (msg[i] - 'A')) + b) % 26) + 'A');
|
||||
cipher = cipher + (char) ((((a * (msg[i] - 'A')) + b) % 26) + 'A');
|
||||
} else { // else simply append space character
|
||||
cipher += msg[i];
|
||||
}
|
||||
@ -29,8 +28,8 @@ class AffineCipher {
|
||||
int a_inv = 0;
|
||||
int flag = 0;
|
||||
|
||||
//Find a^-1 (the multiplicative inverse of a
|
||||
//in the group of integers modulo m.)
|
||||
// Find a^-1 (the multiplicative inverse of a
|
||||
// in the group of integers modulo m.)
|
||||
for (int i = 0; i < 26; i++) {
|
||||
flag = (a * i) % 26;
|
||||
|
||||
@ -45,12 +44,8 @@ class AffineCipher {
|
||||
{here x is cipher[i] and m is 26} and added 'A'
|
||||
to bring it in range of ASCII alphabet[ 65-90 | A-Z ] */
|
||||
if (cipher.charAt(i) != ' ') {
|
||||
msg =
|
||||
msg +
|
||||
(char) (
|
||||
((a_inv * ((cipher.charAt(i) + 'A' - b)) % 26)) + 'A'
|
||||
);
|
||||
} else { //else simply append space character
|
||||
msg = msg + (char) (((a_inv * ((cipher.charAt(i) + 'A' - b)) % 26)) + 'A');
|
||||
} else { // else simply append space character
|
||||
msg += cipher.charAt(i);
|
||||
}
|
||||
}
|
||||
@ -67,8 +62,6 @@ class AffineCipher {
|
||||
System.out.println("Encrypted Message is : " + cipherText);
|
||||
|
||||
// Calling Decryption function
|
||||
System.out.println(
|
||||
"Decrypted Message is: " + decryptCipher(cipherText)
|
||||
);
|
||||
System.out.println("Decrypted Message is: " + decryptCipher(cipherText));
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ package com.thealgorithms.ciphers;
|
||||
|
||||
public class Blowfish {
|
||||
|
||||
//Initializing substitution boxes
|
||||
// Initializing substitution boxes
|
||||
String[][] S = {
|
||||
{
|
||||
"d1310ba6",
|
||||
@ -1046,7 +1046,7 @@ public class Blowfish {
|
||||
},
|
||||
};
|
||||
|
||||
//Initializing subkeys with digits of pi
|
||||
// Initializing subkeys with digits of pi
|
||||
String[] P = {
|
||||
"243f6a88",
|
||||
"85a308d3",
|
||||
@ -1068,7 +1068,7 @@ public class Blowfish {
|
||||
"8979fb1b",
|
||||
};
|
||||
|
||||
//Initializing modVal to 2^32
|
||||
// Initializing modVal to 2^32
|
||||
long modVal = 4294967296L;
|
||||
|
||||
/**
|
||||
@ -1098,7 +1098,8 @@ public class Blowfish {
|
||||
* This method returns hexadecimal representation of the binary number passed as parameter
|
||||
*
|
||||
* @param binary Number for which hexadecimal representation is required
|
||||
* @return String object which is a hexadecimal representation of the binary number passed as parameter
|
||||
* @return String object which is a hexadecimal representation of the binary number passed as
|
||||
* parameter
|
||||
*/
|
||||
private String binToHex(String binary) {
|
||||
long num = Long.parseUnsignedLong(binary, 2);
|
||||
@ -1109,7 +1110,8 @@ public class Blowfish {
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a string obtained by XOR-ing two strings of same length passed a method parameters
|
||||
* This method returns a string obtained by XOR-ing two strings of same length passed a method
|
||||
* parameters
|
||||
*
|
||||
* @param String a and b are string objects which will be XORed and are to be of same length
|
||||
* @return String object obtained by XOR operation on String a and String b
|
||||
@ -1118,17 +1120,19 @@ public class Blowfish {
|
||||
a = hexToBin(a);
|
||||
b = hexToBin(b);
|
||||
String ans = "";
|
||||
for (int i = 0; i < a.length(); i++) ans +=
|
||||
(char) (((a.charAt(i) - '0') ^ (b.charAt(i) - '0')) + '0');
|
||||
for (int i = 0; i < a.length(); i++)
|
||||
ans += (char) (((a.charAt(i) - '0') ^ (b.charAt(i) - '0')) + '0');
|
||||
ans = binToHex(ans);
|
||||
return ans;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns addition of two hexadecimal numbers passed as parameters and moded with 2^32
|
||||
* This method returns addition of two hexadecimal numbers passed as parameters and moded with
|
||||
* 2^32
|
||||
*
|
||||
* @param String a and b are hexadecimal numbers
|
||||
* @return String object which is a is addition that is then moded with 2^32 of hex numbers passed as parameters
|
||||
* @return String object which is a is addition that is then moded with 2^32 of hex numbers
|
||||
* passed as parameters
|
||||
*/
|
||||
private String addBin(String a, String b) {
|
||||
String ans = "";
|
||||
@ -1140,20 +1144,17 @@ public class Blowfish {
|
||||
return ans.substring(ans.length() - 8);
|
||||
}
|
||||
|
||||
/*F-function splits the 32-bit input into four 8-bit quarters
|
||||
and uses the quarters as input to the S-boxes.
|
||||
The S-boxes accept 8-bit input and produce 32-bit output.
|
||||
The outputs are added modulo 232 and XORed to produce the final 32-bit output
|
||||
*/
|
||||
/*F-function splits the 32-bit input into four 8-bit quarters
|
||||
and uses the quarters as input to the S-boxes.
|
||||
The S-boxes accept 8-bit input and produce 32-bit output.
|
||||
The outputs are added modulo 232 and XORed to produce the final 32-bit output
|
||||
*/
|
||||
private String f(String plainText) {
|
||||
String[] a = new String[4];
|
||||
String ans = "";
|
||||
for (int i = 0; i < 8; i += 2) {
|
||||
//column number for S-box is a 8-bit value
|
||||
long col = Long.parseUnsignedLong(
|
||||
hexToBin(plainText.substring(i, i + 2)),
|
||||
2
|
||||
);
|
||||
// column number for S-box is a 8-bit value
|
||||
long col = Long.parseUnsignedLong(hexToBin(plainText.substring(i, i + 2)), 2);
|
||||
a[i / 2] = S[i / 2][(int) col];
|
||||
}
|
||||
ans = addBin(a[0], a[1]);
|
||||
@ -1162,30 +1163,30 @@ public class Blowfish {
|
||||
return ans;
|
||||
}
|
||||
|
||||
//generate subkeys
|
||||
// generate subkeys
|
||||
private void keyGenerate(String key) {
|
||||
int j = 0;
|
||||
for (int i = 0; i < P.length; i++) {
|
||||
//XOR-ing 32-bit parts of the key with initial subkeys
|
||||
// XOR-ing 32-bit parts of the key with initial subkeys
|
||||
P[i] = xor(P[i], key.substring(j, j + 8));
|
||||
|
||||
j = (j + 8) % key.length();
|
||||
}
|
||||
}
|
||||
|
||||
//round function
|
||||
// round function
|
||||
private String round(int time, String plainText) {
|
||||
String left, right;
|
||||
left = plainText.substring(0, 8);
|
||||
right = plainText.substring(8, 16);
|
||||
left = xor(left, P[time]);
|
||||
|
||||
//output from F function
|
||||
// output from F function
|
||||
String fOut = f(left);
|
||||
|
||||
right = xor(fOut, right);
|
||||
|
||||
//swap left and right
|
||||
// swap left and right
|
||||
return right + left;
|
||||
}
|
||||
|
||||
@ -1198,12 +1199,12 @@ public class Blowfish {
|
||||
* @return String cipherText is the encrypted value
|
||||
*/
|
||||
String encrypt(String plainText, String key) {
|
||||
//generating key
|
||||
// generating key
|
||||
keyGenerate(key);
|
||||
|
||||
for (int i = 0; i < 16; i++) plainText = round(i, plainText);
|
||||
|
||||
//postprocessing
|
||||
// postprocessing
|
||||
String right = plainText.substring(0, 8);
|
||||
String left = plainText.substring(8, 16);
|
||||
right = xor(right, P[16]);
|
||||
@ -1220,12 +1221,12 @@ public class Blowfish {
|
||||
* @return String plainText is the decrypted text
|
||||
*/
|
||||
String decrypt(String cipherText, String key) {
|
||||
//generating key
|
||||
// generating key
|
||||
keyGenerate(key);
|
||||
|
||||
for (int i = 17; i > 1; i--) cipherText = round(i, cipherText);
|
||||
|
||||
//postprocessing
|
||||
// postprocessing
|
||||
String right = cipherText.substring(0, 8);
|
||||
String left = cipherText.substring(8, 16);
|
||||
right = xor(right, P[1]);
|
||||
|
@ -23,16 +23,19 @@ public class Caesar {
|
||||
|
||||
final int length = message.length();
|
||||
for (int i = 0; i < length; i++) {
|
||||
// int current = message.charAt(i); //using char to shift characters because ascii
|
||||
// int current = message.charAt(i); //using char to shift characters because
|
||||
// ascii
|
||||
// is in-order latin alphabet
|
||||
char current = message.charAt(i); // Java law : char + int = char
|
||||
|
||||
if (isCapitalLatinLetter(current)) {
|
||||
current += shift;
|
||||
encoded.append((char) (current > 'Z' ? current - 26 : current)); // 26 = number of latin letters
|
||||
encoded.append((
|
||||
char) (current > 'Z' ? current - 26 : current)); // 26 = number of latin letters
|
||||
} else if (isSmallLatinLetter(current)) {
|
||||
current += shift;
|
||||
encoded.append((char) (current > 'z' ? current - 26 : current)); // 26 = number of latin letters
|
||||
encoded.append((
|
||||
char) (current > 'z' ? current - 26 : current)); // 26 = number of latin letters
|
||||
} else {
|
||||
encoded.append(current);
|
||||
}
|
||||
@ -56,10 +59,12 @@ public class Caesar {
|
||||
char current = encryptedMessage.charAt(i);
|
||||
if (isCapitalLatinLetter(current)) {
|
||||
current -= shift;
|
||||
decoded.append((char) (current < 'A' ? current + 26 : current)); // 26 = number of latin letters
|
||||
decoded.append((
|
||||
char) (current < 'A' ? current + 26 : current)); // 26 = number of latin letters
|
||||
} else if (isSmallLatinLetter(current)) {
|
||||
current -= shift;
|
||||
decoded.append((char) (current < 'a' ? current + 26 : current)); // 26 = number of latin letters
|
||||
decoded.append((
|
||||
char) (current < 'a' ? current + 26 : current)); // 26 = number of latin letters
|
||||
} else {
|
||||
decoded.append(current);
|
||||
}
|
||||
|
@ -12,9 +12,8 @@ public class ColumnarTranspositionCipher {
|
||||
private static String keyword;
|
||||
private static Object[][] table;
|
||||
private static String abecedarium;
|
||||
public static final String ABECEDARIUM =
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFG" +
|
||||
"HIJKLMNOPQRSTUVWXYZ0123456789,.;:-@";
|
||||
public static final String ABECEDARIUM = "abcdefghijklmnopqrstuvwxyzABCDEFG"
|
||||
+ "HIJKLMNOPQRSTUVWXYZ0123456789,.;:-@";
|
||||
private static final String ENCRYPTION_FIELD = "≈";
|
||||
private static final char ENCRYPTION_FIELD_CHAR = '≈';
|
||||
|
||||
@ -50,14 +49,10 @@ public class ColumnarTranspositionCipher {
|
||||
* @return a String with the word encrypted by the Columnar Transposition
|
||||
* Cipher Rule
|
||||
*/
|
||||
public static String encrpyter(
|
||||
String word,
|
||||
String keyword,
|
||||
String abecedarium
|
||||
) {
|
||||
public static String encrpyter(String word, String keyword, String abecedarium) {
|
||||
ColumnarTranspositionCipher.keyword = keyword;
|
||||
ColumnarTranspositionCipher.abecedarium =
|
||||
Objects.requireNonNullElse(abecedarium, ABECEDARIUM);
|
||||
ColumnarTranspositionCipher.abecedarium
|
||||
= Objects.requireNonNullElse(abecedarium, ABECEDARIUM);
|
||||
table = tableBuilder(word);
|
||||
Object[][] sortedTable = sortTable(table);
|
||||
StringBuilder wordEncrypted = new StringBuilder();
|
||||
@ -120,9 +115,7 @@ public class ColumnarTranspositionCipher {
|
||||
* order to respect the Columnar Transposition Cipher Rule.
|
||||
*/
|
||||
private static int numberOfRows(String word) {
|
||||
if (
|
||||
word.length() / keyword.length() > word.length() / keyword.length()
|
||||
) {
|
||||
if (word.length() / keyword.length() > word.length() / keyword.length()) {
|
||||
return (word.length() / keyword.length()) + 1;
|
||||
} else {
|
||||
return word.length() / keyword.length();
|
||||
@ -147,22 +140,12 @@ public class ColumnarTranspositionCipher {
|
||||
private static Object[][] sortTable(Object[][] table) {
|
||||
Object[][] tableSorted = new Object[table.length][table[0].length];
|
||||
for (int i = 0; i < tableSorted.length; i++) {
|
||||
System.arraycopy(
|
||||
table[i],
|
||||
0,
|
||||
tableSorted[i],
|
||||
0,
|
||||
tableSorted[i].length
|
||||
);
|
||||
System.arraycopy(table[i], 0, tableSorted[i], 0, tableSorted[i].length);
|
||||
}
|
||||
for (int i = 0; i < tableSorted[0].length; i++) {
|
||||
for (int j = i + 1; j < tableSorted[0].length; j++) {
|
||||
if ((int) tableSorted[0][i] > (int) table[0][j]) {
|
||||
Object[] column = getColumn(
|
||||
tableSorted,
|
||||
tableSorted.length,
|
||||
i
|
||||
);
|
||||
Object[] column = getColumn(tableSorted, tableSorted.length, i);
|
||||
switchColumns(tableSorted, j, i, column);
|
||||
}
|
||||
}
|
||||
@ -182,11 +165,7 @@ public class ColumnarTranspositionCipher {
|
||||
}
|
||||
|
||||
private static void switchColumns(
|
||||
Object[][] table,
|
||||
int firstColumnIndex,
|
||||
int secondColumnIndex,
|
||||
Object[] columnToSwitch
|
||||
) {
|
||||
Object[][] table, int firstColumnIndex, int secondColumnIndex, Object[] columnToSwitch) {
|
||||
for (int i = 0; i < table.length; i++) {
|
||||
table[i][secondColumnIndex] = table[i][firstColumnIndex];
|
||||
table[i][firstColumnIndex] = columnToSwitch[i];
|
||||
@ -217,22 +196,12 @@ public class ColumnarTranspositionCipher {
|
||||
|
||||
public static void main(String[] args) {
|
||||
String keywordForExample = "asd215";
|
||||
String wordBeingEncrypted =
|
||||
"This is a test of the Columnar Transposition Cipher";
|
||||
System.out.println(
|
||||
"### Example of Columnar Transposition Cipher ###\n"
|
||||
);
|
||||
String wordBeingEncrypted = "This is a test of the Columnar Transposition Cipher";
|
||||
System.out.println("### Example of Columnar Transposition Cipher ###\n");
|
||||
System.out.println("Word being encryped ->>> " + wordBeingEncrypted);
|
||||
System.out.println(
|
||||
"Word encrypted ->>> " +
|
||||
ColumnarTranspositionCipher.encrpyter(
|
||||
wordBeingEncrypted,
|
||||
keywordForExample
|
||||
)
|
||||
);
|
||||
System.out.println(
|
||||
"Word decryped ->>> " + ColumnarTranspositionCipher.decrypter()
|
||||
);
|
||||
System.out.println("Word encrypted ->>> "
|
||||
+ ColumnarTranspositionCipher.encrpyter(wordBeingEncrypted, keywordForExample));
|
||||
System.out.println("Word decryped ->>> " + ColumnarTranspositionCipher.decrypter());
|
||||
System.out.println("\n### Encrypted Table ###");
|
||||
showTable();
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
package com.thealgorithms.ciphers;
|
||||
|
||||
/**
|
||||
* This class is build to demonstrate the application of the DES-algorithm (https://en.wikipedia.org/wiki/Data_Encryption_Standard) on a
|
||||
* plain English message. The supplied key must be in form of a 64 bit binary String.
|
||||
* This class is build to demonstrate the application of the DES-algorithm
|
||||
* (https://en.wikipedia.org/wiki/Data_Encryption_Standard) on a plain English message. The supplied
|
||||
* key must be in form of a 64 bit binary String.
|
||||
*/
|
||||
public class DES {
|
||||
|
||||
@ -12,7 +13,8 @@ public class DES {
|
||||
private void sanitize(String key) {
|
||||
int length = key.length();
|
||||
if (length != 64) {
|
||||
throw new IllegalArgumentException("DES key must be supplied as a 64 character binary string");
|
||||
throw new IllegalArgumentException(
|
||||
"DES key must be supplied as a 64 character binary string");
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,170 +32,102 @@ public class DES {
|
||||
sanitize(key);
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
//Permutation table to convert initial 64 bit key to 56 bit key
|
||||
private static int[] PC1 =
|
||||
{
|
||||
57, 49, 41, 33, 25, 17, 9,
|
||||
1, 58, 50, 42, 34, 26, 18,
|
||||
10, 2, 59, 51, 43, 35, 27,
|
||||
19, 11, 3, 60, 52, 44, 36,
|
||||
63, 55, 47, 39, 31, 23, 15,
|
||||
7, 62, 54, 46, 38, 30, 22,
|
||||
14, 6, 61, 53, 45, 37, 29,
|
||||
21, 13, 5, 28, 20, 12, 4
|
||||
};
|
||||
|
||||
//Lookup table used to shift the initial key, in order to generate the subkeys
|
||||
private static int[] KEY_SHIFTS =
|
||||
{
|
||||
1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
|
||||
};
|
||||
// Permutation table to convert initial 64 bit key to 56 bit key
|
||||
private static int[] PC1 = {57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51,
|
||||
43, 35, 27, 19, 11, 3, 60, 52, 44, 36, 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30,
|
||||
22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4};
|
||||
|
||||
//Table to convert the 56 bit subkeys to 48 bit subkeys
|
||||
private static int[] PC2 =
|
||||
{
|
||||
14, 17, 11, 24, 1, 5,
|
||||
3, 28, 15, 6, 21, 10,
|
||||
23, 19, 12, 4, 26, 8,
|
||||
16, 7, 27, 20, 13, 2,
|
||||
41, 52, 31, 37, 47, 55,
|
||||
30, 40, 51, 45, 33, 48,
|
||||
44, 49, 39, 56, 34, 53,
|
||||
46, 42, 50, 36, 29, 32
|
||||
};
|
||||
// Lookup table used to shift the initial key, in order to generate the subkeys
|
||||
private static int[] KEY_SHIFTS = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};
|
||||
|
||||
//Initial permutatation of each 64 but message block
|
||||
private static int[] IP =
|
||||
{
|
||||
58, 50, 42, 34, 26, 18, 10 , 2,
|
||||
60, 52, 44, 36, 28, 20, 12, 4,
|
||||
62, 54, 46, 38, 30, 22, 14, 6,
|
||||
64, 56, 48, 40, 32, 24, 16, 8,
|
||||
57, 49, 41, 33, 25, 17, 9, 1,
|
||||
59, 51, 43, 35, 27, 19, 11, 3,
|
||||
61, 53, 45, 37, 29, 21, 13, 5,
|
||||
63, 55, 47, 39, 31, 23, 15, 7
|
||||
};
|
||||
// Table to convert the 56 bit subkeys to 48 bit subkeys
|
||||
private static int[] PC2 = {14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, 23, 19, 12, 4, 26, 8,
|
||||
16, 7, 27, 20, 13, 2, 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, 44, 49, 39, 56, 34,
|
||||
53, 46, 42, 50, 36, 29, 32};
|
||||
|
||||
//Expansion table to convert right half of message blocks from 32 bits to 48 bits
|
||||
private static int[] expansion =
|
||||
{
|
||||
32, 1, 2, 3, 4, 5,
|
||||
4, 5, 6, 7, 8, 9,
|
||||
8, 9, 10, 11, 12, 13,
|
||||
12, 13, 14, 15, 16, 17,
|
||||
16, 17, 18, 19, 20, 21,
|
||||
20, 21, 22, 23, 24, 25,
|
||||
24, 25, 26, 27, 28, 29,
|
||||
28, 29, 30, 31, 32, 1
|
||||
};
|
||||
|
||||
//The eight substitution boxes are defined below
|
||||
private static int[][] s1 = {
|
||||
{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7},
|
||||
{0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8},
|
||||
{4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0},
|
||||
{15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}
|
||||
};
|
||||
// Initial permutatation of each 64 but message block
|
||||
private static int[] IP = {58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54,
|
||||
46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8, 57, 49, 41, 33, 25, 17, 9, 1, 59, 51,
|
||||
43, 35, 27, 19, 11, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7};
|
||||
|
||||
private static int[][] s2 = {
|
||||
{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10},
|
||||
{3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5},
|
||||
{0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15},
|
||||
{13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}
|
||||
};
|
||||
|
||||
private static int[][] s3 = {
|
||||
{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8},
|
||||
{13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1},
|
||||
{13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7},
|
||||
{1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}
|
||||
};
|
||||
|
||||
private static int[][] s4 = {
|
||||
{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15},
|
||||
{13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9},
|
||||
{10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4},
|
||||
{3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}
|
||||
};
|
||||
|
||||
private static int[][] s5 = {
|
||||
{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9},
|
||||
{14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6},
|
||||
{4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14},
|
||||
{11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}
|
||||
};
|
||||
|
||||
private static int[][] s6 = {
|
||||
{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11},
|
||||
{10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8},
|
||||
{9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6},
|
||||
{4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}
|
||||
};
|
||||
|
||||
private static int[][] s7 = {
|
||||
{4, 11, 2, 14, 15, 0, 8, 13 , 3, 12, 9 , 7, 5, 10, 6, 1},
|
||||
{13 , 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6},
|
||||
{1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2},
|
||||
{6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}
|
||||
};
|
||||
|
||||
private static int[][] s8 = {
|
||||
{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7},
|
||||
{1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6 ,11, 0, 14, 9, 2},
|
||||
{7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10 ,13, 15, 3, 5, 8},
|
||||
{2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6 ,11}
|
||||
};
|
||||
|
||||
private static int[][][] s = {s1, s2, s3, s4, s5, s6, s7, s8};
|
||||
// Expansion table to convert right half of message blocks from 32 bits to 48 bits
|
||||
private static int[] expansion = {32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13, 12,
|
||||
13, 14, 15, 16, 17, 16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25, 24, 25, 26, 27, 28, 29,
|
||||
28, 29, 30, 31, 32, 1};
|
||||
|
||||
//Permutation table, used in the feistel function post s-box usage
|
||||
static int[] permutation =
|
||||
{
|
||||
16, 7, 20, 21,
|
||||
29, 12, 28, 17,
|
||||
1, 15, 23, 26,
|
||||
5, 18, 31, 10,
|
||||
2, 8, 24, 14,
|
||||
32, 27, 3, 9,
|
||||
19, 13, 30, 6,
|
||||
22, 11, 4, 25
|
||||
};
|
||||
// The eight substitution boxes are defined below
|
||||
private static int[][] s1 = {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7},
|
||||
{0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8},
|
||||
{4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0},
|
||||
{15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}};
|
||||
|
||||
//Table used for final inversion of the message box after 16 rounds of Feistel Function
|
||||
static int[] IPinverse =
|
||||
{
|
||||
40, 8, 48, 16, 56, 24, 64, 32,
|
||||
39, 7, 47, 15, 55, 23, 63, 31,
|
||||
38, 6, 46, 14, 54, 22, 62, 30,
|
||||
37, 5, 45, 13, 53, 21, 61, 29,
|
||||
36, 4, 44, 12, 52, 20, 60, 28,
|
||||
35, 3, 43 ,11, 51, 19, 59, 27,
|
||||
34, 2, 42, 10, 50, 18, 58, 26,
|
||||
33, 1, 41, 9, 49, 17, 57, 25
|
||||
};
|
||||
private static int[][] s2 = {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10},
|
||||
{3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5},
|
||||
{0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15},
|
||||
{13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}};
|
||||
|
||||
private static int[][] s3 = {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8},
|
||||
{13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1},
|
||||
{13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7},
|
||||
{1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}};
|
||||
|
||||
private static int[][] s4 = {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15},
|
||||
{13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9},
|
||||
{10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4},
|
||||
{3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}};
|
||||
|
||||
private static int[][] s5 = {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9},
|
||||
{14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6},
|
||||
{4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14},
|
||||
{11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}};
|
||||
|
||||
private static int[][] s6 = {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11},
|
||||
{10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8},
|
||||
{9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6},
|
||||
{4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}};
|
||||
|
||||
private static int[][] s7 = {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1},
|
||||
{13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6},
|
||||
{1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2},
|
||||
{6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}};
|
||||
|
||||
private static int[][] s8 = {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7},
|
||||
{1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2},
|
||||
{7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8},
|
||||
{2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}};
|
||||
|
||||
private static int[][][] s = {s1, s2, s3, s4, s5, s6, s7, s8};
|
||||
|
||||
// Permutation table, used in the feistel function post s-box usage
|
||||
static int[] permutation = {16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, 2, 8,
|
||||
24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25};
|
||||
|
||||
// Table used for final inversion of the message box after 16 rounds of Feistel Function
|
||||
static int[] IPinverse = {40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31, 38, 6,
|
||||
46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, 36, 4, 44, 12, 52, 20, 60, 28, 35, 3,
|
||||
43, 11, 51, 19, 59, 27, 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25};
|
||||
|
||||
private String[] getSubkeys(String originalKey) {
|
||||
StringBuilder permutedKey = new StringBuilder(); //Initial permutation of keys via PC1
|
||||
StringBuilder permutedKey = new StringBuilder(); // Initial permutation of keys via PC1
|
||||
int i, j;
|
||||
for (i = 0; i < 56; i++) {
|
||||
permutedKey.append(originalKey.charAt(PC1[i] - 1));
|
||||
permutedKey.append(originalKey.charAt(PC1[i] - 1));
|
||||
}
|
||||
String subKeys[] = new String[16];
|
||||
String initialPermutedKey = permutedKey.toString();
|
||||
String C0 = initialPermutedKey.substring(0, 28), D0 = initialPermutedKey.substring(28);
|
||||
|
||||
//We will now operate on the left and right halves of the permutedKey
|
||||
|
||||
// We will now operate on the left and right halves of the permutedKey
|
||||
for (i = 0; i < 16; i++) {
|
||||
String Cn = C0.substring(KEY_SHIFTS[i]) + C0.substring(0, KEY_SHIFTS[i]);
|
||||
String Dn = D0.substring(KEY_SHIFTS[i]) + D0.substring(0, KEY_SHIFTS[i]);
|
||||
subKeys[i] = Cn + Dn;
|
||||
C0 = Cn; //Re-assign the values to create running permutation
|
||||
C0 = Cn; // Re-assign the values to create running permutation
|
||||
D0 = Dn;
|
||||
}
|
||||
|
||||
//Let us shrink the keys to 48 bits (well, characters here) using PC2
|
||||
// Let us shrink the keys to 48 bits (well, characters here) using PC2
|
||||
for (i = 0; i < 16; i++) {
|
||||
String key = subKeys[i];
|
||||
permutedKey.setLength(0);
|
||||
@ -244,16 +178,17 @@ public class DES {
|
||||
String mixedKey = XOR(expandedKey.toString(), key);
|
||||
StringBuilder substitutedString = new StringBuilder();
|
||||
|
||||
//Let us now use the s-boxes to transform each 6 bit (length here) block to 4 bits
|
||||
// Let us now use the s-boxes to transform each 6 bit (length here) block to 4 bits
|
||||
for (i = 0; i < 48; i += 6) {
|
||||
String block = mixedKey.substring(i, i + 6);
|
||||
int row = (block.charAt(0) - 48) * 2 + (block.charAt(5) - 48);
|
||||
int col = (block.charAt(1) - 48) * 8 + (block.charAt(2) - 48) * 4 + (block.charAt(3) - 48) * 2 + (block.charAt(4) - 48);
|
||||
int col = (block.charAt(1) - 48) * 8 + (block.charAt(2) - 48) * 4
|
||||
+ (block.charAt(3) - 48) * 2 + (block.charAt(4) - 48);
|
||||
String substitutedBlock = pad(Integer.toBinaryString(s[i / 6][row][col]), 4);
|
||||
substitutedString.append(substitutedBlock);
|
||||
}
|
||||
|
||||
StringBuilder permutedString = new StringBuilder();
|
||||
StringBuilder permutedString = new StringBuilder();
|
||||
for (i = 0; i < 32; i++) {
|
||||
permutedString.append(substitutedString.charAt(permutation[i] - 1));
|
||||
}
|
||||
@ -269,7 +204,7 @@ public class DES {
|
||||
}
|
||||
String L0 = permutedMessage.substring(0, 32), R0 = permutedMessage.substring(32);
|
||||
|
||||
//Iterate 16 times
|
||||
// Iterate 16 times
|
||||
for (i = 0; i < 16; i++) {
|
||||
String Ln = R0; // Previous Right block
|
||||
String Rn = XOR(L0, feistel(R0, keys[i]));
|
||||
@ -277,7 +212,7 @@ public class DES {
|
||||
R0 = Rn;
|
||||
}
|
||||
|
||||
String combinedBlock = R0 + L0; //Reverse the 16th block
|
||||
String combinedBlock = R0 + L0; // Reverse the 16th block
|
||||
permutedMessage.setLength(0);
|
||||
for (i = 0; i < 64; i++) {
|
||||
permutedMessage.append(combinedBlock.charAt(IPinverse[i] - 1));
|
||||
@ -285,7 +220,7 @@ public class DES {
|
||||
return permutedMessage.toString();
|
||||
}
|
||||
|
||||
//To decode, we follow the same process as encoding, but with reversed keys
|
||||
// To decode, we follow the same process as encoding, but with reversed keys
|
||||
private String decryptBlock(String message, String keys[]) {
|
||||
String reversedKeys[] = new String[keys.length];
|
||||
for (int i = 0; i < keys.length; i++) {
|
||||
@ -307,7 +242,7 @@ public class DES {
|
||||
message = padLast(message, desiredLength);
|
||||
}
|
||||
|
||||
for (i = 0; i < l; i+= 8) {
|
||||
for (i = 0; i < l; i += 8) {
|
||||
String block = message.substring(i, i + 8);
|
||||
StringBuilder bitBlock = new StringBuilder();
|
||||
byte[] bytes = block.getBytes();
|
||||
@ -327,18 +262,19 @@ public class DES {
|
||||
StringBuilder decryptedMessage = new StringBuilder();
|
||||
int l = message.length(), i, j;
|
||||
if (l % 64 != 0) {
|
||||
throw new IllegalArgumentException("Encrypted message should be a multiple of 64 characters in length");
|
||||
throw new IllegalArgumentException(
|
||||
"Encrypted message should be a multiple of 64 characters in length");
|
||||
}
|
||||
for (i = 0; i < l; i+= 64) {
|
||||
for (i = 0; i < l; i += 64) {
|
||||
String block = message.substring(i, i + 64);
|
||||
String result = decryptBlock(block.toString(), subKeys);
|
||||
byte res[] = new byte[8];
|
||||
for (j = 0; j < 64; j+=8) {
|
||||
res[j / 8] = (byte)Integer.parseInt(result.substring(j, j + 8), 2);
|
||||
for (j = 0; j < 64; j += 8) {
|
||||
res[j / 8] = (byte) Integer.parseInt(result.substring(j, j + 8), 2);
|
||||
}
|
||||
decryptedMessage.append(new String(res));
|
||||
}
|
||||
return decryptedMessage.toString().replace("\0", ""); // Get rid of the null bytes used for padding
|
||||
return decryptedMessage.toString().replace(
|
||||
"\0", ""); // Get rid of the null bytes used for padding
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,10 +4,11 @@ import java.util.Scanner;
|
||||
|
||||
/*
|
||||
* Java Implementation of Hill Cipher
|
||||
* Hill cipher is a polyalphabetic substitution cipher. Each letter is represented by a number belonging to the set Z26 where A=0 , B=1, ..... Z=25.
|
||||
* To encrypt a message, each block of n letters (since matrix size is n x n) is multiplied by an invertible n × n matrix, against modulus 26.
|
||||
* To decrypt the message, each block is multiplied by the inverse of the matrix used for encryption.
|
||||
* The cipher key and plaintext/ciphertext are user inputs.
|
||||
* Hill cipher is a polyalphabetic substitution cipher. Each letter is represented by a number
|
||||
* belonging to the set Z26 where A=0 , B=1, ..... Z=25. To encrypt a message, each block of n
|
||||
* letters (since matrix size is n x n) is multiplied by an invertible n × n matrix, against
|
||||
* modulus 26. To decrypt the message, each block is multiplied by the inverse of the matrix used
|
||||
* for encryption. The cipher key and plaintext/ciphertext are user inputs.
|
||||
* @author Ojasva Jain
|
||||
*/
|
||||
public class HillCipher {
|
||||
@ -28,7 +29,7 @@ public class HillCipher {
|
||||
keyMatrix[i][j] = userInput.nextInt();
|
||||
}
|
||||
}
|
||||
//check if det = 0
|
||||
// check if det = 0
|
||||
validateDeterminant(keyMatrix, matrixSize);
|
||||
|
||||
int[][] messageVector = new int[matrixSize][1];
|
||||
@ -62,7 +63,7 @@ public class HillCipher {
|
||||
System.out.println("Ciphertext: " + CipherText);
|
||||
}
|
||||
|
||||
//Following function decrypts a message
|
||||
// Following function decrypts a message
|
||||
static void decrypt(String message) {
|
||||
message = message.toUpperCase();
|
||||
// Get key matrix
|
||||
@ -75,10 +76,10 @@ public class HillCipher {
|
||||
keyMatrix[i][j] = userInput.nextInt();
|
||||
}
|
||||
}
|
||||
//check if det = 0
|
||||
// check if det = 0
|
||||
validateDeterminant(keyMatrix, n);
|
||||
|
||||
//solving for the required plaintext message
|
||||
// solving for the required plaintext message
|
||||
int[][] messageVector = new int[n][1];
|
||||
String PlainText = "";
|
||||
int[][] plainMatrix = new int[n][1];
|
||||
@ -157,9 +158,7 @@ public class HillCipher {
|
||||
|
||||
static void validateDeterminant(int[][] keyMatrix, int n) {
|
||||
if (determinant(keyMatrix, n) % 26 == 0) {
|
||||
System.out.println(
|
||||
"Invalid key, as determinant = 0. Program Terminated"
|
||||
);
|
||||
System.out.println("Invalid key, as determinant = 0. Program Terminated");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,8 @@ package com.thealgorithms.ciphers;
|
||||
* Letters in alphabet takes place to two dimension table.
|
||||
* Encrypted text is created according to row and column in two dimension table
|
||||
* Decrypted text is generated by looking at the row and column respectively
|
||||
* Additionally, some letters in english alphabet deliberately throws such as U because U is very similar with V
|
||||
* Additionally, some letters in english alphabet deliberately throws such as U because U is very
|
||||
* similar with V
|
||||
*
|
||||
* @author Hikmet ÇAKIR
|
||||
* @since 08-07-2022+03:00
|
||||
@ -16,11 +17,11 @@ public class Polybius {
|
||||
|
||||
private static final char[][] key = {
|
||||
// 0 1 2 3 4
|
||||
/* 0 */{ 'A', 'B', 'C', 'D', 'E' },
|
||||
/* 1 */{ 'F', 'G', 'H', 'I', 'J' },
|
||||
/* 2 */{ 'K', 'L', 'M', 'N', 'O' },
|
||||
/* 3 */{ 'P', 'Q', 'R', 'S', 'T' },
|
||||
/* 4 */{ 'V', 'W', 'X', 'Y', 'Z' },
|
||||
/* 0 */ {'A', 'B', 'C', 'D', 'E'},
|
||||
/* 1 */ {'F', 'G', 'H', 'I', 'J'},
|
||||
/* 2 */ {'K', 'L', 'M', 'N', 'O'},
|
||||
/* 3 */ {'P', 'Q', 'R', 'S', 'T'},
|
||||
/* 4 */ {'V', 'W', 'X', 'Y', 'Z'},
|
||||
};
|
||||
|
||||
private static String findLocationByCharacter(final char character) {
|
||||
|
@ -20,8 +20,7 @@ public class RSA {
|
||||
* @return encrypted message
|
||||
*/
|
||||
public synchronized String encrypt(String message) {
|
||||
return (new BigInteger(message.getBytes())).modPow(publicKey, modulus)
|
||||
.toString();
|
||||
return (new BigInteger(message.getBytes())).modPow(publicKey, modulus).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -36,9 +35,7 @@ public class RSA {
|
||||
*/
|
||||
public synchronized String decrypt(String encryptedMessage) {
|
||||
return new String(
|
||||
(new BigInteger(encryptedMessage)).modPow(privateKey, modulus)
|
||||
.toByteArray()
|
||||
);
|
||||
(new BigInteger(encryptedMessage)).modPow(privateKey, modulus).toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -57,8 +54,7 @@ public class RSA {
|
||||
BigInteger q = new BigInteger(bits / 2, 100, r);
|
||||
modulus = p.multiply(q);
|
||||
|
||||
BigInteger m =
|
||||
(p.subtract(BigInteger.ONE)).multiply(q.subtract(BigInteger.ONE));
|
||||
BigInteger m = (p.subtract(BigInteger.ONE)).multiply(q.subtract(BigInteger.ONE));
|
||||
|
||||
publicKey = BigInteger.valueOf(3L);
|
||||
|
||||
|
@ -82,5 +82,4 @@ public class SimpleSubCipher {
|
||||
|
||||
return decoded.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,21 +16,9 @@ public class Vigenere {
|
||||
char c = message.charAt(i);
|
||||
if (Character.isLetter(c)) {
|
||||
if (Character.isUpperCase(c)) {
|
||||
result.append(
|
||||
(char) (
|
||||
(c + key.toUpperCase().charAt(j) - 2 * 'A') %
|
||||
26 +
|
||||
'A'
|
||||
)
|
||||
);
|
||||
result.append((char) ((c + key.toUpperCase().charAt(j) - 2 * 'A') % 26 + 'A'));
|
||||
} else {
|
||||
result.append(
|
||||
(char) (
|
||||
(c + key.toLowerCase().charAt(j) - 2 * 'a') %
|
||||
26 +
|
||||
'a'
|
||||
)
|
||||
);
|
||||
result.append((char) ((c + key.toLowerCase().charAt(j) - 2 * 'a') % 26 + 'a'));
|
||||
}
|
||||
} else {
|
||||
result.append(c);
|
||||
@ -48,17 +36,9 @@ public class Vigenere {
|
||||
char c = message.charAt(i);
|
||||
if (Character.isLetter(c)) {
|
||||
if (Character.isUpperCase(c)) {
|
||||
result.append(
|
||||
(char) (
|
||||
'Z' - (25 - (c - key.toUpperCase().charAt(j))) % 26
|
||||
)
|
||||
);
|
||||
result.append((char) ('Z' - (25 - (c - key.toUpperCase().charAt(j))) % 26));
|
||||
} else {
|
||||
result.append(
|
||||
(char) (
|
||||
'z' - (25 - (c - key.toLowerCase().charAt(j))) % 26
|
||||
)
|
||||
);
|
||||
result.append((char) ('z' - (25 - (c - key.toLowerCase().charAt(j))) % 26));
|
||||
}
|
||||
} else {
|
||||
result.append(c);
|
||||
|
@ -6,7 +6,8 @@ import java.util.BitSet;
|
||||
public class A5Cipher {
|
||||
|
||||
private final A5KeyStreamGenerator keyStreamGenerator;
|
||||
private static final int KEY_STREAM_LENGTH = 228; // 28.5 bytes so we need to pad bytes or something
|
||||
private static final int KEY_STREAM_LENGTH
|
||||
= 228; // 28.5 bytes so we need to pad bytes or something
|
||||
|
||||
public A5Cipher(BitSet sessionKey, BitSet frameCounter) {
|
||||
keyStreamGenerator = new A5KeyStreamGenerator();
|
||||
|
@ -9,7 +9,8 @@ public class A5KeyStreamGenerator extends CompositeLFSR {
|
||||
private BitSet frameCounter;
|
||||
private BitSet sessionKey;
|
||||
private static final int INITIAL_CLOCKING_CYCLES = 100;
|
||||
private static final int KEY_STREAM_LENGTH = 228; // 28.5 bytes so we need to pad bytes or something
|
||||
private static final int KEY_STREAM_LENGTH
|
||||
= 228; // 28.5 bytes so we need to pad bytes or something
|
||||
|
||||
@Override
|
||||
public void initialize(BitSet sessionKey, BitSet frameCounter) {
|
||||
@ -17,9 +18,9 @@ public class A5KeyStreamGenerator extends CompositeLFSR {
|
||||
this.frameCounter = (BitSet) frameCounter.clone();
|
||||
this.initialFrameCounter = (BitSet) frameCounter.clone();
|
||||
registers.clear();
|
||||
LFSR lfsr1 = new LFSR(19, 8, new int[] { 13, 16, 17, 18 });
|
||||
LFSR lfsr2 = new LFSR(22, 10, new int[] { 20, 21 });
|
||||
LFSR lfsr3 = new LFSR(23, 10, new int[] { 7, 20, 21, 22 });
|
||||
LFSR lfsr1 = new LFSR(19, 8, new int[] {13, 16, 17, 18});
|
||||
LFSR lfsr2 = new LFSR(22, 10, new int[] {20, 21});
|
||||
LFSR lfsr3 = new LFSR(23, 10, new int[] {7, 20, 21, 22});
|
||||
registers.add(lfsr1);
|
||||
registers.add(lfsr2);
|
||||
registers.add(lfsr3);
|
||||
@ -31,11 +32,7 @@ public class A5KeyStreamGenerator extends CompositeLFSR {
|
||||
}
|
||||
|
||||
public BitSet getNextKeyStream() {
|
||||
for (
|
||||
int cycle = 1;
|
||||
cycle <= INITIAL_CLOCKING_CYCLES;
|
||||
++cycle
|
||||
) this.clock();
|
||||
for (int cycle = 1; cycle <= INITIAL_CLOCKING_CYCLES; ++cycle) this.clock();
|
||||
|
||||
BitSet result = new BitSet(KEY_STREAM_LENGTH);
|
||||
for (int cycle = 1; cycle <= KEY_STREAM_LENGTH; ++cycle) {
|
||||
|
@ -29,12 +29,8 @@ public abstract class CompositeLFSR implements BaseLFSR {
|
||||
bitCount.put(false, 0);
|
||||
bitCount.put(true, 0);
|
||||
|
||||
registers.forEach(lfsr ->
|
||||
bitCount.put(
|
||||
lfsr.getClockBit(),
|
||||
bitCount.get(lfsr.getClockBit()) + 1
|
||||
)
|
||||
);
|
||||
registers.forEach(
|
||||
lfsr -> bitCount.put(lfsr.getClockBit(), bitCount.get(lfsr.getClockBit()) + 1));
|
||||
return bitCount.get(false) <= bitCount.get(true);
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
package com.thealgorithms.ciphers.a5;
|
||||
|
||||
// Source http://www.java2s.com/example/java-utility-method/bitset/increment-bitset-bits-int-size-9fd84.html
|
||||
//package com.java2s;
|
||||
//License from project: Open Source License
|
||||
// Source
|
||||
// http://www.java2s.com/example/java-utility-method/bitset/increment-bitset-bits-int-size-9fd84.html
|
||||
// package com.java2s;
|
||||
// License from project: Open Source License
|
||||
|
||||
import java.util.BitSet;
|
||||
|
||||
@ -11,7 +12,7 @@ public class Utils {
|
||||
public static boolean increment(BitSet bits, int size) {
|
||||
int i = size - 1;
|
||||
while (i >= 0 && bits.get(i)) {
|
||||
bits.set(i--, false);/*from w w w . j a v a 2s .c o m*/
|
||||
bits.set(i--, false); /*from w w w . j a v a 2s .c o m*/
|
||||
}
|
||||
if (i < 0) {
|
||||
return false;
|
||||
|
Reference in New Issue
Block a user