征求最好的算法(100)

skp000 2003-10-08 10:24:18
下面是题目的介绍以及题目本身,最后给出了我的算法,最常见的那种.想看看大家的想法,想找出更好的算法来,如果想出来了,可以和大家分享一下吗?

=========================================================================
INTRODUCTION
Ciphers are used to produce messages which can be understood only by the sender and authorized receivers, so ciphers can be used for secret correspondence in situations where the message may fall into the wrong hands. The process of converting a readable message (the plaintext) to an unreadable form (the ciphertext) is called “encryption”; converting ciphertext to plaintext is called “decryption”.
The Vigenere cipher was developed by Biaise de Vigenere around 1586, for French diplomatic and military communications. The Vigenere cipher uses a keyword and a 26-by-26 matrix of letters to substitute plaintext letters with ciphertext letters, and vice versa. The message sender and receiver must both use the same matrix and keyword. For this experiment, the matrix will be:
a b c d e f g h i j k l m n o p q r s t u v w x y z
a A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
b B C D E F G H I J K L M N O P Q R S T U V W X Y Z A
c C D E F G H I J K L M N O P Q R S T U V W X Y Z A B
.... .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
.... .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
z Z A B C D E F G H I J K L M N O P Q R S T U V W X Y


The matrix contains the (uppercase) ciphertext letters. The lowercase letters are the row and column indices.
To encrypt a plaintext letter:
1. The plaintext letter is matched with a keyword letter, as shown below.
2. The keyword letter determines the ROW of the matrix. Find the row that begins with the keyword letter.
3. The plaintext letter determines the COLUMN of the matrix.
4. The ciphertext letter is found at the intersection of ROW and COLUMN.
For example, if the keyword is “calculus” and the plaintext is “beammeupscotty”:
Keword: calculus
Plaintext: beammeupscotty
The ciphertext will be “DELOGPOHUCZVNJ”.
The first plaintext letter, ‘b’, is matched with the first keyword letter, ‘c’, so the first ciphertext letter, ‘D’,
is found in the matrix at row ‘c’, column ‘b’. The second ciphertext letter, ‘E’, is found at row ‘a’, column
‘e’, etc.
To decrypt a message, the processs is reversed. The ciphertext is matched with the same keyword as
was used in the encryption. As before, a keyword letter determines a row of the matrix. To decrypt a
ciphertext letter:
1. Match the ciphertest letter to a keyword letter.
2. Search the row corresponding to the keyword letter, then locate the ciphertext letter.
3. Find the index of the column in which the ciphertext letter appears. The column index is the plaintext
letter that corresponds to the given ciphertext letter.

=========================================================================


Write an interactive program to:
· Allow the user to enter a keyword of 20 characters or less.
· Encrypt a plaintext message of 80 characters or less, using the method described above with the keyword supplied by the user.
· Decrypt a ciphertext message of 80 characters or less, using the method described above with the keyword supplied by the user.

· You should print ciphertext in uppercase letters.
Test case:
· Use the keyword “zygote”, encrypt “zoology” and “aardvark” (separately).
· Use the same keyword “zygote”, decrypt “YSIQAMMG” and “ZPIVTINNZSKCW”.
· Exit the program.
· Use the keyword “apple”, encrypt “zeppelin” and decrypt “ZNBFVGN”.


#########################################################################
#include <stdio.h>

void encrypt(char str1[], char str2[]);
void decrypt(char str1[], char str2[]);
int length(char str[]);

