C语言编程问题!很急啊!

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言编程问题!很急啊!相关的知识,希望对你有一定的参考价值。

函数功能对传入的数据使用指定的密钥进行维吉尼亚加密,其算法参见下一页的附录。
函数原型
int Vigenere_cipher(unsigned char* data, int data_length, char* key);
参数
data 待加密数据,其长度由参数data_length指定。返回时,此数组中应该是加密后的数据。
data_length 数据长度(字节数)。
key 密钥是一个\0结尾的字符串,必须全部为字母。
返回值
0 操作成功
1 密钥中包含有非字母的字符
说明
1、密钥长度为0时,函数正常返回0,不加密。
2、明文可以包含任何字符,明文的大写字母遇到密钥是小写的时候,把密钥的小写字母转换为对应的大写, 然后查大写维吉尼亚表生成的还是对应的大写密文, 同理,明文为小写字母的时候遇到密钥是大写的时候,把密钥的大写字母转换为小写字母,然后查小写维吉尼亚表生成的是对应的小写的密文,明文是非字符的时候,保留原来的数据不加密。
简单的说就是: 大小写字母处理后仍保持大小写, 非字母保持不变。
如: 明文:A b a B 1 @ “
密钥:B b B b B b B
密文:B c b C 1 @ “
3、密钥的长度是可以不大于待加密数据的长度的。
请哪位大神帮帮忙!很急啊!

// 关于第三点:密钥的长度是可以不大于待加密数据的长度的。这个有点不太明白,
// 密钥长度好象不能小于加密数据的长度,至于是大于还是等于,好象对处理的结果没有
// 影响,不知道这里专门指出不会大于加密数据的长度,有什么特别的含义吗?

#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;

追问

我也不清楚,题目就是这么说的!

追答

实际上题目说的不清楚,如果需求有问题,还可以问设计者,题目不清楚,难道要问出书的?.....

这里我只能猜了,可能我前面的代码还是有点问题,

"密钥的长度是可以不大于待加密数据的长度的。"意思应该是密钥的长度可以小于或等于数据的长度,又从前面说的"密钥是一个\\0结尾的字符串,必须全部为字母。"推测密钥可以小于数据长度,如果遇到密钥为\\0时,会表示密钥结束了,但是这样又带来了新的问题,当密钥小于数据长度时,要如何处理数据,是不再加密还是别的处理,这些都没说明,所以

建议对下面代码中关于密钥的处理

// 密钥非字母,中断退出返回1
else

nRet = 1;
break; 

改动一下,变为

else if( cKey == '\\0' )

// 如果提前遇到密钥结束符'\\0',则不再处理数据加密,
// 跳出循环
break;

// 最后,再处理即不是字母,也不是结束符'\\0'的情况, 中断退出返回1
else

nRet = 1;
break; 

这样的话,对密钥长度等于数据长度的情况没有影响,对密钥长度小于数据长度的情况,也进行了

处理,就是只加密有密钥部分的明文,不加密后面没有密钥部分的明文,

追问

哦!我们老师出的题,我先看看!谢谢!

追答

大胆假定,只要不违题,应该是正解

=======================================================
强烈建议把之前的程序中关于下面的部分替换一下:

// 密钥非字母,中断退出返回1
else

nRet = 1;
break;

=======================================================
替换为:
else if( cKey == '\0' )

// 如果提前遇到密钥结束符'\0',则不再处理数据加密,
// 跳出循环
break;

// 最后,再处理即不是字母,也不是结束符'\0'的情况, 中断退出返回1
// 实际上都是中断加密,前面的是返回成功0,这里的是返回失败1
else

nRet = 1;
break;

这样处理的话,对密钥长度等于数据长度的情况没有影响,对密钥长度小于数据长度的情况,
也作了处理,只加密有密钥部分的明文,不加密没有密钥部分的明文,

参考技术A //给你一些伪代码你看看,剩下的实现就是基本功的问题了~
int Vigenere_cipher(unsigned char* data, int data_length, char* key)
// check key
if(checkHaveNotChar(key))
return 1;


// set lower
setLower(key, keyLower);
setLower(data, dataLower);

