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

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);
}




posted @ 2024-01-28 17:17  zer0_h  阅读(254)  评论(0)    收藏  举报