首页 > 其他分享 >维吉尼亚c语言实现加解密

维吉尼亚c语言实现加解密

时间:2024-01-28 17:23:17浏览次数:24  
标签:DuLinkedList 语言 int printf 加解密 next char 维吉尼亚 keyList

image

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <time.h>

#define OK 		1
#define ERROR 	0

typedef struct DualNode {
    int data;
    struct DualNode* prior;
    struct DualNode* next;
} DualNode, *DuLinkedList;

// 函数声明
DuLinkedList createDualList(int n);
char* vigenereDecrypt(const char* ciphertext, DuLinkedList keyList);
void destroyDualList(DuLinkedList L);
char* vigenereEncrypt(const char* plaintext, DuLinkedList keyList);
void saveKeyToFile(DuLinkedList keyList, const char* filename);
void readKeyFromFile(const char* filename, int** keyArray, int* keyArrayLength);

int main() {
    const char* plaintext = "HELLOWORLD";
    const char* filename = "key.txt";



    // 创建维吉尼亚密码的密钥链表
    DuLinkedList keyList = createDualList(10);

    // 维吉尼亚加密
    
    printf("明文: %s\n", plaintext);
    printf("密钥: ");

    DuLinkedList p = keyList->next;
	

    do
	{	
		printf("%d ", p->data);
        p =p->next;
    }while( p->next != keyList->next->next );
    
    printf("\n");
	char* ciphertext = vigenereEncrypt(plaintext, keyList);
    printf("密文: %s\n", ciphertext);

    // 将密钥保存到文件
    saveKeyToFile(keyList, filename);
    printf("密钥已保存到文件 %s\n", filename);
	
	int* keyArray;
    int keyArrayLength;

    readKeyFromFile(filename, &keyArray, &keyArrayLength);

    printf("读取到的密钥值:");
    for (int i = 0; i < keyArrayLength; i++) {
        printf("%d ", keyArray[i]);
    }
    printf("\n");

    free(keyArray);

	
	
	
	char* decryptedText = vigenereDecrypt(ciphertext, keyList);
	printf("解密后的明文: %s\n", decryptedText);
	
    // 释放动态分配的内存
    free(ciphertext);
    destroyDualList(keyList);
	
	
    return 0;
}



void readKeyFromFile(const char* filename, int** keyArray, int* keyArrayLength) {
    FILE* file = fopen(filename, "r");
    if (file == NULL) {
        printf("无法打开文件 %s\n", filename);
        return;
    }

    int count = 0;
    int number;
    while (fscanf(file, "%d", &number) == 1) {
        count++;
    }

    *keyArrayLength = count;
    *keyArray = (int*)malloc(count * sizeof(int));
    if (*keyArray == NULL) {
        printf("内存分配失败\n");
        fclose(file);
        return;
    }

    fseek(file, 0, SEEK_SET);
    count = 0;
    while (fscanf(file, "%d", &number) == 1) {
        (*keyArray)[count] = number;
        count++;
    }

    fclose(file);
}


char* vigenereDecrypt(const char* ciphertext, DuLinkedList keyList) {
    int ciphertextLen = strlen(ciphertext);
    char* plaintext = (char*)malloc((ciphertextLen + 1) * sizeof(char));

    for (int i = 0; i < ciphertextLen; i++) {
        char ciphertextChar = toupper(ciphertext[i]);

        int keyNum = keyList->next->data;
        keyList->next = keyList->next->next;

        int ciphertextIndex = ciphertextChar - 'A';
        int keyIndex = keyNum % 26;
        int plaintextIndex = (ciphertextIndex - keyIndex + 26) % 26;

        plaintext[i] = 'A' + plaintextIndex;
    }

    plaintext[ciphertextLen] = '\0';
    return plaintext;
}

