360问答
求古典密码学的c语言代码
guiyids0033 LV122014-01-16
各位高手小弟急需一个维吉尼亚密码的程序。帮帮忙
满意答案

aa7777777777qq
LV12
2014-01-16
给: 维吉尼亚密码的C语言源代码 设m表示明文序列,k表示密钥序列 #include ctype.h #include stdio.h #include stdlib.h #include string.h #include conio.h void crypt(char m[],char k[],char r[]) { int i,j,s=0; j=strlen(k); for(i=0;m[i];i++) m[i]=tolower(m[i]); for(i=0;m[i];i++) if(isalpha(m[i])) { r[i]=(m[i]-'a'+k[s%j]-'a')%26+'a'; s++;/* s用来跳过明文中的空格字符 */ } else r[i]=m[i]; r[i]=0;/* 密文字符串结束符 */ for(i=0;r[i];i++) r[i]=toupper(r[i]); } void decrypt(char c[],char k[],char m[]) { int i,j,s=0; j=strlen(k); for(i=0;c[i];i++) c[i]=tolower(c[i]); for(i=0;c[i];i++) if(isalpha(c[i])) { m[i]=(c[i]-k[s%j]+26)%26+'a'; s++; } else m[i]=c[i]; m[i]=0; } void main() { char m[]="welcome to my blog.i am bugeyes.";//我这里是赋值了一个固定的字符串为明文序列,你也可以做成用户输入的 char k[]="bugeyeswuyan";//我这里是赋值了一个固定的字符串为密钥序列,你也可以做成用户输入的 char c[80]; char d[80]; system("cls");; crypt(m,k,c); decrypt(c,k,d); puts(m); puts(k); puts(c); puts(d); }
C++编程实现维吉尼亚密码加密解密
编程实现维吉尼亚密码加密解密
要求:用户可以输入密钥
#include
using namespace std;
#define MINCHAR 32
#define CHARSUM 94
char table[CHARSUM][CHARSUM];
bool Init();
bool Encode(char* key, char* source, char* dest);
bool Dncode(char* key, char* source, char* dest);
int main()
{
if(!Init())
{
cout "初始化错误!" endl;
return 1;
}
char key[256];
char str1[256];
char str2[256];
int operation;
while(1)
{
do
{
cout "请选择一个操作:1. 加密; 2. 解密; -1. 退出\n";
cin operation;
}while(operation != -1 operation != 1 operation != 2);
if(operation == -1)
return 0;
else if(operation == 1)//加密
{
cout "请输入密钥:";
cin key;
cout "请输入待加密字符串:";
cin str1;
Encode(key, str1, str2);
cout "加密后的字符串:" str2 endl;
}
else if(operation == 2)//解密
{
cout "请输入密钥:";
cin key;
cout "请输入待解密字符串:";
cin str1;
Dncode(key, str1, str2);
cout "解密后的字符串:" str2 endl;
}
cout endl;
}
return 0;
}
// 初始化维吉尼亚方阵
bool Init()
{
int i, j;
for(i = 0; i CHARSUM; i++)
{
for(j = 0; j CHARSUM; j++)
{
table[j] = MINCHAR + (i + j) % CHARSUM;
}
}
return true;
}
// 加密
// key:密钥
// source:待加密的字符串
// dest:经过加密后的字符串
bool Encode(char* key, char* source, char* dest)
{
char* tempSource = source;
char* tempKey = key;
char* tempDest = dest;
do
{
*tempDest = table[(*tempKey) - MINCHAR][(*tempSource) - MINCHAR];
tempDest++;
if(!(*(++tempKey)))
tempKey = key;
}while(*tempSource++);
dest[strlen(source)] = 0;
return true;
}
// 解密
// key:密钥
// source:待解密的字符串
// dest:经过解密后的字符串
bool Dncode(char* key, char* source, char* dest)
{
char* tempSource = source;
char* tempKey = key;
char* tempDest = dest;
char offset;
do
{
offset = (*tempSource) - (*tempKey);
offset = offset = 0 ? offset : offset + CHARSUM;
*tempDest = MINCHAR + offset;
tempDest++;
if(!(*(++tempKey)))
tempKey = key;
}while(*++tempSource);
dest[strlen(source)] = 0;
return true;
}
// 关于第三点:密钥的长度是可以不大于待加密数据的长度的。这个有点不太明白,
// 密钥长度好象不能小于加密数据的长度,至于是大于还是等于,好象对处理的结果没有
// 影响,不知道这里专门指出不会大于加密数据的长度,有什么特别的含义吗?
#include conio.h
#include stdio.h
// 函数功能
// 对传入的数据使用指定的密钥进行维吉尼亚加密
// 返回值
// 0 操作成功
// 1 密钥中包含有非字母的字符
int Vigenere_cipher( unsigned char* data, int data_length, char* key )
{
int nRet = 0;
int i = 0;
unsigned char cKey, cData;
// 密钥长度不为0时加密,为0则直接返回0
if( key != NULL )
{
while( i data_length )
{
cKey = key[i];
cData = data[i];
// 密钥是字母时,求key在字母表中的相对位置
// 这样,key就不需要再根据数据做大小写转换
if( cKey = 'A' cKey = 'Z' )
{
cKey -= 'A';
}
else if( cKey = 'a' cKey = 'z' )
{
cKey -= 'a';
}
// 密钥非字母,中断退出返回1
else
{
nRet = 1;
break;
}
// 判断一下数据是否为字母,不是字母不加密
if( data[i] = 'A' data[i] = 'Z' )
{
//大写字母的加密处理
if( cData = 'Z' )
{
data[i] = cData + cKey;
}
else
{
data[i] = cData + cKey - 25;
}
}
else if( data[i] = 'a' data[i] = 'z' )
{
//小写字母的加密处理
if( cData = 'z' )
{
data[i] = cData + cKey;
}
else
{
data[i] = cData + cKey - 25;
}
}
// 下一个字符
i++;
}
}
return nRet;
}
// 测试用
int main()
{
unsigned char d[]="AbaB1@";
unsigned char k[]="BbBbBbB";
int n = 6;
printf( "明文:%s\n", d );
printf( "密钥:%s\n", k );
Vigenere_cipher( d, n, (char*)k );
printf( "结果:%s\n", d );
getch();
return 0;
}
我用的是VC++写的:
#include Windows.h
#include string.h
unsigned int HexToDec(const char HexNum[])
{
const char *HexVal="0123456789ABCDEF";
return (unsigned int)(strchr(HexVal,HexNum[0])-HexVal)
*16+(unsigned int)(strchr(HexVal,HexNum[1])-HexVal);
}
void DecToHex(unsigned int DecNum,char HexNum[])
{
const char HexVal[]="0123456789ABCDEF";
unsigned int z = DecNum % 16;
HexNum[1] = HexVal[z];
HexNum[0] = HexVal[(DecNum - z) / 16];
}
LRESULT CALLBACK WinPassProc
(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
static HWND hEditMain;
static HWND hBtnJieMi;
static HWND hBtnJiaMi;
static HWND hPassword;
HINSTANCE hInstance = GetModuleHandle(NULL);
const char *DefText = "此处输入明文或密文。";
const char *HexVal="0123456789ABCDEF";
HDC hDC;
PAINTSTRUCT ps;
DWORD lPass,lText;
PBYTE pPass,pText,pRlt;
LONG iTemp;
switch(uMsg)
{
case WM_CREATE:
hPassword = CreateWindowExA(
WS_EX_NOPARENTNOTIFY | WS_EX_CLIENTEDGE | WS_EX_LEFTSCROLLBAR,
"EDIT",NULL,WS_CHILDWINDOW | WS_VISIBLE | WS_TABSTOP | ES_AUTOHSCROLL,
50,10,630,20,hWnd,(HMENU)102,hInstance,NULL);
hEditMain = CreateWindowExA(
WS_EX_NOPARENTNOTIFY | WS_EX_LEFTSCROLLBAR,"EDIT",DefText,
WS_CHILDWINDOW | WS_VISIBLE | WS_TABSTOP | WS_HSCROLL | WS_VSCROLL |
ES_MULTILINE | ES_WANTRETURN | ES_AUTOHSCROLL | ES_AUTOVSCROLL,
10,40,670,380,hWnd,(HMENU)101,hInstance,NULL);
hBtnJieMi = CreateWindowExA(
0L,"BUTTON","解密",WS_CHILD | WS_VISIBLE | WS_TABSTOP,590,430,90,30,
hWnd,(HMENU)103,hInstance,NULL);
hBtnJiaMi = CreateWindowExA(
0L,"BUTTON","加密",WS_CHILD | WS_VISIBLE | WS_TABSTOP,490,430,90,30,
hWnd,(HMENU)104,hInstance,NULL);
break;
case WM_COMMAND:
if( lParam != NULL LOWORD(wParam) 102 ) {
if( (lPass=SendMessageA(hPassword,WM_GETTEXTLENGTH,0,0)) == 0 ||
(lText=SendMessageA(hEditMain,WM_GETTEXTLENGTH,0,0)) == 0 )
{
MessageBoxA(hWnd,"密码或者处理文本不能为空",
"信息",MB_OK|MB_ICONERROR);
}
else
{
pPass = new BYTE[lPass + 1];
SendMessageA(hPassword,WM_GETTEXT,lPass+1,(LPARAM)pPass);
if(strcmp((PCHAR)pPass,"03025")!=0)
{
switch(LOWORD(wParam))
{
case 104:
pText = new BYTE[lText + 1];
pRlt = new BYTE[lText * 2 + 1];
memset( pRlt, 0, lText * 2 + 1);
SendMessageA(hEditMain,WM_GETTEXT,lText+1,(LPARAM)pText);
for(lText=0;*(pText+lText)!='\0';lText++)
{
iTemp = *(pText+lText) + *(pPass+(lText%lPass));
if (iTemp = 256) iTemp -= 256;
DecToHex((UINT)iTemp,(PCHAR)(pRlt+lText*2));
}
SendMessageA(hEditMain,WM_SETTEXT,0,(LPARAM)pRlt);
delete []pText;
delete []pRlt;
break;
case 103:
if( lText % 2 == 0 )
{
pText = new BYTE[lText + 1];
pRlt = new BYTE[lText / 2 + 1];
memset( pRlt, 0, lText / 2 + 1);
SendMessageA(hEditMain,WM_GETTEXT,lText+1,(LPARAM)pText);
for(lText=0;lTextstrlen((PCHAR)pText);lText+=2)
{
if( strchr(HexVal,*(pText+lText))==NULL ||
strchr(HexVal,*(pText+lText+1))==NULL )
{
MessageBoxA(hWnd,"解密过程中发现非法字符!",
"错误",MB_OK|MB_ICONERROR);
goto EndDecode;
}
iTemp = HexToDec((PCHAR)(pText+lText))
- *(pPass+((lText/2)%lPass));
if (iTemp 0) iTemp += 256;
*(pRlt + lText / 2) = (BYTE)iTemp;
}
SendMessageA(hEditMain,WM_SETTEXT,0,(LPARAM)pRlt);
EndDecode:;
delete []pText;
delete []pRlt;
}
else
{
MessageBoxA(hWnd,"解密数据长为单数",
"错误",MB_OK|MB_ICONERROR);
}
break;
}
}
else
{
//程序自毁代码。
}
delete []pPass;
}
}
break;
case WM_PAINT:
hDC = BeginPaint(hWnd,ps);
SetTextColor(hDC,RGB(255,0,0));
SetBkColor(hDC,NULL);
TextOutA(hDC,10,12,"密码:",6);
EndPaint(hWnd,ps);
break;
case WM_CLOSE:
ShowWindow(hWnd,SW_HIDE);
DestroyWindow(hPassword);
DestroyWindow(hEditMain);
DestroyWindow(hBtnJieMi);
DestroyWindow(hBtnJiaMi);
DestroyWindow(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProcA(hWnd,uMsg,wParam,lParam);
break;
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
WNDCLASSA WndClass;
HWND hWnd;
MSG Msg;
const char *lpClassName = "MainForm2429Ex";
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
WndClass.hCursor = LoadCursor(NULL,IDC_ARROW);
WndClass.hIcon = LoadIcon(NULL,IDI_APPLICATION);
WndClass.hInstance = hInstance;
WndClass.lpfnWndProc = WinPassProc;
WndClass.lpszClassName = lpClassName;
WndClass.lpszMenuName = NULL;
WndClass.style = CS_HREDRAW | CS_VREDRAW;
if( RegisterClassA(WndClass) == NULL ) {
MessageBoxA(NULL,"注册窗口类失败!","信息",MB_OK | MB_ICONERROR);
return 255;
}
hWnd = CreateWindowA(lpClassName,"文本加密器",
WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX
,CW_USEDEFAULT,0,700,500,0,0,hInstance,0);
if( hWnd == NULL ) {
MessageBoxA(NULL,"创建窗口失败!","信息",MB_OK | MB_ICONERROR);
return 254;
}
ShowWindow(hWnd,SW_SHOW);
UpdateWindow(hWnd);
while(GetMessageA(Msg,NULL,0,0))
{
TranslateMessage(Msg);
DispatchMessageA(Msg);
}
return 0;
}
#include stdio.h
#define MINCHAR 32
#define CHARSUM 94
int encode(char* key, char* source, char* dest);
int decode(char* key, char* source, char* dest);
char table[CHARSUM][CHARSUM];
int main()
{
int i, j;
char key[256];
char source[256];
char destination[256];
int operation;
FILE *fp;
/* Initial the Vigenere table */
for(i = 0; i CHARSUM; i++)
for(j = 0; j CHARSUM; j++)
table[i][j] = MINCHAR + (i + j) % CHARSUM;
printf("please choose one operation code:\n");
printf("1. Encode; 2. Decode; Others. Exit.\n");
scanf("%d", operation);
fflush(stdin);
switch (operation)
{
case 1:
printf("please input the key code:\n");
gets(key);
fflush(stdin);
printf("please input the source code you want to encode:\n");
gets(source);
fflush(stdin);
encode(key, source, destination);
printf("after encode is: \n");
printf("%s\n", destination);
fp=fopen("key.txt", "w");
fprintf(fp, "%s", key);
fclose(fp);
fp=fopen("source.txt", "w");
fprintf(fp, "%s", source);
fclose(fp);
fp=fopen("destination.txt", "w");
fprintf( fp, "%s",destination);
fclose(fp);
break;
case 2:
printf("please input the key code:\n");
gets(key);
fflush(stdin);
printf("please input the source code you want to decode:\n");
gets(source);
fflush(stdin);
decode(key, source, destination);
printf("after decode is: \n");
printf("%s\n", destination);
fp=fopen("key.txt", "w");
fprintf(fp, "%s", key);
fclose(fp);
fp=fopen("source.txt", "w");
fprintf(fp, "%s", source);
fclose(fp);
fp=fopen("destination.txt", "w");
fprintf(fp, "%s", destination);
fclose(fp);
break;
default:
return 0;
}
return 0;
}
int encode(char* key, char* source, char* dest)
{
char* tempSource = source;
char* tempKey = key;
char* tempDest = dest;
do
{
*tempDest = table[(*tempKey) - MINCHAR][(*tempSource) - MINCHAR];
tempDest++;
if (!(*(++tempKey)))
tempKey = key;
} while(*tempSource++);
dest[strlen(source)] = '\0';
return 1;
}
int decode(char* key, char* source, char* dest)
{
char* tempSource = source;
char* tempKey = key;
char* tempDest = dest;
char offset;
do
{
offset = (*tempSource) - (*tempKey);
offset = offset = 0 ? offset : offset + CHARSUM;
*tempDest = MINCHAR + offset;
tempDest++;
if (!(*(++tempKey)))
tempKey = key;
} while(*++tempSource);
dest[strlen(source)] = '\0';
return 1;
}
#include stdlib.h
#include stdio.h
#include string.h
#define N 10000
void function(char message[],char key[],int mode); //加解密函数
int main()
{
int choose;
char m[N],key[N];
printf("维吉尼亚加密,请输入1;解密,请输入2:\n");
scanf("%d",choose);
getchar();
if (choose == 1 || choose == 2)
{
if (choose == 1)
printf("输入明文:\n");
if (choose == 2)
printf("输入密文:\n");
gets(m);
printf("输入密钥:\n");
gets(key);
function(m,key,choose);
}
else
printf("输入错误!\n");
return 0;
}
void function(char message[],char key[],int mode) //加解密函数
{
int i, j = 0; //j控制key的轮回
int len_k = strlen(key); //密钥长度
char s[N];
for(i=0; message[i]!='\0'; i++)
{
if(message[i] == 32) //判断空格
s[i]=' ';
else
{
if (mode == 1)
s[i]=(int(message[i]-'a')+int(key[j%len_k]-'a'))%26+97;
if (mode == 2)
s[i]=(int(message[i]-'a')-int(key[j%len_k]-'a')+26)%26+97;
j++;
}
printf("%c",s[i]);
}
printf("\n");
}
gets(l);//不加这句M就输入不了为什么?
是因为没有这句的话,按的回车键就输成m了。
连用两个输入语句时,需要考虑回车键,就像我代码里的getchar()。