• 欢迎光临~

Java-列移位(Columnar Transposition Cipher)算法实现版本二

• 实现思路如下：

• 对密文按字符顺序进行排序，并记录排序索引值；
• 对密文进行迭代，求出每个密文字符对应的目标偏移量；
• 循环按照密文字符偏移量读取原文字符，将其写到密文字符串中；

``````import java.util.Arrays;
import java.util.Objects;

public class ColumnarTranspositionCipherTest {

private static String mKey = "german";

public static void main(String[] args) {
String inputStr = "defend*the*east*wall*of*the*castle";
String encipher = encipher(inputStr);
String decrypt = decrypt(encipher);
System.out.println("inputStr:" + inputStr);
System.out.println("encipher:" + encipher);
System.out.println("decrypt:" + decrypt);
System.out.println("加解密结果：" + inputStr.equals(decrypt));
}

/**
* 加密
*
* @param inputStr
* @return
*/
public static String encipher(String inputStr) {

if (Objects.isNull(inputStr) || Objects.isNull(mKey)) {
return "";
}

byte[] keyBytes = mKey.getBytes();

int[] keyBytesSorted = getKeyBytesSorted(keyBytes);

final int inputLength = inputStr.getBytes().length;
String output = "";
for (int i = 0; i < keyBytes.length; i++) {
int r = 0;
int arrySortedIndex = getArrySortedIndex(keyBytesSorted, i);

int offset;
while ((offset = r * keyBytes.length + arrySortedIndex) < inputLength) {
output = output + inputStr.charAt(offset);
r++;
}
}

return new String(output);
}

/**
* 对密钥字符进行排序，返回的是密钥字符排序后值
*
* @param keyBytes
* @return
*/
private static int[] getKeyBytesSorted(byte[] keyBytes) {

int[] keyBytesSorted = new int[keyBytes.length];
for (int i = 0; i < keyBytes.length; i++) {

byte min = 0;
int minIndex = -1;
for (int j = 0; j < keyBytes.length; j++) {
if (keyBytes[j] >= 0) {
min = keyBytes[j];
minIndex = j;
break;
}
}

for (int j = 0; j < keyBytes.length; j++) {
if (keyBytes[j] >= 0 && keyBytes[j] < min) {
min = keyBytes[j];
minIndex = j;
}
}

keyBytes[minIndex] = -1;
keyBytesSorted[minIndex] = i;
}
return keyBytesSorted;
}

/**
* 从密钥字符排序数组中，找出排序值对应的下标索引
*
* @param keyBytesSorted
* @param num
* @return
*/
public static int getArrySortedIndex(int[] keyBytesSorted, int num) {
for (int i = 0; i < keyBytesSorted.length; i++) {
if (keyBytesSorted[i] == num)
return i;
}
return -1;
}

/**
* 解密
*
* @param inputStr
* @return
*/
public static String decrypt(String inputStr) {
if (Objects.isNull(inputStr) || Objects.isNull(mKey)) {
return "";
}

byte[] keyBytes = mKey.getBytes();

int[] keyBytesSorted = getKeyBytesSorted(keyBytes);
final int keyBytesLength = keyBytes.length;
int[] decryptIndexArray = new int[keyBytesLength];

for (int i = 0; i < keyBytesLength; i++) {
decryptIndexArray[i] = getArrySortedIndex(keyBytesSorted, i);
}

char[] inputChars = inputStr.toCharArray();
char[] outputChars = new char[inputChars.length];

int inputIndex = 0;
for (int i = 0; i < decryptIndexArray.length; i++) {
int originIndexOffset = decryptIndexArray[i];
int r = 0;

int offset;
while ((offset = r * keyBytesLength + originIndexOffset) < inputChars.length) {
outputChars[offset] = inputChars[inputIndex];
r++;
inputIndex++;
}
}
return new String(outputChars);
}
}
``````