解密和加密算法时髦

Decryption and encryption algoritms funky

我为基于凯撒密码和转录密码的自定义加密和解密算法制作了一个小脚本。

首先介绍一下它应该如何工作的背景知识。假设您要在发送前加密一条消息。您将凯撒密码应用于它,即将字母表中的每个字母向右移动 3 个位置。然后你把加密的文本按照你的密钥的字母数分成几个部分。假设您的消息有 n 个字母,而您的密钥有 m 个字母。那么您的消息应该被分解为 n/m 个部分(四舍五入或上限),每个部分 m 个字母。如果消息长度不能被密钥中的字母数整除,则必须按字母 A 填充以填充缺失的字母。然后由键给出,您根据与字母表中的列号相对应的特定键字母的位置转置列。因此,如果您的键是 LEAK,则必须根据以下位置转置列:3241,因为 1234 对应于 AEKL(按字母顺序排序).然后将这个转置矩阵连接回相应的字符串,然后可以将其发送。解密基本上是顺序颠倒的相同过程→您收到一条消息,并且您知道密钥。您将它分成列,然后转置列以对应于键中字母的字母顺序,将其连接回去,然后通过反向凯撒密码 运行 (将字母在字母表中向左移动 3 个位置) .你可能会在最后得到几个 X 字母,这实际上并不重要。

现在谈谈我的问题:我为它写了一个 Javascript 小程序,它实际上是一个模块,我还有一个测试脚本来查看它是如何工作的。但它不能正常工作。换位错误,导致破译文本格式错误。我知道解密的文本,因为我在编写该脚本之前手动完成了这个算法,我知道它应该有的结果。

这是模块:

module.exports = {
    decrypt: (message, key) => {
        if(message.length % key.length != 0) {
            throw new Error(`Lenght of message is not divisible by lenght of the key! ${message.length} is not divisible by ${key.length}!`);
        }
        
        let key_array_unsorted = key.split('');
        let key_array_sorted = key.split('').sort();

        let message_matrix = [];
        for(i = 0; i < message.length / key.length; ++i) {
            let quartet = [];

            for(j = 0; j < key.length; ++j) {
                quartet.push(message.charAt(i*key.length + j));
            }

            message_matrix.push(quartet);
        }

        let message_matrix_shuffled = [];
        message_matrix.forEach(quartet => {
            let quartet_shuffled = [];

            for(i = 0; i < key.length; ++i) {
                for(j = 0; j < key.length; ++j) {
                    if(key_array_unsorted[i] == key_array_sorted[j]) {
                        quartet_shuffled.push(quartet[j]);
                    }
                }
            }

            message_matrix_shuffled.push(quartet_shuffled);
        });

        let message_quartets = [];
        message_matrix_shuffled.forEach(quartet => {message_quartets.push(quartet.join(''))});

        let message_caesar = message_quartets.join('');

        let message_deciphered = "";
        for(i = 0; i < message_caesar.length; ++i) {
            let charcode = message_caesar.charCodeAt(i);
            let alphanum = charcode - 65;

            let alphanum_new = (alphanum + 23) % 26;
            let charcode_new = alphanum_new + 65;

            message_deciphered += String.fromCharCode(charcode_new);
        }

        return message_deciphered;
    },

    encrypt: (message, key) => {
        let message_caesar = "";

        for(i = 0; i < message.length; ++i) {
            let charcode = message.charCodeAt(i);
            let alphanum = charcode - 65;

            let alphanum_new = (alphanum + 3) % 26;
            let charcode_new = alphanum_new + 65;

            message_caesar += String.fromCharCode(charcode_new);
        }

        for(i = 0; i <= Math.ceil(message_caesar.length / key.length) * key.length - message_caesar.length; ++i) {
            message_caesar += "A";
        }

        let key_array_unsorted = key.split('');
        let key_array_sorted = key.split('').sort();

        let message_matrix = [];
        for(i = 0; i < message_caesar.length / key.length; ++i) {
            let quartet = [];

            for(j = 0; j < key.length; ++j) {
                quartet.push(message_caesar.charAt(i*key.length + j));
            }

            message_matrix.push(quartet);
        }

        let message_matrix_shuffled = [];
        message_matrix.forEach(quartet => {
            let quartet_shuffled = [];

            for(i = 0; i < key.length; ++i) {
                for(j = 0; j < key.length; ++j) {
                    if(key_array_sorted[i] == key_array_unsorted[j]) {
                        quartet_shuffled.push(quartet[j]);
                    }
                }
            }

            message_matrix_shuffled.push(quartet_shuffled);
        });

        let message_quartets = [];
        message_matrix_shuffled.forEach(quartet => {message_quartets.push(quartet.join(''))});

        let message_ciphered = message_quartets.join('');
        return message_ciphered;
    }
}

这是测试脚本:

const cipher = require('./cipher');

let message = "HGYRDGQCREGLDYQROXRHABAK";
let key = "OMYL";

console.log(`Received message: ${message}`);
console.log(`Known passphrase: ${key}`);

let message_deciphered = cipher.decrypt(message, key);
console.log(`Deciphered message: ${message_deciphered}`);

let message_encrypted = cipher.encrypt(message_deciphered, key);
console.log(`Control encryption: ${message_encrypted}`);

模块和测试脚本在同一个文件夹中。

输出应该是这样的:

Received message: HGYRDGQCREGLDYQROXRHABAK
Known passphrase: OMYL
Deciphered message: ODEVZDANIBODOVANEULOHYXX
Control encryption: HGYRDGQCREGLDYQROXRHABAK

这是当前输出:

Received message: HGYRDGQCREGLDYQROXRHABAK
Known passphrase: OMYL
Deciphered message: VDOENDZADBIONVOAOUELXYHX
Control encryption: HGYRDGQCREGLDYQROXRHABAK

现在,我确定密钥的字母排序正确,这不是转录错误的原因,我实际上查找了正确排序的密钥字母,没关系。 OMYL 实际上确实正确排序为 LMOY

问题必须出在转录本身,它与密钥的字母顺序不符。问题是,由于某种原因我无法发现错误,如果有的话。我想 Javascript 并不是用于此类事情的好语言,但它相当简单并且不需要编译。我想做的就是让自己成为一个小工具或工具,以便为我的作业快速求解,我在星期一收到作业,我已经知道该作业的主题,即密码。

也许我做错了,也许我实际上不应该使用要比较的关键字母,而是根据关键字母的字母顺序(当然还有步骤顺序 - 加密或解密)。不幸的是,我不知道该怎么做:(

根据聊天中OP给出的算法,码字排序错误

比较排序序列和未排序序列而不是相反

key_array_unsorted[i] == key_array_sorted[j]替换为key_array_sorted[i] == key_array_unsorted[j]