您好,登錄后才能下訂單哦!
很多教材上對(duì)于行置換密碼、列置換密碼的定義都不是完全相同,甚至核心思想根本不一樣。筆者就自己學(xué)習(xí)的經(jīng)歷,簡(jiǎn)單介紹一種一些教材上所謂的“行置換密碼”的算法,大家一起交流、探討。
利用這種加密方法,明文按行填寫在一個(gè)矩陣中,而明文則是以預(yù)定的順序按列讀取生成的。例如如果矩陣是4列5行,那么明文“encryption algorithm”(省去空格后)可以如下寫入該矩陣:
2 | 3 | 1 | 4 |
e | n | c | r |
y | p | t | i |
o | n | a | l |
g | o | r | i |
t | h | m | s |
按一定的順序讀取列以生成密文。
對(duì)于這個(gè)示例,如果讀取順序?yàn)檫f增順序,則明文就是:“ctarm eyogt npnoh rilis”(添加空格只是為了便于觀察)。這種加密法的密鑰是列數(shù)和讀取列的順序。如果列數(shù)很多,記起來(lái)可能會(huì)比較困難,因此它可以表示成一個(gè)關(guān)鍵詞,該關(guān)鍵詞的長(zhǎng)度等于列數(shù),而其字母順序決定讀取列的順序。
例如,關(guān)鍵詞“general”有7個(gè)字母,意味著矩陣有7列。由于“a”是“general”中字母順序最低的,因此數(shù)字1放在第6列;從左往右,第一個(gè)“e”為其次,所以數(shù)字2放在第2列;第二個(gè)“e”則是使數(shù)字3放在第4列。最后的順序如下:
g e n e r a l
4 2 6 3 7 1 5
_______________________________________________________________________________________
This scheme is to write the message in a rectangle, row by row, and read the message off, column by column, but permute the order of the columns.The order of the columns then becomes the key to the algorithm.For example,
Key: 4 3 1 2 5 6 7
Plaintext: a t t a c k p
o s t p o n e
d u n t i l t
w o a m x y z
Ciphertext: ttna aptm tsuo aodw coix knly petz (再次強(qiáng)調(diào),空格只是為了便于觀察)
Thus, in this example, the key is 4312567.To encrypt, start with the column that is labeled 1, in this case column 3. Write down all the letters in that column.
**************************************************************************************
上述的是一次加密,也可把上述密文當(dāng)做新一輪加密的明文,再次進(jìn)行行置換加密。
參考資料:
《Cryptography and Network Security Principles and Practice, Fifth Edition》
————William Stallings
《Classical And Contemporary Cryptology》 ————Richard Spillman
- //Z26上的行置換密碼
- #include<stdio.h>
- #include<string.h>
- #include<stdlib.h>
- #include<time.h>
- int length;//明文長(zhǎng)度
- char plain[100000];
- char cipher[100000];
- char out[100000];
- int l;//密鑰長(zhǎng)度
- int key[100];//密鑰
- int done_key[100]= {0}; //標(biāo)記是否已經(jīng)被轉(zhuǎn)換為數(shù)字
- int num_key[100]= {0};//把密鑰換成數(shù)字
- int num[100];//臨時(shí)矩陣,存放使順序遞增的下標(biāo)序號(hào)
- void gen();//密鑰生成算法
- void encryption();
- void decryption();
- int length_str(int a[]);
- int main()
- {
- int i;
- FILE *fp;
- fp=fopen("plain.txt", "r");
- fscanf(fp, "%s", plain);//從文件讀入明文
- fclose(fp);
- length=strlen(plain);
- gen();
- encryption();
- printf("以上正確");
- decryption();
- for(i=0;i<length;i++)
- {
- printf("%c", out[i]);
- }
- return 0;
- }
- void gen()//密鑰生成算法
- {
- int i;
- printf("請(qǐng)輸入想生成的隨機(jī)密鑰的長(zhǎng)度:");
- scanf("%d", &l);
- srand(time(0));
- for(i=0; i<l; i++)
- {
- key[i]=rand()%26;
- }
- printf("\n隨機(jī)產(chǎn)生的密鑰串為:");
- for(i=0; i<l; i++)
- {
- printf("%c ", key[i]+97);
- }
- printf("\n\n");
- }
- char a[50000][100];//臨時(shí)矩陣,為了更方便的把密文轉(zhuǎn)換出來(lái)
- //這個(gè)數(shù)組必須設(shè)置為全局的,在函數(shù)中聲明的話申請(qǐng)內(nèi)存會(huì)出錯(cuò)!!!
- void encryption()
- {
- ///轉(zhuǎn)換:把密鑰字符串排序,變成數(shù)字
- int k=1;
- int i, j, m;
- int small;//每輪循環(huán)給"最小"的字母編號(hào)(未編號(hào)的、靠前的、序號(hào)小的字母為最小)
- for(i=0; i<l; i++) //把字母換成從1開始的數(shù)字
- {
- m=0;
- while(done_key[m]==1)
- m++;
- small=m;
- for(j=0; j<l; j++)
- {
- if(done_key[j]==0)//沒轉(zhuǎn)換則繼續(xù)
- if(key[j]<key[small])
- small=j;
- }
- num_key[small]=k;
- done_key[small]=1;
- k++;
- }//
- printf("The order of the key is :\n");
- for(i=0; i<l; i++)
- {
- printf("%d ", num_key[i]);
- }
- printf("\n");
- for(i=0; i<length; i++) //忽略非字母字符,把大寫轉(zhuǎn)換為小寫
- {
- if(plain[i]>=65&&plain[i]<=90)
- {
- plain[i]+=32;
- }
- }
- while(length%l)
- {
- strcat(plain,"p");//不能整除時(shí)補(bǔ)上無(wú)效字符p
- length++;
- }
- //生成密文矩陣
- k=0;
- for(i=0; i<length/l; i++) //行
- for(j=0; j<l; j++) //列
- {
- a[i][j]=plain[k++];
- }
- k=0;
- for(i=0;i<l;i++)//列
- {
- for(j=0;j<l;j++)
- if(num_key[j]==i+1)
- num[i]=j;
- }
- k=0;
- for(m=0;m<l;m++)//列
- for(j=0;j<length/l;j++)//行
- cipher[k++]=a[j][num[m]];
- }
- char b[50000][100];
- void decryption()//解密函數(shù)
- {
- int i, j, k;
- k=0;
- for(i=0;i<l;i++)//num[i]作為列
- for(j=0;j<length/l;j++)//行
- b[j][num[i]]=cipher[k++];
- k=0;
- for(i=0;i<length/l;i++)//行
- for(j=0;j<l;j++)//列
- out[k++]=b[i][j];
- }
//同文件夾下需要有“plain.txt”文件,里面必須全部是英文字母,可大小寫混雜,但是不能出現(xiàn)其他字符,如空格、回車換行、數(shù)字等。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。