0x01 置换密码概要
置换密码(Permutation Cipher)又称为换位密码,总的来说就是明文的字符保持不变,但是对位置进行改变
0x02 周期置换密码
将明文P按固定长度m进行分组,然后对分组后的每个子串按某种顺序重新排序,最后组合成密文
例如我们有一个明文:
The reign of House Of Cards may be short lived
密码:21635
意思为:
第一个放到第二个
第六个放到第一个
第三个放到第六个
第五个放到第三个
第二个放到第五个
加密后为
0x03 C语言实现
这次写的比较繁琐,目的是为了更好的展示思路,
//
// Created by lmn on 2022/3/2.
//
#include <stdio.h>
#define LEN 50
// 简单置换密码
void Init(void* arr[LEN])
{
int i = 0;
for (i = 0; i < LEN; i++) {
arr[i] = 0;
}
}
decode()
{
char plaintext[LEN];
int key = 0;
int change[2][LEN];
int realKey[LEN];
int realKey2[LEN];
int i,j=0;
// 输入明文
printf("Please input plaintext:>");
fgets(plaintext, LEN-1, stdin);
// 去除空格
// 拆分输入字符
// The reign of House Of Cards may be short lived
// ThereignofHouseOfCardsmaybeshortlived
char *str_c=plaintext;
int num = 0;
for(i=0;plaintext[i]!='\0';i++)
{
if(plaintext[i]!=' ')
{
str_c[j++]=plaintext[i];
num++;
}
}
str_c[j]='\0';
printf("去除空格后的字符串:> %s\n", str_c);
num-=1;
printf("去除空格后一共有 %d 个字符\n",num);
// 输入key
printf("Please input key (eg.21635):>");
scanf("%d",&key);
// 找key中最大的一个
int key2 = key; // 保留副本
int tmp = 0;// 最大值,也就是分组数
int m = 0;
while(key2)
{
if((key2 % 10) > tmp)
{
tmp = key2 % 10;
realKey[m] = key2 % 10; // 倒序
key2 /= 10;
m++;
}
else
{
realKey[m] = key2 % 10; // 倒序
key2 /= 10;
m++;
}
}
for (i = 0; i < m; i++) {
realKey2[i] = realKey[m-i-1];
}
printf("realKey2 = %d,%d\n",realKey2[0],realKey2[1]);
// 生成明文加密的矩阵
int t = m;
for (i = 0; i < tmp; i++) { // m: realKey的数量
change[0][i] = i+1; //[0] --> [1,2,3,4,5...realKey]
for (j = m-1; j >= 0; j--) { // m: realKey的数量
if (realKey[j] == i+1) {
change[1][i] = realKey[t-1]; // 输入21635 得到 216035
t--;
break;
} else
change[1][i] = i+1;
}
}
// 输出加密矩阵
printf("输出加密矩阵的运算过程:>\n");
for (i = 0; i < 2; i++) {
for (j = 0; j < tmp; j++) {
printf("%d",change[i][j]);
}
printf("\n");
}
// 拆分输入字符(按照tmp)
// ThereignofHouseOfCardsmaybeshortlived
// 输出 Therei gnofHo useOfC ardsma ybesho rtlive d
int col = 0; // 分组数
if(num % tmp != 0)
col = num/tmp+1;
else
col = num/tmp;
char textGroup[col][tmp];
char endTextGroup[col][tmp];
// 初始化
for (i = 0; i < col; i++) {
for (j = 0; j < tmp; j++) {
textGroup[i][j] = ' ';
endTextGroup[i][j] = ' ';
}
}
int all = 0;
printf("col = %d",col);
// 列置换密码
for (i = 0; i < col; i++) {
for (j = 0; j < tmp; j++) {
if(all != num)
{
textGroup[i][j] = plaintext[all];
endTextGroup[i][j] = plaintext[all];
all++;
}
else
endTextGroup[i][j] = '\0';
}
}
printf("\n输出明文矩阵的运算过程:>\n");
for (i = 0; i < col; i++) {
for (j = 0; j < tmp; j++) {
printf("%c",textGroup[i][j]);
}
printf("\n");
}
// 列置换密码进行置换
for (i = 0; i < col; i++) {
char q = textGroup[i][realKey2[0]-1];
for (j = 0; j < m-1; j++) {
endTextGroup[i][realKey2[j]-1] = textGroup[i][realKey2[j+1]-1];
}
endTextGroup[i][realKey2[m-1]-1] = q;
}
printf("\n输出密文矩阵的运算过程:>\n");
for (i = 0; i < col; i++) {
for (j = 0; j < tmp; j++) {
printf("%c",endTextGroup[i][j]);
}
printf("\n");
}
printf("\n输出密文:>\n");
for (i = 0; i < col; i++) {
for (j = 0; j < tmp; j++) {
printf("%c",endTextGroup[i][j]);
}
}
return 0;
}
int Permutation()
{
int a = 1;
printf("***** Welcome to Use PermutationTool! *****\n");
printf("***** 1.encode 0.exit *****\n");
printf("Please make a choice :>");
scanf("%d",&a);
return a;
}
int main()
{
//1. 多次判断+输入信息
int a = 1;
while (a)
{
a = Permutation();
if(a == 0)
break;
else if(a == 1)
decode();
}
return 0;
}
运行结果
0x04 列置换密码
例如我们有一个明文:
The reign of House Of Cards may be short lived
我们定加密密钥为:(143)(56)
这里第一眼可能很难看懂,其实意思是:
第一列放到第四列
第四列放到第三列
第三列放到第一列
第五列放到第六列
第六列放到第五列
进行按六位分组
明文P,不足部分用双方约定的进行补充
加密后为
得出最终密文
eoedeI hnsrbt rfOssi TguayrdioCaoe eHFmhv