package sun.netsecurity.matrixtran;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigInteger;
public class MatrixTransposition {
static {
}
/**
* @param args
* @throws IOException
*/
char[] plaintext = inputPlaintext();
br.close();
String ciphertext
= encrypt
(plaintext, key
);
System.
out.
println("明文加密后为: " + ciphertext
);
String plaintextStr
= decrypt
(ciphertext.
toCharArray(), plaintext, key
);
System.
out.
println("密文解密后为: " + plaintextStr
);
}
/**
* 将明文字符数组分组
*
* @param plaintext
* 明文字符数组
* @param key
* 密钥
* @return
*/
static char[][] groupPlaintext
(char[] plaintext,
Integer key
) {
char[][] plaintextGroup = null;
if (length % key != 0) {// 当字符数组的长度不是密钥的整数倍时,用字符'$'填补
int fillNumber = keyBI.intValue() - mod.intValue();
for (int i = 0; i < fillNumber; i++) {
plaintextStr = plaintextStr + "$";
}
plaintext = plaintextStr.toCharArray();
length = plaintext.length;
}
int groupAmount = length / key;
plaintextGroup = new char[groupAmount][key];
for (int i = 0; i < groupAmount; i++) {
for (int j = 0; j < key; j++) {
// 将明文字符数组分割为二维数组
plaintextGroup[i][j] = plaintext[i * key + j];
}
}
return plaintextGroup;
}
/**
* 将密文分组
*
* @param ciphertext
* 密文
* @param key
* 密钥
* @return
*/
static char[][] groupCiphertext
(char[] ciphertext,
Integer key
) {
char[][] ciphertextGroup = null;
int length = ciphertext.length;
int groupAmount = length / key;
ciphertextGroup = new char[groupAmount][key];
for (int i = 0; i < groupAmount; i++) {
for (int j = 0; j < key; j++) {
ciphertextGroup[i][j] = ciphertext[i * key + j];
}
}
return ciphertextGroup;
}
/**
* 按照加密规则,将分割后的各个子字符数组分别进行移位
*
* @param group
* 每一个子字符数组
* @return
*/
static char[] changePlaintext(char[] group) {
char[] newGroup = new char[group.length];
for (int i = 0; i < group.length; i++) {
if (i == 0) {
newGroup[0] = group[group.length - 1];
continue;
}
newGroup[i] = group[i - 1];
}
return newGroup;
}
/**
*
* @param group
* 按照加密规则,将密文分割后的各个子字符数组按照相反的方式分别进行移位
* @return
*/
static char[] changeCiphertext(char[] group) {
char[] newGroup = new char[group.length];
for (int i = 0; i < group.length; i++) {
if (i == group.length - 1) {
newGroup[group.length - 1] = group[0];
break;
}
newGroup[i] = group[i + 1];
}
return newGroup;
}
static String getCipherFromGroup
(char[][] plaintextGroup
) {
int rowAccount = plaintextGroup.length;
int lowAccount = plaintextGroup[0].length;
for (int i = 0; i < rowAccount; i++) {
char[] rowChar = new char[lowAccount];
for (int j = 0; j < lowAccount; j++) {
rowChar[j] = plaintextGroup[i][j];
}
ciphertext
= ciphertext
+ new String(rowChar
);
}
return ciphertext;
}
static String getPlaintextFromGroup
(char[][] ciphertextGroup
) {
int rowAccount = ciphertextGroup.length;
int lowAccount = ciphertextGroup[0].length;
for (int i = 0; i < rowAccount; i++) {
char[] rowChar = new char[lowAccount];
for (int j = 0; j < lowAccount; j++) {
rowChar[j] = ciphertextGroup[i][j];
}
plaintext
= plaintext
+ new String(rowChar
);
}
return plaintext;
}
// 从键盘输入明文
static char[] inputPlaintext() {
char[] plaintextChar = null;
try {
plaintext = br.readLine();
plaintextChar = plaintext.toCharArray();
e.printStackTrace();
}
return plaintextChar;
}
// 从键盘获得密钥
try {
keyString = br.readLine();
e.printStackTrace();
}
return key;
}
/**
* 对明文进行加密
*
* @param plaintext
* 明文
* @param key
* 密钥
* @return
*/
char[][] plaintextGroup;
// 调用groupPlaintext(plaintext, key)方法对明文分组
plaintextGroup = groupPlaintext(plaintext, key);
for (int i = 0; i < plaintextGroup.length; i++) {
// 调用changePlaintext(char[])进行位变换
char[] rowText = changePlaintext(plaintextGroup[i]);
plaintextGroup[i] = rowText;
}
//
ciphertext = getCipherFromGroup(plaintextGroup);
return ciphertext;
}
/**
* 对密文进行解密
* @param ciphertext 密文
* @param plaintext 明文
* @param key 密钥
* @return
*/
static String decrypt
(char[] ciphertext,
char[] plaintext,
Integer key
) {
char[][] ciphertextGroup;
ciphertextGroup = groupCiphertext(ciphertext, key);
for (int i = 0; i < ciphertextGroup.length; i++) {
char[] rowText = changeCiphertext(ciphertextGroup[i]);
ciphertextGroup[i] = rowText;
}
plaintextStr = getPlaintextFromGroup(ciphertextGroup);
Integer plaintextLength
= plaintext.
length;
if (mod.intValue() != 0) {
plaintextStr = plaintextStr.substring(0, plaintextStr.length()
- (key - mod.intValue()));
}
return plaintextStr;
}
}
//java/5901