1. 程式人生 > >PlayFair密碼的實現

PlayFair密碼的實現

#include <iostream>
#include <string>
using std::cout;
using std::string;
using std::cin;
using std::endl;
   
void K_O(string* , string);   //這個函式

void pfdcp(string et, string pf[5][5] , int alp[3][26] , string nct[]);  //解密函式

//ct即cleartext,pf即密碼矩陣,alp即放了pf座標的字母表 
void pfecp(string ct, string pf[5][5] , int alp[3][26] , string eText[]);  //加密函式
int main()
{
    string key; //金鑰 
    string cleartext;  //明文  
    cout << "請輸入金鑰: " ;getline(cin, key);
    cout << "請輸入明文: " ;getline(cin, cleartext);
    string ecptext = cleartext;
    cout << "預設的密文: " << ecptext << endl; 
//    cout << key<<key.length() << endl;
    string playfair[5][5] ;  //密碼矩陣
    string another;   //約定填充的字母
    cout << "輸入約定的填充字母: ";cin >> another; 
	
	 
	
	string eText[cleartext.length()];    //
	string cText[ecptext.length()];
	 
    //去重
	int alp[3][26] = {{0*26},{0*26},{0*26}};
	int abLength=0;
    for(int i=0 ; i<key.length() ; i++){
    	
    	 if(alp[0][((int)key[i]) - 97] == 0){ //應該用一個臨時變數放這個強轉 
    	 	if(key[i] == 'i'||key[i] == 'j'){  //讓i、j變得相同 
    			alp[0][8]=alp[0][9]=1;
    			playfair[abLength/5][abLength%5] = key[i];
    			//新增alp在playfair裡面的對應座標
    			alp[1][8]=alp[1][9] = abLength/5;
    			alp[2][8]=alp[2][9] = abLength%5;
			 	abLength++;
			}
			else{
				alp[0][((int)key[i]) - 97] = 1;
    			playfair[abLength/5][abLength%5] = key[i];
    			alp[1][((int)key[i]) - 97] = abLength/5;
				alp[2][((int)key[i]) - 97] = abLength%5;
    			abLength++;
			}
		}
			
	}
	
	//檢查 
//	for(int i=0; i<5 ; i++){
//		for(int j=0 ; j<5 ; j++)
//		cout << playfair[i][j] ;
//		cout << endl;
//	}

//填充Playfair矩陣 
	for(int i = 0 ; i<26 ; i++){
			if (i == 8){
				if(alp[0][i] == 0){
					char x =i+97;
					playfair[abLength/5][abLength%5] = x;
					alp[1][i] = abLength/5;
					alp[2][i] = abLength%5; 
					alp[1][i+1] = abLength/5;
					alp[2][i+1] = abLength%5;
    				abLength++;
    				alp[0][i+1] = 1;
				}
			}
			else if(alp[0][i] == 0 ){
				char x =i+97;
				playfair[abLength/5][abLength%5] = x;
				alp[1][i] = abLength/5;
				alp[2][i] = abLength%5; 
    			abLength++;
			} 
		
	} 
		//填充檢查 
	for(int i=0; i<5 ; i++){
		for(int j=0 ; j<5 ; j++)
		cout << playfair[i][j] << " | ";
		cout << endl;
 	}
 	//檢查alp中的陣列下標 
// 	for(int i=0 ; i<3 ; i++){
// 		for(int j=0 ; j<26 ; j++)
// 			cout << alp[i][j] <<" | " ;
// 		cout << endl;
//	 }
 	
 	//明文預處理 
	K_O(&cleartext, another);
	//明文輸出檢查 
	cout <<"明文預處理輸出檢查: " << cleartext <<endl;
	
	pfecp(cleartext , playfair , alp , eText);
	
	cout << "密文: ";
	for(int i=0; i<cleartext.length() ; i++)
	cout << eText[i] ;
	cout << endl;
	
	pfdcp(ecptext , playfair , alp , cText);
	cout << "明文: ";
	for(int i=0 ; i<ecptext.length() ; i++)
	cout << cText[i] ;
 
	return 0;
}

int check(string text){
	int i=0;
	for(; i<text.length()-2 ; i+=2){
		if(text[i] == text[i+1] ||(text[i] == 'i' && text[i+1] == 'j')||(text[i] == 'j' && text[i+1] == 'i'))
			return i;
	}
	if (i+1<text.length()){
		if(text[i] == text[i+1] ||(text[i] == 'i' && text[i+1] == 'j')||(text[i] == 'j' && text[i+1] == 'i'))
			return i;
		else return -1;
	}
	else return text.length()-1;
} 

