双向循环链表:维吉尼亚密码
生活随笔
收集整理的這篇文章主要介紹了
双向循环链表:维吉尼亚密码
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
維吉尼亞密碼簡介
維吉尼亞密碼引入了“密鑰”的概念,即根據密鑰來決定用哪一行的密表來進行替換,以此來對抗字頻統計。假如下面圖第一行代表明文字母,左面第一列代表密鑰字母,對如下明文加密:
TO BE OR NOT TO BE THAT IS THE QUESTION
當選定RELATIONS作為密鑰時,加密過程是:明文一個字母為T,第一個密鑰字母為R,因此可以找到在R行中代替T的為K,依此類推,得出對應關系如下:
密鑰:RELAT IONSR ELATI ONSRE LATIO NSREL
明文:TOBEO RNOTT OBETH ATIST HEQUE STION
密文:KSMEH ZBBLK SMEMP OGAJX SEJCS FLZSY
維吉尼亞密碼分析
明文T字符 密鑰是R 對應的密文是K?從數學角度 有沒有規律可尋呢?我們仔細看圖,每一行每一列都是26個連續的字母,不同字母開頭反正都是循環一圈,
從明文T到 密文K 是不是經歷了17個單元,恰巧是密鑰R在26個元素中的下標17。
我們將 A—Z密鑰看作0—25個數,明文字符在A—Z循環鏈表走過 密鑰個數結點 到密文結點。說的太拗口,舉個簡單例子,明文是 T ,密鑰是B那么 T 走1個位置 是 U ,那么 明文就T的密文 就是U??磮D 查看密鑰是不是。
循環鏈表實現方式
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #define OK 1 #define ERROR 0typedef int Status; typedef char EleType; //雙向循環鏈表 結點數據結構 typedef struct DulNode {EleType data;//數據域struct DulNode* next;//后繼結點指針域struct DulNode* prior;//前驅結點指針域 }DulNode, *DulLinkList; //取了別名 DulNode* 相當于DulLInkListDulLinkList list_AZ = NULL;//創建26個英文字母雙向循環鏈表 Status CreatDulLink(DulLinkList* list) {if (list == NULL){return ERROR;}DulNode* head = (DulNode*)malloc(sizeof(DulNode));//創建頭結點if (head == NULL){return ERROR;}DulNode* p = head;//p 移動指針,起初指向頭結點p->next = p->prior = NULL;for (size_t i = 0; i < 26; i++){DulNode* node = (DulNode*)malloc(sizeof(DulNode));//創建結點node->data = 'A' + i;//下面3步將創建的node結點放到雙向循環鏈表中node->next = p->next;//直接賦值NULL也可以node->prior = p;p->next = node;//p 始終指向鏈表最后一個結點p = node;}//下2步 將尾結點和第一個結點關聯形成雙向循環鏈表,越過頭結點。p->next = head->next;head->next->prior = p;//循環鏈表指向第一個元素*list = p->next;//釋放頭結點free(head);return OK; } //進行位移 Status Caesar(DulLinkList* list, int num) {DulLinkList tmp = *list;//雙向循環鏈表指針往后移if (num > 0){int i = 0;//num = 1 往后移動1位, temp = temp -> nextwhile (i < num){tmp = tmp->next;i++;}*list = tmp;}//雙向循環鏈表指針往前移if (num < 0){int i = 0;//num = -1 往前移動1位,temp = temp->priorwhile (i < num*-1){tmp = tmp->prior;i++;}*list = tmp;}return OK; }/* 獲取密文字符 num 字符移動位數 ch 字符起點 */ char GetCipertext(int num,char ch) {//printf("num=%d", num);DulLinkList list = list_AZ;//移動到字符位置Caesar(&list, ch - 'A');//根據密鑰進行偏移Caesar(&list, num);return list->data; }/* 維吉尼亞密碼 生成隨機密鑰 根據隨機密鑰進行加密 */Status Virginia(char* words,char** keytext,char** cipertext ,int len) {char* key = (char*)malloc(sizeof(char)*len+1);char* ciper = (char*)malloc(sizeof(char)*len+1);memset(key, 0, len + 1);memset(ciper, 0, len + 1);srand((size_t)time(NULL));for (size_t i = 0; i < len; i++){//需要范圍為 x ~ y 公式 為 rand()%(y-x)+x //如果需要 1~ 9 公式為 rand()%8+1int num = rand() % 26;key[i] = 'A' + num;ciper[i] = GetCipertext(num,words[i]);}//通過指針返回數據*cipertext = ciper;*keytext = key;return OK; }int main(int argc, char *argv[]) { //創建26個字母的循環鏈表CreatDulLink(&list_AZ);char temp[1024] = {0};while (1){printf("請輸入一段明文(英文大寫,0退出):");scanf("%s", temp);if (temp[0] == '0'){break;}char* key = NULL;char* ciper = NULL;Virginia(temp,&key, &ciper, strlen(temp));printf("明文:%s\n", temp);printf("密鑰:%s\n", key);printf("密文:%s\n", ciper);}system("pause");return 0; }
運行結果
對照維吉尼亞密碼表 沒有問題
總結
以上是生活随笔為你收集整理的双向循环链表:维吉尼亚密码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 人生实苦,可这就是人生
- 下一篇: excl中将某列数据合到单个单元格