曲路密码算法

曲路密码

参考一日一加密——曲路密码

文章目录


用一个例子来说明加密方式

假设要加密的文本text=123456789ABCDEFGHI,长度为18

那么可以用一个3*6的矩阵也可以用一个2*9的矩阵恰好填入18个字符

这里选用3*6的矩阵,即3行 × \times ×每行6列的矩阵

首先将text按行填入该矩阵,如图所示

然后从右下角开始,首先向上,到顶左转一个单位,然后立刻转向下方,到底然后左转一个单位,然后立刻向上,如图箭头所示

按照次顺序以此取出矩阵中的元素即得到加密密码

如果做过C语言什么"矩阵螺旋取数",什么"Z字扫描",这里算法设计也是差不多的道理

给定加密密码和矩阵规格,也容易得到原文

只需要按照同样的顺序首先把加密码填入矩阵,然后按照行顺序取出组合在一起

算法是比较容易的

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

string encrypt(const string &text, const int &rows, const int &cols) {//加密算法
	int length = text.length();
	if (length != rows * cols)
		return "wrong matrix";//保证矩阵matrix恰好装下text
	string matrix[rows];
	for (int i = 0; i < rows; ++i) {
		matrix[i] = text.substr(i * cols, cols);
	}
	//矩阵计算完毕,开始曲路取字符
	string encrypted;
	int x = cols - 1;
	int y = rows - 1; //当前x,y坐标位置
	int director = -1;//竖直方向上有向下和向上两种方向,需要一个director变量记录方向
	bool turn_flag = 0;//拐弯标记
	for (int i = 0; i < length; i++) {
		encrypted += matrix[y][x];
		if (y == 0 || y == rows - 1) {//y=0或者y=rows-1时需要拐弯
			if (turn_flag == 0) {
                //考虑拐弯有两种,一种是竖直方向转向水平,一种是水平方向转向数值,需要分类讨论
                //但是两种转向方式是交替出现的,因此用一个只有两个状态的开关trun_flag来记录区别就可以
				turn_flag = 1;//如果本次是水平方向转向竖直方向,那么下一次一定是从竖直方向转向水平方向
				y += director;//此种情况是水平方向转向竖直方向,需要在竖直方向上向director方向迈出一步
			} else {
				turn_flag = 0;
				--x;//此种情况是竖直方向转水平方向,需要水平向左迈出一步
			}
			if (y == 0 )
				director = 1;//如果y处在最高处,那么以后的竖直方向一定是下降的
			else if (y == rows - 1)
				director = -1;//如果y处在最低处,那么以后的竖直方向一定是上升的
		} else
			y += director;//此处else判断的是在竖直半路上位置,不需要考虑x的变化,只需要无脑听从director的指示
	}
	return encrypted;
}

string decrypt(const string &encrypted, const int &rows, const int &cols) {
	int length = encrypted.length();
	if (length != rows * cols)
		return "wrong matrix";
	string matrix[rows];
	for (int i = 0; i < rows; i++) {
		matrix[i].resize(cols);
	}
	int x = cols - 1;
	int y = rows - 1; //当前x,y坐标位置
	int director = -1;
	int turn_flag = 0;//拐弯标记
	for (int i = 0; i < length; i++) {
		matrix[y][x] = encrypted[i];
		if (y == 0 || y == rows - 1) {//y=0或者y=rows-1时需要拐弯
			if (turn_flag == 0) {
				turn_flag = 1;
				y += director;
			} else {
				turn_flag = 0;
				--x;
			}
			if (y == 0 )
				director = 1;
			else if (y == rows - 1)
				director = -1;
		} else
			y += director;
	}
	string text;
	for (int i = 0; i < rows; i++) {
		text += matrix[i];
	}
	return text;
}

int main() {
	string text = "WelcometotheDedSec";
	string encrypted = encrypt(text, 3, 6);
	string decrypted = decrypt(encrypted, 3, 6);
	cout << encrypted << endl;
	cout << decrypted << endl;
	return 0;
}

运行结果:

cemoheStclodeteWeD
WelcometotheDedSec

这与B站这位up主的分享是相同的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

灰球球

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值