-
维吉尼亚密码
人们在单一
恺撒密码的基础上扩展出多表密码,称为“维吉尼亚”密码。该方法最早记录在
吉奥万·巴蒂斯塔·贝拉索( Giovan Battista Bellaso)于1553年所著的书《吉奥万·巴蒂斯塔·贝拉索先生的密码》(意大利语:La cifra del. Sig. Giovan Battista Bellaso)中。
维吉尼亚密码引入了“
密钥”的概念,即根据密钥来决定用哪一行的密表来进行替换,以此来对抗字频统计。假如以上面第一行代表明文字母,左面第一列代表密钥字母,对如下明文加密:
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
历史上以维吉尼亚密表为基础又演变出很多种加密方法,其基本元素无非是密表与密钥,并一直沿用到二战以后的初级电子密码机上。
公元16世纪晚期,想要获得更高的保密度的人获得了一种设计更加精细的密码表。
实现图片:
实现代码:
#include <stdio.h> #include <malloc.h> #include <stdlib.h> #include <memory.h> #define MAXSIZE 1000 typedef struct duplexNode{ char alphabet; struct duplexNode * previous; struct duplexNode * next; }DuplexNode,*DuplexLinkList; typedef enum{ FAILED,SUCCESS }Status; Status initDuplexLinkList(DuplexLinkList * duplexLinkList); void vigenere(DuplexLinkList *duplexLinkList,char al,int n); char * s_gets(char * s,int n); int main(void) { char str_temp[MAXSIZE] = {'\0'}; int rand_temp[MAXSIZE] = {0}; int j = 0; DuplexLinkList duplexLinkList = NULL; if(initDuplexLinkList(&duplexLinkList) == FAILED) { fprintf(stderr,"failed of init!"); exit(1); } printf("请输入明文:"); s_gets(str_temp,MAXSIZE); printf("随机密匙:"); while(str_temp[j] != '\0') { rand_temp[j] = rand()%100+1; printf("%d ",rand_temp[j]); j++; } printf("\n"); printf("密文:"); for(int m=0;m<j;m++) vigenere(&duplexLinkList,str_temp[m],rand_temp[m]); printf("\n"); return 0; } Status initDuplexLinkList(DuplexLinkList * duplexLinkList) { (*duplexLinkList) = (DuplexNode *)malloc(sizeof(DuplexNode)); (*duplexLinkList)->alphabet = NULL; DuplexNode *p, *q = NULL; p = (*duplexLinkList); int k; for(k=0;k<26;k++) { q = (DuplexNode *)malloc(sizeof(DuplexNode)); if(!q) { fprintf(stderr,"error due to malloc!\n"); return FAILED; } q->alphabet = (char) ('A' + k); q->previous = p; q->next = NULL; p->next = q; p = q; } q->next = (*duplexLinkList)->next; (*duplexLinkList)->next->previous = q; return SUCCESS; } void vigenere(DuplexLinkList *duplexLinkList,char al,int n) { DuplexNode * node = (*duplexLinkList)->next; //指向A int i = al - 'A'; for(int k=0;k<i+n;k++) node = node->next; printf("%c",node->alphabet); } char * s_gets(char * s,int n) { char *st=NULL,*find=NULL; st = fgets(s,n,stdin); if(st) { find = strchr(st,'\n'); if(find) *find = '\0'; else while(getchar() != '\n') continue; } return st; }