main (void)
{
int choice;
char str1[20];
char str2[80];
char str3[80]; /*variable declaration*/

printf("Enter a keyword: ");
gets(str1);

do {
printf("You have the following options:\n");
printf("1: encrypt a plaintext message\n");
printf("2: decrypt a ciphertext message\n");
printf("3: quit the program\n"); /*declare different kinds of choices*/
printf("Enter the number of your choice=>");
scanf("%d", &choice); /*user select choice*/
fflush(stdin);

switch(choice){
case 1: printf("Enter a line of text (only lowercase letters and are valid): ");
gets(str2);
printf("\tplaintext = %s \n", str2);
printf("\tciphertext = ");
encrypt(str1,str2);
break;
case 2: printf("Enter a line of text: ");
gets(str3);
printf("\tplaintext = %s \n", str3);
printf("\tciphertext = ");
decrypt(str1,str3);
break;
case 3: printf("Program is terminating......\n");
break;
}
}while(choice<=2); /*user call these choices*/
return 0;

}

void encrypt(char str1[], char str2[])
{
char str[26][26];
int i,j,x;
int m, n;

for(i=0;i<26; i++){
for(j=0;j<26; j++){
str[i][j]='A'+(i+j)%26;}}
m=length(str1);
n=length(str2);
for(x=0;x<n;x++){
printf("%c", str[str2[x]-97][str1[x%m]-97]);}
printf("\n");

}

void decrypt(char str1[], char str2[])
{
char str[26][26];
int i,j, x;
int m,n;

for(i=0;i<26; i++){
for(j=0;j<26; j++){
str[i][j]='a'+(26+i-j)%26;;}}
m=length(str1);
n=length(str2);
for(x=0; x<n;x++)
printf("%c", str[str2[x]-65][str1[x%m]-97]);
printf("\n");

}

int length(char str[])
{
int count =0;
while(str[count]!='\0')
count++;
return count;
}
#########################################################################
...全文
137 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
Andy84920 2003-10-11
  • 打赏
  • 举报
回复
唉, 还是红星的厉害啊.

收藏一下,回来研究!
skp000 2003-10-11
  • 打赏
  • 举报
回复
ft,don't where to add value to replyer....
TianGuangZao 2003-10-09
  • 打赏
  • 举报
回复
很有意思的练习,可惜给的程序没法正常运行。
liao2001 2003-10-09
  • 打赏
  • 举报
回复
sorry,my english is pool !!!
stcrane1228 2003-10-09
  • 打赏
  • 举报
回复
学习ing……
JetGeng 2003-10-09
  • 打赏
  • 举报
回复
Ciphers are used to produce messages which can be understood only by the sender and authorized receivers(这是一个加密程序,通过他加密的信息只有发送者和授权接收者才有权阅读), so ciphers can be used for secret correspondence in situations where the message may fall into the wrong hands.(因此该程序可用于可能被别人截获但需要保密的场合) The process of converting a readable message (the plaintext) to an unreadable form (the ciphertext) is called “encryption”;(从明文-可阅读,到暗文-不可阅读的过程叫做编码) converting ciphertext to plaintext is called “decryption”.(从暗文到明文的过程叫做解码)
Vigenere 加密程序是Biaise de Vigenere在1586前后为用于法国的外交和军事而开发的。该加密算法用一个密匙(keyword)和一个26*26的字符矩阵来用暗文来替换明文,反之也可。发送者和授权接收者一定要使用同样的密匙(keyword)和字符矩阵。为了说明矩阵为如下结构
The Vigenere cipher was developed by Biaise de Vigenere around 1586, for French diplomatic and military communications. The Vigenere cipher uses a keyword and a 26-by-26 matrix of letters to substitute plaintext letters with ciphertext letters, and vice versa. The message sender and receiver must both use the same matrix and keyword. For this experiment, the matrix will be:
a b c d e f g h i j k l m n o p q r s t u v w x y z
a A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
b B C D E F G H I J K L M N O P Q R S T U V W X Y Z A
c C D E F G H I J K L M N O P Q R S T U V W X Y Z A B
.... .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
.... .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
z Z A B C D E F G H I J K L M N O P Q R S T U V W X Y