for(keyLower)
// process only letter
if(dataLower[i]<='z' &&  dataLower[i] >='a')
temp1 = dataLower[i] - 'a';
temp2 = 'z'-keyLower[i];
if(temp1 < temp2)
dataLower[i] = keyLower[i] + temp1;
 else
dataLower[i] = 'a' + (temp1 - temp2);




// restore case-sensitive
restore(data, dataLower);

return 0;


void setLower(char *src, char* dest)
for(src)
if(src[i] <='Z' && src[i] >='A')
dest[i] = src[i] -'A' +'a';
 else 
dest[i] = src[i];




void restore(char* data, char* lower)
for(lower)
if(data[i] <= 'z' && data[i] >= 'a')
data[i] = lower[i];

if(data[i] <= 'Z' && data[i] >= 'A')
data[i] = lower[i] - 'a' + 'A';


参考技术B 对你这个维吉尼亚加密不熟,但是根据你的描述,觉得不难实现,主要是不知道你的维吉尼亚表的具体内容。可以的话,你加Q:7147 668 58

Q上把原题全部发给我,应该能很快写完,但是你说的很急就不知道现在来得及否。追问

这个就是原题所以的内容啊!后面的就只有一些历史和算法了!

追答

这个我就不相信你急了,在回答过后,我已经根据描述写好了,只是等你回复。。。

我是对你的密码表存有疑惑,想看看你原题上是不是给出了密码表,我从网上查了一个表,根据这个表来写的算法。有问题加Q百度Hi,问题解决,删Q采纳,谢谢!

追问

这个怎么说啦,你回答的时候我们都已经考试结束了,所以就没来得及回复你,就接着上课去了!

本回答被提问者采纳

C语言 根据输入的年份和月份,判断输出是不是闰年和该月的天数,很急,谢谢!

很急哦...555...
#include<stdio.h>
void main()
int year,b,month,d;
printf("请输入年份:\n");
scanf("%d\n",&year);
if(year%4==0&&year%100==0||year%400==0)
printf("今年是闰年!\n");
d=29;

else
printf("今年不是闰年!");
d=28;

printf("请输入月份:\n");
scanf("%d\n",&b);
if(b==2)
month=d;
if(b==8)
month=31;
if(b%2==0)
month=30;
else month=31;
printf("本月%d天!\n",month);

哪出问题了呀??

//vc6 pass
#include <stdio.h>

int isLeap(int y)

return (y%4==0&&y%100!=0)||(y%400==0);


int days(int y,int m)

switch(m)

case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
return 31;break;
case 4:
case 6:
case 9:
case 11:
return 30;break;
case 2:
if(isLeap(y))

return 29;
break;

else

return 28;
break;

default:return 0;break;



void main()

int year,month;
printf("input year:\n");
scanf("%d",&year);
printf("input month:\n");
scanf("%d",&month);

if(isLeap(year))
printf("是润年\n");
else
printf("不是润年\n");

printf("该月天数是:");
printf("%d\n",days(year,month));
参考技术A int a;
scanf(d%,a);
if(a>0,a%4!=0)
printf("不是闰")
eles
printf("是闰")

判断出是否闰年,月份那个很简单了。用选择语句。
参考技术B 2楼回答的不对

闰年是天文历法上为了补时间上的不刚号
地球绕太阳转是365天5小时48分46秒,所以每4年补一年,同时因为也不是6小时,所以还需要400年去一年。从公元元年开始,那就很简单了。
学过C自己写一下吧
这么懒
参考技术C 书上不是有原题嘛!

以上是关于C语言编程问题!很急啊!的主要内容,如果未能解决你的问题,请参考以下文章

C语言求救,急啊,谢谢了~!

线性方程组求解——C语言程序设计代码,高手们,拜托啦!急急急啊!!!

很急,我用keil写一个C语言子函数,去调用数组,怎么写,例如

用C语言2. 编写栅栏密码算法加密、解密编码程序。。求急啊

C语言 根据输入的年份和月份,判断输出是不是闰年和该月的天数,很急,谢谢!

用C语言来实现DES加密算法(很急)两天内