列置换密码
置换密码(Permutation Cipher)
又叫
换位密码(Transposition Cipher)
,其特点就是保持明文的所有字符不变,打乱明文字符的位置和次序。常见的置换密码有两种:
列置换密码
和
周期置换密码
。
列置换
的加密过程:
1.将明文M以设定的固定分组宽度m按
行
写出,即每行有m个字符。若明文不是m的整数倍,用双方提前规定好的方式补充,如空格,得到矩阵
。
2.按1,2,3 ...m的某一置换交换列的位置次序得到新的字符矩阵。
3.按
列
的顺序依次读出得密文序列C。
解密过程:
1.将密文C按加密过程的分组宽度m按
列
写出字符矩阵。
2.按加密过程的置换的逆置换的位置次序得到新的字符矩阵。
3.按
行
的顺序依次读出得明文序列M。
2、流程图
3、编程实现
难点:
如何根据密钥实现列置换和逆置换。
因为主要是学习算法思想,程序用户输入明文分组的固定长度,再输入列置换,得到密文。之后通过求出列置换的逆置换,解密得到明文。
具体代码如下:
#include"ColPermutation.h"
int main() {
while (1) {
show(); //菜单界面
keyDown(); //按键处理
system("pause");
system("cls");
头文件ColPermutation.h
#pragma once
#include<cstdio>
#include<iostream>
#include<cstring>
#include<Windows.h>
#include<vector>
using namespace std;
void init();
void show();
void keyDown();
void readFile();
void saveFile();
void encrypt();
void decrypt();
ColPermutation.cpp
#include "ColPermutation.h"
string fileStr = "";
string finalStr = "";
void init()//初始化
fileStr = "";
finalStr = "";
void show()
cout << "***************列置换密码***************" << endl;
cout << "\t\t1.加密文件" << endl;
cout << "\t\t2.解密文件" << endl;
cout << "\t\t3.退出" << endl;
cout << "******************************************" << endl;
void keyDown()//按键处理
int userkey = 0;
cin >> userkey;
switch (userkey) {
case 1:
cout << "-----------------加密文件-----------------" << endl;
readFile();
encrypt();
saveFile();
init();
break;
case 2:
cout << "-----------------解密文件-----------------" << endl;
readFile();
decrypt();
saveFile();
init();
break;
case 3:
exit(0);
break;
void readFile()//读取文件
cout << "请输入文件名:" << endl;
string fileName;
cin >> fileName;
FILE* fp = fopen(fileName.c_str(), "r+");
if (fp == nullptr) {
cout << "未找到相关文件" << endl;
return;
else {
cout << "成功打开文件" << endl;
char ch;
int pos = 0;
while ((ch = fgetc(fp)) != EOF) {
fileStr += ch;
cout << endl << "待处理的文件为:" << endl;
cout << fileStr << endl;
fclose(fp);
void saveFile()//保存文件
string fileName;
cout << endl << "请输入要保存信息的文件名:" << endl;
cin >> fileName;
FILE* fp = fopen(fileName.c_str(), "w+");
if (fp == nullptr) {
cout << endl << "保存文件失败" << endl;
return;
else {
cout << endl << "保存成功" << endl;
fprintf(fp, "%s", finalStr.c_str());
fclose(fp);
void encrypt()//加密文件
cout << endl << "请输入密钥:(固定长度和列置换)" << endl;
cout << "请输入固定长度:" << endl;
int length = 0;
cin >> length;
int col = fileStr.size() / length + (fileStr.size() % length != 0);//每列的长度
cout << "明文矩阵为:" << endl;
for (int i = 0; i < fileStr.size(); i++) {
if (i != 0 && i % length == 0)cout << endl;
cout << fileStr[i] << " ";//明文矩阵
cout << endl;
vector<string> c;//存放明文的数组
int pos = 0;
for (int i = 0; i < length; i++) {
int pos = i;
string temp = "";
while (pos < fileStr.size()) {
temp += fileStr[pos];
pos += 6;
if (temp.size() != col)temp += ' ';
c.push_back(temp);//按列存入数组中
int* key = new int[length + 1]();//存放列置换 key[目标列]=源列
while (1) {
cout << "请输入一组列置换:" << endl;
string temp = "";
cin >> temp;//列置换字符串// 143或者56
//求key
//(1 4 3)(5 6)
//key[1]=4 key[2]=2 key[3]=1 key[4]=3 key[5]=6 key[6]=5
for (int i = 0; i < temp.size(); i++) {
if (i == temp.size() - 1) {
key[temp[i] - '0'] = temp[0] - '0';
else key[temp[i] - '0'] = temp[i + 1] - '0';
//继续输出还是退出
char ch = '\0';
cout << "是否继续输入列置换(y/n)?" << endl;
cin >> ch; if (ch == 'n')break;
for (int i = 1; i <= length; i++) {
if (key[i] == 0) {
key[i] = i;//不移动的列序号
//cout << i << " " << key[i] << endl;
cout << endl << "按下任意键进行加密" << endl;
char ch = getchar(); ch = getchar();
for (int i = 1; i <= length; i++) {
finalStr += c[key[i] - 1];
cout << "密文矩阵为:" << endl;
for (int i = 0; i < col; i++) {
for (int j = 1; j <= length; j++) {
cout << c[key[j] - 1][i] << " ";
cout << endl;
cout << endl << "得到的密文为:" << endl;
cout << finalStr << endl;
void decrypt()//解密文件
cout << endl << "请输入密钥:(固定长度和列置换)" << endl;
cout << "请输入固定长度:" << endl;
int length = 0;
cin >> length;
int col = fileStr.size() / length + (fileStr.size() % length != 0);//每列的长度
cout << "密文矩阵为:" << endl;
for (int i = 0; i < col; i++) {
int pos = i;
for (int j = i; j < fileStr.size(); j += col) {
cout << fileStr[j] << " ";
cout << endl;
vector<string> antic;//存放密文的数组
for (int i = 0; i < fileStr.size();) {
antic.push_back(string(fileStr.begin() + i, fileStr.begin() + i + col));
i += col;
int* antikey = new int[length + 1]();//存放列置换 key[目标列]=源列
while (1) {
cout << "请输入一组列置换(不是列置换的逆置换):" << endl;
string temp = "";
cin >> temp;//列置换字符串// 143和56
//(1 4 3)(5 6)
for (int i = 0; i < temp.size(); i++) {
if (i == 0) {
antikey[temp[i] - '0'] = temp[temp.size() - 1] - '0';
else antikey[temp[i] - '0'] = temp[i - 1] - '0';
//继续输出还是退出
char ch = '\0';
cout << "是否继续输入列置换(y/n)?" << endl;
cin >> ch; if (ch == 'n')break;
cout << "列置换的逆置换为:" << endl;
for (int i = 1; i <= length; i++) {
if (antikey[i] == 0) {
antikey[i] = i;
//cout << i << " " << antikey[i] << endl;
cout << "成功得到列置换的逆置换!" << endl;
cout << endl << "按下任意键进行解密" << endl;
char ch = getchar(); ch = getchar();
cout << "明文矩阵为:" << endl;
for (int i = 0; i < col; i++) {
for (int j = 1; j <= length; j++) {
cout << antic[antikey[j] - 1][i] << " ";
finalStr += antic[antikey[j] - 1][i];//按行输出的明文
cout << endl;
cout << endl << "得到的明文为:" << endl;
cout << finalStr << endl;
列置换密码的有很多不同的细节实现,但主要算法思想是一样的,同样和之前一样学习算法思想是最主要的,编程实现可以帮助我们更好的学习和理解。
置换密码/huanweim
置换密码(Permutation Cipher)又叫换位密码(Transposi-tionCipher),它根据一定的规则重新排列明文,以便打破明文的结构特性。置换密码的特点是保持明文的所有字符不变,只是利用置换打乱了明文字符的位置和次序。
最常见的置换密码有二种:
列置换密码(明文遵照密钥的规程按列换位并且按列读出序列得到密文);周期置换密码(将明文P按固定长度m分组,然后对每组按1,2…,m的某个置换重排位置从而得到密文C)。
置换密码(Permutation Cipher)又叫换位密码(Transposition Cipher),其特点就是保持明文的所有字符不变,打乱明文字符的位置和次序。常见的置换密码有两种:列置换密码和周期置换密码。
一、列置换加密
将明文字符P以固定的分组宽度m按行写出,构成m x n的矩阵[M]mxn,不够的按双方约定的字符补充,比如空格字符。然...
加密过程
将明文p以设定的固定分组宽度m按行写出,即每行有m个字符;若明文长度不是m的整数倍,则不足部分用双方约定的方式填充,如双方约定用空格代替空缺处字符,不妨设最后得字符矩阵[Mp]n×m
按1,2…,m的某一置换σ交换列的位置次序得字符矩阵[Mp]n×m
把矩阵按[Mp]n×m列的顺序依次读出得密文序列c。
1.要求使用4行*4列的双重置换密码,使用行置换:(1,2,3,4)→(2,4,1,3)和列置换:(1,2,3,4)→(3,1,2,4) 编写置换密码算法的实现程序,实现加密和解密操作。它将明文中的字母按照给定的顺序安排在一个矩阵中,然后用根据密钥提供的顺序重新组合矩阵中的字母,从而形成密文。其解密过程是根据密钥的字母数作为列数,将密文按照列、行的顺序写出,再根据由密钥给出的矩阵置换产生新的矩阵,从而恢复明文。置换密码通过改变明文消息各元素的相对位置,但明文消息元素本身的取值或内容形式不变;
重新排列明文字母,达到信息加密的目的。与替代密码不同的是,原来明文中的字母同样出现在密文中,只是顺序被打断。古典的置换密码的例子:Rail Fence密码、行置换密码、乘积密码、转子机、隐写术。