密码学课设 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
    评论
SPN加密算法(Substitution-Permutation Network)是一种分组加密算法,它由替换和置换两个步骤组成。下面是SPN加密算法的C语言实现: ```c #include <stdio.h> #define SBOX_SIZE 16 // S-盒的大小 #define NUM_ROUNDS 4 // 加密轮数 // S-盒的定义 int sBox[SBOX_SIZE] = {0x9, 0x4, 0xa, 0xb, 0xd, 0x1, 0x8, 0x5, 0x6, 0x2, 0x0, 0x3, 0xc, 0xe, 0xf, 0x7}; // 加密函数 int encrypt(int plaintext, int key) { int i, j; int cipher = plaintext ^ key; // 异或运算 for (i = 0; i < NUM_ROUNDS; i++) { // 替换步骤 int sBoxInput = 0; for (j = 0; j < SBOX_SIZE; j++) { if ((cipher >> j) & 1) { sBoxInput ^= j; } } int sBoxOutput = sBox[sBoxInput]; // 置换步骤 int permutationOutput = 0; for (j = 0; j < SBOX_SIZE; j++) { permutationOutput ^= ((sBoxOutput >> j) & 1) << ((4 * j) % SBOX_SIZE); } cipher = permutationOutput; } return cipher; } int main() { int plaintext = 0x8; // 明文 int key = 0x3; // 密钥 int ciphertext = encrypt(plaintext, key); printf("Ciphertext: 0x%x\n", ciphertext); return 0; } ``` 以上是SPN加密算法的C语言实现示例。具体实现中,使用了一个S-盒作为替代步骤,并进行了4轮的替代和置换操作。在 `encrypt` 函数中,首先将明文和密钥进行异或运算得到初始密文,在每一轮中依次进行替代和置换操作得到下一轮的密文。最后得到的密文即为加密结果。 在示例中,明文和密钥分别使用了十六进制表示法,可以根据需要进行修改。运行程序后,将输出加密结果的十六进制表示。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值