(免费)字符串移位、替换、置换的简单实现(C++源码,ascii的所有字符)

本文详细介绍了如何使用移位、替换和置换表(二维数组)对字符串进行加密,以及对应的解密过程,涉及凯撒加密原理和C++代码实现。
摘要由CSDN通过智能技术生成

目录

一、前言

二、原理

三、代码

四、闲谈


一、前言

作者:钱塘江上潮信来,今日方知我是我

原创内容转载需说明

二、原理

加密:

移位类似凯撒加密;替换采用用了map映射思想,数组下标对应要加密字符的ascii码,数组的值是下标相应的替换字符;置换:col设置一行最多有几列,做成二维表,然后两列两列相交换,剩下的单列不交换,使用列存储的方式转化成一维数组。

解密:

与加密反着来,再反转解密顺序。

三、代码

#include <iostream>//C++标准输入输出函数和常用函数文件
#include <string>//存储字符串操作函数文件
#include <vector>//存储数据类型模版容器函数文件

//声明流输入输出、字符串和vector容器操作等功能
using std::cin;
using std::cout;
using std::string;
using std::vector;

//移位操作函数(-key可以还原字符串)
/* 默认操作可见字符,若想设置默认所有ASCII表内字符则分别设置为0, 127, 128 */
string Shift(string str, short key, short begin = 32, short end = 126, short base = 95);

//替换操作函数
/* 默认操作可见字符,若想设置默认所有ASCII表内字符则分别设置为0, 127 */
string ToMapping(string str, short begin = 32, short end = 126);

//替换成原来的操作函数
/* 默认操作可见字符,若想设置默认所有ASCII表内字符则分别设置为0, 127 */
string ReMapping(string str, short begin = 32, short end = 126);

string Map;//替换表,储存ASCII表内替换内容
string InitMap();//初始化Map表

/*ASCII表可显示字符有: !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ */
string map0_9 = "7853214690";//0到9替换表
string mapA_Z = "poiuytrewqlkjhgfdsamnbvcxz";//A到Z替换表
string mapa_z = "MNBVCXZLKJHGFDSAPOIUYTREWQ";//a到z替换表

//其他符号的替换:
string map32_47 = "+-)!#$(\" /\'*.,&%";
string map58_64 = "<@;?:=>";
string map91_96 = "`^_][\\";
string map123_126 = "~}{|";

/* 不可显示符号的替换: { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,127 };*/
string map0_31 = { 20,21,22,23,24,25,16,127,18,19,10,31,30,29,28,27,26,12,13,14,15,11,8,9,6,7,4,5,2,3,0,1 };
char map127 = 17;

//置换操作
string Permutation(string str, unsigned short cols, bool &b);
//反置换操作
string RePermutation(string str, unsigned short cols, bool &b);


//加密函数
string Encrypted(string str, short key, unsigned short col, bool &b);
//解密函数
string Decrypt(string str, short key, unsigned short col, bool &b);

int main() {

	/* {
		//对照表,ascii可显示字符串,32:126。测试数据用到,加密解密未用到。
		string Initial_Array;

		for (size_t i = 0; i < 95; i++) {
		Initial_Array += char(i + 32);
		}
		cout << Initial_Array << '\n';
		cout << Initial_Array.length();
	}*/

	string str;//储存加密解密字符串
	short key = 5;//向左移5位。负数向右移。
	short col = 5;//置换表设置成5列。
	bool b = true;//字符串长度大于等于置换表列数(5)。
	Map = InitMap();//初始化替换表。

	cout << "请输入要加密的字符串:\n";
	cin >> str;


	//进行一次加密
	string str1 = Encrypted(str, key, col, b);
	if (!b) {cout << "加密失败";return -1;}//如果输入字符串小于置换表列长(5)
	cout << "加密后的字符串为:\n" << str1 << '\n';//输出结果

	//进行一次解密
	str = Decrypt(str1, key, col, b);
	cout << "解密后的字符串为:\n" << str << '\n';//输出结果


	return 0;
}

//移位函数
string Shift(string str, short key, short begin, short end, short base) {
	string s;
	short t = 0;
	for (short i = 0; i < str.length(); i++) {
		t = str[i];
		if (t >= begin && t <= end) {
			t += key;
			if (t > end) s += char(t - base);
			else if (t < begin) s += char(t + base);
			else s += char(t);
		}
		else s += char(t);
	}
	return s;
}

