曲路密码
文章目录
用一个例子来说明加密方式
假设要加密的文本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主的分享是相同的