DuLinkedList createDualList(int n) {
    DuLinkedList q, p;

    DuLinkedList L = (DuLinkedList)malloc(sizeof(DualNode));
    if (!L) {
        return NULL;
    }

    // 链表初始化 
    L->prior = L->next = L;
    p = L;
    srand(time(NULL));

    for (int i = 0; i < n; i++) {
        int randomNum = rand() % 5;  // 生成0到99之间的随机数字
        q = (DuLinkedList)malloc(sizeof(DualNode));
        if (!q) {
            return NULL;
        }
//        赋值 
        q->data = randomNum;
        
//        头&next 
        q->prior = p;
        q->next = p->next;
//        头尾相连 
        p->next->prior = q;
//        尾巴 
        p->next = q;
//        位置互换 
        p = q;
    }
	q->next =L->next;
	L->next->prior =q;
    return L;
}



void destroyDualList(DuLinkedList L) {
    DuLinkedList p = L->next;
    while (p != L) {
        DuLinkedList temp = p;
        p = p->next;
        free(temp);
    }
    free(L);
}

char* vigenereEncrypt(const char* plaintext, DuLinkedList keyList) { 
	// 获取明文字符长度 
    int plaintextLen = strlen(plaintext);
    // 分配加密字符的空间 
    char* ciphertext = (char*)malloc((plaintextLen + 1) * sizeof(char));

    

        


    for (int i = 0; i < plaintextLen; i++) {
    	// 全部转换成大写字母 
        char plaintextChar = toupper(plaintext[i]);
        
        int keyNum = keyList->next->data;

        // 移动密钥链表的指针
        keyList->next = keyList->next->next;

        // 计算密文字母的位置
        int plaintextIndex = plaintextChar - 'A';
        int keyIndex = keyNum % 26;
        int ciphertextIndex = (plaintextIndex + keyIndex) % 26;

        // 将密文字母存储到结果中
        ciphertext[i] = 'A' + ciphertextIndex;
    }

    ciphertext[plaintextLen] = '\0';
    return ciphertext;
}


void saveKeyToFile(DuLinkedList keyList, const char* filename) {
    FILE* file = fopen(filename, "w");
    if (file == NULL) {
        printf("无法打开文件 %s\n", filename);
        return;
    }

    DuLinkedList p = keyList->next;
	
	do
	{	
		
        fprintf(file, "%d\n", p->data);
        p = p->next;
    }while( p->next != keyList->next->next );
	
	
   

    fclose(file);
}

附:双向链表c-code

#include <stdio.h>
#include <stdlib.h>
 
#define OK 		1
#define ERROR 	0

typedef char 	ElemType;
typedef int		Status;

typedef struct DualNode
{
	ElemType data;
	struct DualNode *prior;
	struct DualNode *next;	
}DualNdoe, *DuLinList;


Status InitList(DuLinList *L)
{
	DuLinList q, p;
	int i;
	
	*L = (DuLinList)malloc(sizeof(DualNdoe));
	if ( !(*L) )
	{
		return ERROR;
	}
	(*L)->next = (*L)->prior = NULL;
	p = (*L);
	for( i=0; i<26; i++ )
	{
		q = (DuLinList)malloc(sizeof(DualNdoe));
		if ( !q)
		{
			return ERROR;
		}
		q->data = 'A'+i;
		q->prior = q;
		q->next = p->next;
		p->next = q;
		p = q;
	}
	
	
	p->next = (*L)->next;
	(*L)->next->prior =p;
	
	
	return OK;
}

void DestroyList(DuLinList *L)
{
    DuLinList p = (*L)->next; // 获取第一个节点

    while (p != (*L)) {
        DuLinList temp = p;
        p = p->next; // 移动到下一个节点
        free(temp); // 释放当前节点的内存
    }

    free(*L); // 释放链表头结点的内存
    *L = NULL; // 将链表头指针置为空
}



void Caesar(DuLinList *L, int i)
{
	if( i>0 )
	{
		do
		{
			(*L) = (*L)->next;
		}while(--i); 
	}
	
	if( i<0 )
	{
		do
		{
			(*L) = (*L)->next;
		}while(++i);
	}
}

int main()
{
	DuLinList L;
	int i, n;
	printf("Enter a Integer Number:");
	InitList(&L);

	scanf("%d",&n);
	printf("\n");
	
	Caesar(&L, n);
	
	for( i=0; i < 26; i++ )
	{
		L = L->next;
		printf("-%c-",L->data);
		
	}	
	DestroyList(&L);
}




