密码学课设 SPN实现 Hust

这里写自定义目录标题

题目要求

Input
第一行,一个正整数n,表示n组数据。
接下来n行,每行包含两个用空格分开的16进制字符串。第一个字符串长度为8,表示32比特密钥key,第二个字符串长度为4,表示16比特明文。
对1<=k<=6,第k个数据点点满足n = 10^k。
对k=7,n = 4*10^6。
TIPS: 需要快速读入

Output
共n行,每行包含两个用空格分开的16进制字符串。第一个字符串表示对应行的明文加密后的密文,第二个字符串表示将密文最后1比特取反,解密后得到的明文。

在这里插入图片描述

未优化的代码

目前只能跑过k=5,再高就跑的太慢了,还是太菜了。

#include <string>
#include <iostream>
#include <math.h>
#include <vector>
#include <cstring>
#include<algorithm>

#pragma warning(disable : 4996)

static int SBox[16] = {
   14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7};
static int PBox[16] = {
   1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16};
static int SBox_inverse[16] = {
   14,3,4,8,1,12,10,15,7,13,9,6,11,2,0,5};
static int PBox_inverse[16] = {
   1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16};

using namespace std;

int HexToDec(string str)        //十六进制转十进制
{
   
	if (str.empty())
		return 1;				//字符串为空
	if (str.length() > 8)
		return -1;				//超出范围
	int n = 0;
	char* pc = const_cast<char*>(str.c_str());
	int cpyCount = str.length();
	int mid;
	for (int i = 0; i < cpyCount; i++)
	{
   
		if (*pc >= '0' && *pc <= '9')
			mid = *pc - '0';
		else if (*pc >= 'A' && *pc <= 'F')
			mid = *pc - 'A' + 10;
		else if (*pc >= 'a' && *pc <= 'f')
			mid = *pc - 'a' + 10;
		else
			return -1;			//含有非法字符

		mid *= pow(16,(cpyCount - 1 - i));
		n += mid;
		pc++;
	}
	return n;
}

string DecToHex(int dec)        //十进制转十六进制
{
   
	char hex[16] = {
   '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};

	string str = "";
	for (int i = 4; i > 0; i--)		//将十六进制存为字符数组
	{
   
		int point = (int)(dec / pow(16, i - 1));
		str = str + hex[point];
		dec = dec - point * pow(16, i - 1);
	}
	return str;
}

string DecToBin(int dec)					//十进制转二进制
{
   
		string	s;
		for (int a = dec, i=0; a || i<16; a = a / 2, i++)
			s = s + ((a % 2) ? '1' : '0');	//不断进行相除
		reverse(s.begin(), s.end());		//倒置字符串
		return s;
}

int BinToDec(string str)					//二进制转十进制
{
   
	int n = 0;
	char* pc = const_cast<char*>(str.c_str());
	int cpyCount = str.length();
	int mid;
	for (int i = 0; i < cpyCount; i++)
	{
   
		if (*pc == '1')
			mid = *pc - '0';
		else
			mid = 0;
		mid *= pow(2, (cpyCount - 1 - i));
		n += mid;
		pc++;
	}
	return n;
}

string S_Change(string str)					//S盒置换
{
   
	auto length = str.length();
	string back = "";
	for (int i = 0; i < length; i++)
	{
   
		
		string tool = str.substr(i, 
  • 6
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值