这个矩阵包括暗文(大写字母),小写字母用来表示行和列
The matrix contains the (uppercase) ciphertext letters. The lowercase letters are the row and column indices.
下面是加密的算法
To encrypt a plaintext letter:
明文字符与密匙(keyword)字符匹配,
1. The plaintext letter is matched with a keyword letter, as shown below.
与明文匹配的密匙(keyword)字符决定了矩阵的行(看行号-表示行的小写字母与密匙(keyword)字符是否相等)。
2. The keyword letter determines the ROW of the matrix. Find the row that begins with the keyword letter.
明文字符决定了矩阵的列
3. The plaintext letter determines the COLUMN of the matrix.
由行和列所确定的字符就是该明文所对应的暗文
4. The ciphertext letter is found at the intersection of ROW and COLUMN.
例如:密匙(keyword)为“calculus” 明文为“beammeupscotty”
For example, if the keyword is “calculus” and the plaintext is “beammeupscotty”:
Keword: calculus
Plaintext: beammeupscotty
那么该暗文为“DELOGPOHUCZVNJ”
小弟学着翻了一下,由于是上班时间翻了一部分,请见谅
differ1 2003-10-09
  • 打赏
  • 举报
回复
收藏
cnxiaohai 2003-10-09
  • 打赏
  • 举报
回复
强人哥哥,帮我翻译一下好啊?
TianGuangZao 2003-10-09
  • 打赏
  • 举报
回复
算法没什么好讲的,本身题目已经把算法解释的很清楚,对应的加密解密函数写不出什么名堂来。
关键是搂主给的程序,漏洞很多,应该是如何帮他完善。

比如 gets 函数是很不安全的,是该被丢弃的东西。比较好的方法是用 fgets + sscanf 来代替它。
fflush(stdin) 属于未定义行为,除了极个别编译器标新立异外,本身没有可移植性,比如在 linux gcc 环境下,它不起作用,导致程序没法正常运行,一个解决方法是用 void __fpurge(FILE *stream); 但同样该函数只适合 linux 和 BSD,也不具有可移植性。通用的办法就是自己写一个清空输入缓冲区中多余字符函数,并保证它的可移植性,这是有一定难度的。

"不一定非要设置成全局变量。搂主的写法是不需要的。
----------------------------------------------
那你怎么写呢??"

请看楼主的程序,使用的是局部自动数组,直接从被调用函数中打印结果。
skp000 2003-10-09
  • 打赏
  • 举报
回复
不一定非要设置成全局变量。搂主的写法是不需要的。
----------------------------------------------
那你怎么写呢??
skp000 2003-10-09
  • 打赏
  • 举报
回复
把建立矩阵的语句提到主函数的初始化的地方。
for(i=0;i<26; i++){
for(j=0;j<26; j++){
str[i][j]='A'+(i+j)%26;}

}

char str[26][26];
设成全局变量。
--------------------------------------------------------------
那算法还是没有什么变化啊

我还想过下面这种方法
char matrix[26][26];
char key[20], string[80];
int choice;
int row, col;

for ( row = 0;row < 26;row ++ ){
for ( col = 0;col < 26;col ++ ){
if ( row + col < 26){
matrix[row][col] = 97 + row + col ;}
else if ( row + col >= 26 ){
matix[row][col] = 97 + row + col - 26; } } }
不过程序没有写完.....
wxyking 2003-10-09
  • 打赏
  • 举报
回复


互相学习
TianGuangZao 2003-10-09
  • 打赏
  • 举报
回复
不一定非要设置成全局变量。搂主的写法是不需要的。
hyifeng 2003-10-09
  • 打赏
  • 举报
回复
不建立距阵
直接计算:

'A' + ( char1 - 'a' ) + ( char2 - 'a' )
甚至简化如下:

char1 + char2 - 129
huigll 2003-10-09
  • 打赏
  • 举报
回复
把建立矩阵的语句提到主函数的初始化的地方。
for(i=0;i<26; i++){
for(j=0;j<26; j++){
str[i][j]='A'+(i+j)%26;}

}

char str[26][26];
设成全局变量。
playboyxp 2003-10-08
  • 打赏
  • 举报
回复
英语?
晕!!!

69,335

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