//明文的處理 
//隱患:當字尾是z,或者中間插入之前是z,那就麻煩了 
void K_O(string *str , string z){
	int indi = check(*str);
	if (indi == str->length()-1){
			*str+=z;
			K_O(str , z);
		}
	else if(indi == -1);
	else	
	{	str->insert(indi+1,z);
		K_O(str ,z);
	}
}
<pre name="code" class="cpp">void pfdcp(string et, string pf[5][5] , int alp[3][26] , string nct[]){
	//遍歷密文,每次兩個 
	for(int i = 0 ; i<et.length() ; i+=2){
		//將密文字母轉化為對應字母表的下標 
		int cti1 = (int)et[i];
		cti1-=97;
		int cti2 = (int)et[i+1];
		cti2-=97;

		//逆處理 
		int fline =alp[1][cti1],frow = alp[2][cti1];
		int sline = alp[1][cti2],srow = alp[2][cti2];
		if(fline == sline){//同行,還要判斷是否黏著 
			if(frow - srow == -1){
				nct[i] = pf[fline][(frow+3)%5];//這裡應該是frow-2+5,防止負數 
				nct[i+1] = pf[fline][(frow+4)%5];
			}
			else if (frow - srow == 1){
				nct[i] = pf[fline][(frow+2)%5];
				nct[i+1] = pf[fline][(frow+3)%5];
			}
			else{
				nct[i] = pf[fline][(frow+4)%5];
				nct[i+1] = pf[fline][(srow+4)%5];
			}
		}	
		else if(frow == srow){ //同列,也要判斷是否黏著 
			if(fline - sline == -1){
				nct[i] = pf[(fline+3)%5][frow];
				nct[i+1] = pf[(fline+4)%5][frow];
			}
			else if(fline - sline == 1){
				nct[i] = pf[(fline+2)%5][frow];
				nct[i+1] = pf[(fline+3)%5][frow];
			}
			else{
				nct[i] = pf[(fline+4)%5][frow];
				nct[i+1] = pf[(sline+4)%5][frow];
			}
		}
		else {//不同行列  
			nct[i] = pf[fline][srow];
			nct[i+1] = pf[sline][frow];
		 }
	}
}
<pre name="code" class="cpp">void pfecp(string ct, string pf[5][5] , int alp[3][26] , string eText[]){

	//遍歷明文,每次兩個 
	for(int i = 0 ; i<ct.length() ; i+=2){
		//將明文字母轉化為對應字母表的下標 
		int cti1 = (int)ct[i];
		cti1-=97;
		int cti2 = (int)ct[i+1];
		cti2-=97;
		//判斷是否為j,如果是則改為i 
		if(cti1 == 9)
			cti1-=1;
		else if(cti2 == 9)
			cti2-=1;
		//判斷屬於哪種情況 ,經過明文處理,只有1.同行,2.同列,3.都不同 
		int fline =alp[1][cti1],frow = alp[2][cti1];
		int sline = alp[1][cti2],srow = alp[2][cti2];
		if(fline == sline){//同行,還要判斷是否黏著 
			if(frow - srow == -1){
				eText[i] = pf[fline][(frow+2)%5];
				eText[i+1] = pf[fline][(frow+3)%5];
			}
			else if (frow - srow == 1){
				eText[i] = pf[fline][(frow+1)%5];
				eText[i+1] = pf[fline][(frow+2)%5];
			}
			else{
				eText[i] = pf[fline][(frow+1)%5];
				eText[i+1] = pf[fline][(srow+1)%5];
			}
		}	
		else if(frow == srow){ //同列,也要判斷是否黏著 
			if(fline - sline == -1){
				eText[i] = pf[(fline+2)%5][frow];
				eText[i+1] = pf[(fline+3)%5][frow];
			}
			else if(fline - sline == 1){
				eText[i] = pf[(fline+1)%5][frow];
				eText[i+1] = pf[(fline+2)%5][frow];
			}
			else{
				eText[i] = pf[(fline+1)%5][frow];
				eText[i+1] = pf[(sline+1)%5][frow];
			}
		}
		else {//不同行列  
			eText[i] = pf[fline][srow];
			eText[i+1] = pf[sline][frow];
		 }
	}
}


相關推薦

playfair密碼java實現