标签:DuLinkedList,语言,int,printf,加解密,next,char,维吉尼亚,keyList
From: https://www.cnblogs.com/z3r0/p/17993041

相关文章

  • [职场] 面试题:Java语言技术的应用有哪些?
    小伙伴们面试时,特别是和代码相关的岗位,面试时可能会遇见关于Java语言技术的应用这个问题,那么我们应该如何作答呢?一起来看看答案吧!答案:1、Android,应用许多的Android,应用都是Java程序员开发者开发。虽然Androidi运用了不同的JVMl以及不同的封装方式,但是代码还是用Java语言所编写。......
  • 初识C语言
    今天第一次接触了C语言,认识了C语言。C语言,即computer语言,是计算机能够识别、能够执行的语言。人与人之间是靠着各种语言在进行交流,比如上级对下级发布任务,上级会对此任务进行描述,使得下级能够看懂或者听懂,进而完成上级的命令;计算机与人之间的交流类似于此。人类好比计算机的上级,......
  • C语言代码实现:一个整数存储在内存中的二进制中的1的个数
    e.g.代码实现:一个整数存储在内存中的二进制中的1的个数#define_CRT_SECURE_NO_WARNINGS1#include<stdio.h>intmain(){ intnum=0; intcount=0; printf("统计num的补码中有几个1,请输入num:>"); scanf("%d",&num); //统计num的补码中有几个1 //法一 //while(nu......
  • C语言学习Part2(1000-2000行代码)
    #define_CRT_SECURE_NO_WARNINGS1#include<stdio.h>//头文件,仅标注一次e.g.猜数字游戏//e.g.猜数字游戏//1.电脑生成一个随机数//2.猜数字//3.循环玩#include<stdlib.h>#include<time.h>voidmenu(){ printf("************************\n"); printf("***1.pla......
  • R语言中的模拟过程和离散化:泊松过程和维纳过程
    全文链接:http://tecdat.cn/?p=17303 原文出处:拓端数据部落公众号本文中,我们讨论了一个将Poisson过程与Wiener过程结合在一起的最佳算法的问题。实际上,为了生成泊松过程,我们总是习惯于模拟跳跃之间的持续时间。我们使用给定时间间隔内跳跃的均匀性,该条件取决于跳跃的次数。首先......
  • R语言KNN模型分类信贷用户信用等级参数调优和预测可视化
    全文链接:https://tecdat.cn/?p=34941原文出处:拓端数据部落公众号本文主要介绍了如何帮助客户通过读取数据、查看部分数据、转换数据为因子并将数值变量归一化、进行描述性分析、建立knn模型等步骤对数据进行分析。通过分别选择不同的k值进行建模,并对比它们的准确度,找到最优的参......
  • (2024.1.22-2024.1.28)C语言学习小结
    本周主要围绕《HeadfirstC》这本书展开C语言学习,按照计划,我学习了前四章的内容。基本内容以下时学习做的思维导图(笔记)第1章虽然做的是思维导图,但实际上因为大多数内容已经掌握,所以实际上就是补充记了几个零散的点。第2、2.5章主要是指针、数组、字符串的内容,大多也已经......
  • 大语言模型(LLM)运行报错:AttributeError: module 'streamlit' has no attribute 'cache_
    解决方法:......
  • python语言理解
    类python是一门面向对象的语言,强调的是对象,当我们创建一个类时,必然要给这个类赋予对应的属性去描述它,例如一个动物的类,那么这个类应该有动物种类,颜色,年龄,体重,习性等属性,代码如下:classAnimal:def__init__(self,species,color,age,weight,habitat):self.spec......
  • c++实现一门计算机语言到手撸虚拟机实战200节
    1对于编程语言实现原理提供了实战。2学习之后对于JAVA,PHP,PY等语言的实现原理提供了经验平移参考3对JAVA等语言的虚拟机实现原理提供了实战参考。4加深对编程语言的驾驭和深度认知。5虚拟机是计算机系统中非常重要的组成部分,理解了虚拟机的原理和实现方式,从而更好地理解计算......