//映射替换
string ToMapping(string str, short begin, short end) {
	string s;
	for (char& c : str)
		for (short i = begin; i <= end; i++)
			if (c == i) {
				s += Map[i];
				break;
			}
	return s;
}

//替换回来
string ReMapping(string str, short begin, short end) {
	string s;
	for (char& c : str)
		for (short i = begin; i <= end; i++)
			if (c == Map[i]) {
				s += char(i);
				break;
			}
	return s;
}

string InitMap() {//初始化替换表
	string s;
	s = map0_31;
	s += map32_47;
	s += map0_9;
	s += map58_64;
	s += mapA_Z;
	s += map91_96;
	s += mapa_z;
	s += map123_126;
	s += map127;
	return s;
}

//置换函数
string Permutation(string str, unsigned short cols, bool &b) {
	unsigned short len = unsigned short(str.length());
	if (len < cols) {
		cout << "置换失败:字符串总长度小于所设置的列长("<< cols <<")\n";
		b = false;
		return str;
	}
	unsigned short rows = unsigned short(len / cols);
	if (rows * cols != len)rows += 1;
	

	// 使用vector来创建二维数组
	vector<string> t1(rows, string(cols, '\0'));
	vector<string> t2(rows, string(cols, '\0'));

	//分割数组
	unsigned short row = 0;
	unsigned short col = 0;
	for (unsigned short i = 0; i < len; i++) {
		col = i % cols;
		if (i != 0 && col == 0)row += 1;
		t1[row][col] = str[i];
		t2[row][col] = str[i];
		col++;
	}

	if (cols > 1) {//第一列和第二列换,第三列和第四列换,第五列和第六列换……
		for (unsigned short i = 0; i < cols; i+=2) {
			for (unsigned short j = 0; j < rows; j++) {
				if (t1[j][i + 1] == '\0')break;//单行不换
				t1[j][i] = t2[j][i + 1];
				t1[j][i+1] = t2[j][i];
			}
		}
	}

	// 列录入:将二维数组转换为一维字符串
	string s;
	for (unsigned short i = 0; i < cols; i++) {
		for (unsigned short j = 0; j < rows; j++) {
				s += t1[j][i];
		}
	}

	return s;
}

//置换回来
string RePermutation(string str, unsigned short cols, bool &b) {
	unsigned short len = unsigned short(str.length());
	if (len < cols) {
		cout << "置换失败:字符串总长度小于所设置的列长(" << cols << ")\n";
		b = false;
		return str;
	}
	unsigned short rows = unsigned short(len / cols);
	if (rows * cols != len)rows += 1;


	// 使用vector来创建二维数组
	vector<string> t1(rows, string(cols, '\0'));
	vector<string> t2(rows, string(cols, '\0'));

	//逆列录入,将一维数组转换为二维字符串
	unsigned short x = 0;
	for (unsigned short i = 0; i < cols; i++) {
		for (unsigned short j = 0; j < rows; j++) {
			t1[j][i] = str[x];
			t2[j][i] = str[x];
			x++;
		}
	}

	/*for (unsigned short i = 0; i < rows; i++) {
		for (unsigned short j = 0; j < cols; j++) {
			cout << t1[i][j];
		}
		cout << '\n';
	}
	cout << '\n';*/

	if (cols > 1) {//第一列和第二列换,第三列和第四列换,第五列和第六列换……
		for (unsigned short i = 0; i < cols; i += 2) {
			for (unsigned short j = 0; j < rows; j++) {
				if (t1[j][i + 1] == '\0')break;//单行不换
				t1[j][i] = t2[j][i + 1];
				t1[j][i + 1] = t2[j][i];
			}
		}
	}

	// 将二维数组转换为一维字符串
	string s;
	for (const auto& row : t1) {
		s += row;
	}

	return s;
}

//一次三操作加密
string Encrypted(string str, short key, unsigned short col, bool &b) {
	
	//ASCII表所有字符移位。32,126,95是可见字符移位
	string str1 = Shift(str, key, 0, 127, 128);

	//进行替换
	string str2 = ToMapping(str1);

	//进行置换
	str = Permutation(str2, col, b);

	return str;
}

//一次三操作解密
string Decrypt(string str, short key, unsigned short col, bool &b) {

	//进行反置换
	string str1 = RePermutation(str, col, b);

	//进行反替换
	string str2 = ReMapping(str1);

	//反移位。
	str = Shift(str2, -key, 0, 127, 128);

	return str;
}

四、闲谈

  • 8
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值