Java-列移位(Columnar Transposition Cipher)算法实现版本二
这是几年前写的旧文,此前发布Wordpress小站上,现在又重新整理。算是温故知新,后续会继续整理。如有错误望及时指出,在此感谢。
这里提供一个另种版本的实现,上一篇的实现中,为了讲明白算法逻辑,写的过于啰嗦。
-
实现思路如下:
-
- 对密文按字符顺序进行排序,并记录排序索引值;
- 对密文进行迭代,求出每个密文字符对应的目标偏移量;
- 循环按照密文字符偏移量读取原文字符,将其写到密文字符串中;
代码如下
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);
}
}
结论
整体思路更简洁,希望对大家有帮助;
浙公网安备 33010602011771号