這次,使用java來模擬現實playfair密碼加密解密過程 import java.util.HashSet; import java.util.Scanner; public class Test1 { public static char a

PlayFair密碼實現

#include <iostream> #include <string> using std::cout; using std::string; using std::cin; using std::endl; void K_O(strin

密碼學筆記——playfair密碼

bsp 替換 www. style ima www log aik 是把 Playfair密碼(Playfair cipher 或 Playfair square)一種替換密碼,1854年由查爾斯·惠斯通(Charles Wheatstone)的英國人發明。 例題:

appium-手勢密碼實現

str oca 分享圖片 on() const 元素 style app .com 1. 紅色區域的範圍為:[66,575][1014,1523], 由於這塊是一個整塊,所以無法使用每個點的數據;因此只能使用LockPatternView對象拿到左上角的坐標值

Android手勢密碼實現方案

一、大致介面介紹: 圖1 圖2 圖3 圖4 圖1:手勢密碼繪製介面 【主要是繪製上方的9個提示圖示和9個宮格密碼圖示】 圖2:設定手勢密碼 【監聽手勢的輸入,TouchEvent的事件處理,獲取輸入的手勢密碼,同時顯示在上方的提示區域】 圖3

php使用cookie實現記住使用者名稱和密碼實現程式碼

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <form id="form1" name="form1" method="post" action="check_remember.php">

【CTF-Crypto】PlayFair密碼

PlayFair密碼是古典密碼的一種,由一個5*5的矩陣構成金鑰; 為了方便描述,加密與解密的過程,這裡引用一道實驗吧的題目; http://www.shiyanbar.com/ctf/1852 給出的密文是:The quick brown fox jumps over t

電信 光纖貓 貝爾E8-C-EPON 破解超級管理員密碼 實現PPPoE自動撥號和無線路由功能

電信裝寬頻都會送一個光纖貓,但是會把你之前的路由器收回去。上一篇文章已經說了如何從客戶端入手,讓手機進行WiFi連線併成功上網。但是那個方法是較為麻煩且並不徹底的,沒有什麼普適性。現在就來說下徹底解決電信寬頻的這個問題的方法。 一、基本概念 首先以我淺薄的學識說點基本概念,想知道具體的專業的解說,請自

【阿庫婭教你X程式碼】PlayFair密碼——0

大家好,我是,據說是司掌水的女神,當然也是美貌與智慧並重。今天要講的正是密碼學課本上大部分弱智的古典密碼中稍微有趣一點點而且還挺使用的PlayFair密碼! PlayFair密碼演算法的主要構成:金鑰、PlayFair代換表(PF表)、(約定的)填充字母、

(轉)IIS中FTP設定使用者和密碼 實現多使用者管理

  測試一下:這裡以IP為192.168.0.16為例,輸入FTP://192.168.0.16,回車,提示輸入使用者和密碼,輸入FTP01及其密碼,順利進入,這時進入的只能是FTP01虛擬目錄,可以上傳一個檔案,然後在伺服器上檢視一下是放置在哪個目錄下就可判定了。同樣,以FTP02登入,就進入了FTP02目

Linux系統搭建Git伺服器,新增使用者名稱密碼實現多使用者管理

昨天老大分配工作,要在Linux系統上搭建Git伺服器。知識不夠,百度、部落格來湊,折騰了一天,終於搞定了。寫篇部落格,記錄下來,炫耀一下也給日後工作留點方便。安裝git,使用yum源線上安裝yum install -y git初始化git倉庫,在/home/data/git

輸入賬號 密碼 實現登錄功能

alt win black reg 頁面 div pos 直接 lse 當實現用戶的賬戶和密碼輸入正確之後,頁面跳轉 跳轉 使用window.loacation.href ="網址", 這個時候 那個登錄的地方有個 賬號和密碼 這個是怎麽做到的呢? 現在有個方法是:

C++:順序表類實現約瑟夫問題_密碼不同

class josephus main clu 定義 void seq esp while //.h #pragma once#include <iostream>using namespace std;#define MAXSIZE 100 template

Laravel實現用戶名或密碼登錄

字符串 變量 div style 函數 blog var use 登錄 要實現用戶名或密碼登錄,這就要用到強大的filter_var函數該函數通過指定的過濾器過濾變量,可以判斷輸入值是否是數字、是否是字符串、是否是郵箱、是否是IP等等,不用寫麻煩的正則 $type = f

centos6.8+openvpn實現賬戶密碼連接

說明 文件的 persist exist base span htm sig 更改 #搭建openvpn(編譯安裝) 初始化環境 #update epel mirror yum install wget -y cd /etc/yum.repos.d &&

C++實現密碼強度測試

謝謝 break 差距 font class src com 密碼強度檢測 return 最近在博客中看到許多用js寫的密碼強度檢測,我覺得挺有意思的,所以呢我打算自己也寫個來玩玩,最可悲的是我還沒學js,當然這不重要,所以呢打算用C++來寫一個密碼強度檢測,這裏我來給大家

凱撒密碼加密解密--JAVA實現(基礎)

soft ring java實現 sta 想是 clas pub sof print 凱撒密碼一種代換密碼,據說凱撒是率先使用加密函的古代將領之一,因此這種加密方法被稱為愷撒密碼。凱撒密碼的基本思想是:通過把字母移動一定的位數來實現加密和解密。明文中的所有字母都在字母表上向

用cookie實現記住用戶名和密碼

get username parameter space 服務 png value min put 1、當第一次發送請求時,在jsp頁面並不能獲取cookie對象,第一次是addCookie,之後再請求時才能獲得。 session和sessionid在服務器端生成的時候,同

利用qemu-guest-agent實現重置密碼的功能(測試中)

com install rpm etc cnblogs tps 1-1 利用 sta Windows虛擬機: 1.在宿主機上操作: wget https://fedorapeople.org/groups/virt/virtio-win/virtio-win.repo

忘記root密碼後怎麽解決?克隆虛擬機後如何實現兩臺linux相互登錄?

克隆 登錄 遠程 linux 使用單用戶模式破解更改root密碼:1、如果忘記linux的root密碼,可以進入單用戶模式更改root密碼,首先我們重啟虛擬機,操作如下:2、重啟系統後,3秒鐘內按向下的方向鍵,讓它停留在開機界面,如下圖:3、按方向鍵停留在第一行,按字母e編輯它,然後進入另外