javascript - 时髦的解密和加密算法

标签 javascript caesar-cipher transcription

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

首先有一些背景知识来解释它应该如何工作。假设您要在发送前加密一条消息。您对其应用凯撒密码,即将字母表中的每个字母向右移动 3 个位置。然后,您获取该加密文本,并根据 key 所包含的字母数量将其划分为多个部分。假设您的消息有 n 个字母,而您的 key 有 m 个字母。然后,您的消息应分为 n/m 个部分(向上舍入或向上取整),每个部分由 m 个字母组成。如果消息长度不能被 key 中的字母数整除,则必须对其进行填充,以按字母 A 填充缺失的字母。然后根据键给出,您可以根据与字母表中的列号相对应的特定键字母的位置来转置列。因此,如果您的 key 是 LEAK,则必须根据位置转置列,如下所示:3241,因为 1234 对应于 AEKL(按字母顺序排序)。然后,将该转置矩阵连接回相应的字符串,然后可以发送该字符串。解密基本上是按顺序颠倒的相同过程→您收到一条消息,并且您知道 key 。您将其分成列,然后转置列,以便与 key 中字母的字母顺序相对应,将其连接回来,然后运行反向凯撒密码(将字母表中的字母向左移动 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

现在,我确信 key 的字母已正确排序,这不是转录错误的原因,我实际上查找了 key 的字母已正确排序,并且没问题。 OMYL 实际上确实正确排序为 LMOY

问题必须出在转录本身,它与 key 的字母顺序不对应。问题是,由于某种原因我无法发现错误(如果有的话)。我想 Javascript 并不是真正适合做这样的事情的语言,但它相当简单并且不需要编译。我想做的就是让自己成为一个小工具或工具,为我的作业制作快速求解器,我在周一收到作业,并且我已经知道该作业的主题,即密码。

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

最佳答案

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

将已排序序列与未排序序列进行比较,而不是相反

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

关于javascript - 时髦的解密和加密算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65129102/

相关文章:

java - 如何从speechMatics中获取转录文本

javascript - 为什么 document.getElementById 在这里返回 null?

JavaScript 函数导致循环结束?

CS50 Pset2-凯撒密码

audio - 自动转录软件

google-cloud-platform - Google Speech API 单句

javascript - 验证字段中的 jQuery bool 值问题

XML 文档中带有命名空间的 Javascript XPath

c - 在 C Caesar Cipher 中使用 ASCII 解密具有未知 key 的打开的文本文件

python - 脚本加密,但仍然保存明文而不是密文