• 欢迎光临~

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

开发技术 开发技术 2022-06-09 次浏览

这是几年前写的旧文,此前发布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);
    }
}

结论

整体思路更简洁,希望对大家有帮助;

程序员灯塔
转载请注明原文链接:Java-列移位(Columnar Transposition Cipher)算法实现版本二
喜欢 (0)