自己写了个程序

系统安装、升级讨论
版面规则
我们都知道新人的确很菜,也喜欢抱怨,并且带有浓厚的Windows习惯,但既然在这里询问,我们就应该有责任帮助他们解决问题,而不是直接泼冷水、简单的否定或发表对解决问题没有任何帮助的帖子。乐于分享,以人为本,这正是Ubuntu的精神所在。
回复
头像
mopperwhite
帖子: 330
注册时间: 2010-05-02 20:25
来自: 柯伊伯带外奥尔特云内轨道与黄道错开的空间站里

自己写了个程序

#1

帖子 mopperwhite » 2011-01-09 22:04

问题一大堆,居然段错误啊~
C的文件输入输出一直纠结
输入的文件地址也不对
求解!!!
这是代码:

代码: 全选

//		MopperWhite的加密软件 bate 0.04
//		请编辑过这个文档的人在文档末端留下您的大名及大致解决的问题或增加的功能作为日志!!别忘了标日期!!!
// 
//      加密bate0.04.c
//      
//      Copyright 2011 MopperWhite email:mopperwhite@gmail.com
//      
//      This program is free software; you can redistribute it and/or modify
//      it under the terms of the GNU General Public License as published by
//      the Free Software Foundation; either version 2 of the License, or
//      (at your option) any later version.
//      
//      This program is distributed in the hope that it will be useful,
//      but WITHOUT ANY WARRANTY; without even the implied warranty of
//      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//      GNU General Public License for more details.
//      
//      You should have received a copy of the GNU General Public License
//      along with this program; if not, write to the Free Software
//      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
//      MA 02110-1301, USA.
//      This program is free software; you can redistribute it and/or modify
//      it under the terms of the GNU General Public License as published by
//      the Free Software Foundation; either version 2 of the License, or
//      (at your option) any later version.
//      
//      This program is distributed in the hope that it will be useful,
//      but WITHOUT ANY WARRANTY; without even the implied warranty of
//      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//      GNU General Public License for more details.
//      
//      You should have received a copy of the GNU General Public License
//      along with this program; if not, write to the Free Software
//      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
//      MA 02110-1301, USA.


#include <stdio.h>
#include <string.h>
#define MAXN 1000000
int myin()
{
	char i;
	printf("本软件暂时不能识别换行(俗称回车)与空格\n本软件能读取的内容长度仅限于%d个字节(%d个汉字)'\n由于算法不同,本软件能解密同一软件加密的数据,当然,您可以自己修改它的源码来更改算法 XD\n",MAXN,MAXN/2);
	printf("请问您想加密文件还是解密文件?\n若加密请输“l”,解密请输“u”,退出请输入“e”\nYou:");
	scanf("%c",&i);
	if(i=='l') return 1;
	else
		if(i=='u') return 2;
		else
			if(i=='e') return 3;
			else
				{
					printf("请再看看上面的提示!!\n");
					return myin();
				}
	return 0;
}
void lock(char *rin,char *passwd,char *filename)
{
	int n=strlen(rin);
	int m=strlen(passwd);
	int i,j=0;
	for(i=0;i<n;i++,j++)
	{
		rin[i]=rin[i]+passwd[j]-43;
		if(j>=m-1) j=-1;
	}
	sprintf(filename,"%s%s",filename,".mout");
	FILE *fn;
	fn=fopen(filename,"w");
	fprintf(fn,"%s",rin);
	fclose(fn);
}
void unlock(char *rin,char *passwd,char *filename)
{
	int n=strlen(rin);
	int m=strlen(passwd);
	int o=strlen(filename);
	char _filename[MAXN];
	int i,j=0;
	for(i=0;i<o-5;i++)
		_filename[i]=filename[i];
	for(i=0;i<n;i++,j++)
	{
		rin[i]=rin[i]-passwd[j]+43;
		if(j>=m-1) j=-1;
	}
	//freopen(_filename,"w",stdout);
	FILE *fn;
	fn=fopen(_filename,"w");
	fprintf(fn,"%s",rin);
	fclose(fn);
}
void myout(char *filename,char *passwd,int jinn)
{
	char c;
	int i;
	char rin[MAXN];
	//printf("以下为处理结果:\n%s",rin);
	printf("\n\n========================我是分割线~=========================\n处理完毕的文件将在软件关闭后被存储在当前目录下\n最后说一下,本软件是开源软件,理论上您应该可以从装它的压缩包里找到源代码\n感谢您的使用~~~~~  XD\n");
	//scanf("%c",&c);
	sprintf(filename,"%s%s","./",filename);
	FILE *_rin;
	_rin=fopen(filename,"r");
	if(_rin==NULL)
	{
		printf("出错:文件不存在\n按回车退出");
		char pp;
		scanf("%c",&pp);
		return;
	}
	for(i=0;!feof(_rin);i++)
	{
		fscanf(_rin,"%c",&c);
		rin[i]=c;
	}
	fclose(_rin);
	if(jinn==1) lock(rin,passwd,filename);
	if(jinn==2) unlock(rin,passwd,filename);
}
int main(void)
{
	printf("***********************************************************\n本软件使用GPL协议发布,您可以随意更改、复制、使用它的源代码\n***********************************************************\n\n");
	char _b[10];
	//char rin[MAXN];
	char filename[MAXN];
	char passwd[MAXN];
	int jinn=myin();
	//printf("%d",myin());
	if(jinn==1) sprintf(_b,"%s","加密");
	else
		if(jinn==2) sprintf(_b,"%s","解密");
		else
			if(jinn==3) return 0;
			else
			{
				printf("起始模块发生未知错误");
				return 0;
			}
	printf("请输入您将要%s的文件放在本软件的运行目录下并输入文件名,输完请按回车:\n",_b);
	scanf("%s",filename);
	printf("请输入密码:");
	//gets(passwd);
    scanf("%s",passwd);
    myout(filename,passwd,jinn);
	//if(jinn==1) lock(rin,passwd);
	//if(jinn==2) unlock(rin,passwd);
	return 0;
}
//软件生来自由!!!!!!!!
//坚定GPL一百年不动摇!!!!

//下面是日志:
//====================Bate0.02===========================================
//备注:0.02版本经过Drazet童鞋的修改与优化,谨此表达感谢!
//同时对MW的编程水平……不发表任何意见……
//重要修正:Drazet童鞋帮助解决了MW的把C存成.cpp的问题以及if后的缩进等不良习惯,同时解决了out函数不能通过编译的问题【要命的*.h啊!!!】
//还有!in和out貌似是被占用的!!
//2011/01/08
//====================Bate0.03==========================================
//MopperWhite将0.02中Drazet优化和修改的部分放进同一个文件= =#(原因么……因为MW不会写*.h……)
//貌似难度不大- -!
//纠正一个错别字~
//修正了一个因为if和else使用不当造成异常退出的BUG
//在注释中要求后面的修改者(别看了,就是你!)写日志~
//增加了文件输出(无效~)
//输入不能有空格的BUG待解决
//今天搞不定中文无法解密的问题,建议用if语句对ASCLL码较大的字符进行特殊处理(>100)
//2011/01/09
//====================Bate0.04====================================
//修改为加密文件
//回车问题依旧……
//把“\n友情提示:OGC伤身体(不要深究它的意思……)”去掉……"OGC"本身很邪恶……
//2011/01/09
以前的在:
viewtopic.php?f=77&t=313241&p=2183178
愿他们残酷,但是永远正义
愿恐惧永远不会主宰他们的行动并愿民族的荣誉在他们心中高于一切
最后,愿他们最终可以理解,为完成我们建立民族社会主义国家的任务,需要数百年时间并需要每一个人永远将共同的利益置于个人利益之上。
----希特勒绝笔
讨厌我的人可以试着点一下
讨厌我的人可以试着点一下2.0bate
头像
wl836960072
帖子: 52
注册时间: 2009-08-05 22:04

Re: 自己写了个程序

#2

帖子 wl836960072 » 2011-01-09 22:06

等考完试有事见偶再看
水一样流淌,树一样成长。。。
头像
wl836960072
帖子: 52
注册时间: 2009-08-05 22:04

Re: 自己写了个程序

#3

帖子 wl836960072 » 2011-01-09 22:06

等考完试有事见偶再看 :em04
水一样流淌,树一样成长。。。
头像
astolia
论坛版主
帖子: 6433
注册时间: 2008-09-18 13:11

Re: 自己写了个程序

#4

帖子 astolia » 2011-01-09 22:33

简单的阅读了这段代码后,我要指出的是:只能加解密纯文本文件是个弱点,fopen时应当用二进制模式,fprintf也不要用"%s",你并不能保证rin-passwd[j]+43或rin-passwd[j]+43的结果不为0

如果不执着于纯粹的跨平台代码的话,使用操作系统相关的函数将文件映射到内存中进行处理效率会高很多。linux下是mmap,windows下是MapViewOfFile
头像
gyteng
帖子: 762
注册时间: 2009-07-02 11:24
来自: SCUT

Re: 自己写了个程序

#5

帖子 gyteng » 2011-01-09 22:41

:em04 加密方法过于简单。
头像
liu滔
帖子: 7212
注册时间: 2010-10-09 23:01

Re: 自己写了个程序

#6

帖子 liu滔 » 2011-01-09 23:12

暂时没空看,还得复习概率论呢~
嘿嘿,我也自己写了个Base64的加密算法,不过只能对从命令行输入的字符串加密,至于关键的源代码嘛~在我的签名所指向的个人博客上有,如果有人要.c文件,我也给…… :em03
头像
liu滔
帖子: 7212
注册时间: 2010-10-09 23:01

Re: 自己写了个程序

#7

帖子 liu滔 » 2011-01-09 23:18

astolia 写了:简单的阅读了这段代码后,我要指出的是:只能加解密纯文本文件是个弱点,fopen时应当用二进制模式,fprintf也不要用"%s",你并不能保证rin-passwd[j]+43或rin-passwd[j]+43的结果不为0

如果不执着于纯粹的跨平台代码的话,使用操作系统相关的函数将文件映射到内存中进行处理效率会高很多。linux下是mmap,windows下是MapViewOfFile

受教了,原来还可以用mmap的啊,下次我也试试,我可不希望我写的程序狂读硬盘找一些小小的文件…… :em20
附件
main.c
自己写的Base64加密算法源代码……
(3.29 KiB) 已下载 3 次
头像
garylao
帖子: 157
注册时间: 2008-05-16 7:32
联系:

Re: 自己写了个程序

#8

帖子 garylao » 2011-01-09 23:21

佩服,俺是写不出那程序来,不管对还是错,

支持啦!!! :em11
头像
astolia
论坛版主
帖子: 6433
注册时间: 2008-09-18 13:11

Re: 自己写了个程序

#9

帖子 astolia » 2011-01-10 0:26

liu滔 写了:暂时没空看,还得复习概率论呢~
嘿嘿,我也自己写了个Base64的加密算法,不过只能对从命令行输入的字符串加密,至于关键的源代码嘛~在我的签名所指向的个人博客上有,如果有人要.c文件,我也给…… :em03
严格来讲你这个只能叫编码,不能叫加密
头像
astolia
论坛版主
帖子: 6433
注册时间: 2008-09-18 13:11

Re: 自己写了个程序

#10

帖子 astolia » 2011-01-10 0:29

自己改着玩的,楼主的问题都解决了

代码: 全选

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MAX_FILENAME_LENGTH 65536
#define MAX_PASSWORD_LENGTH 65536

/*
 * 处理文件加解密
 *
 * 参数:
 *   filename:待处理文件名
 *   passwd:密码
 *   type:操作类型,0为加密,1为解密
 * 返回值:
 *   0:一切正常
 *   1:打开待处理文件失败
 *   2:打开处理后文件失败
 */
int core(char *filename,char *passwd,int type) {
	FILE *fin = fopen(filename, "rb");
	if(fin == NULL) {
		fprintf(stderr, "出错:文件 %s 不存在\n按回车退出", filename);
		fgetc(stdin);
		return 1;
	}

	char wfilename[MAX_FILENAME_LENGTH] = {0};
	if(type == 0) {
		strncpy(wfilename, filename, strlen(filename) + 1);
		strcat(wfilename, ".mout");
	} else {
		filename[strlen(filename) - 5] = 0;
		strncpy(wfilename, filename, strlen(filename));
	}

	FILE *fout = fopen(wfilename, "wb");
	if (fout == NULL) {
		fprintf(stderr, "出错:无法保存处理后的文件\n按回车退出");
		fgetc(stdin);
		return 2;
	}

	fprintf(stdout, "\n\n========================我是分割线~=========================\n处理完毕的文件将在软件关闭后被存储在 %s\n最后说一下,本软件是开源软件,理论上您应该可以从装它的压缩包里找到源代码\n感谢您的使用~~~~~  XD\n", wfilename);

	int plen = strlen(passwd);
	int pi;
	for(pi = 0; pi < plen; pi++) {
		if(type == 1) {
			passwd[pi] -= 43;
		} else {
			passwd[pi] = 43 - passwd[pi];
		}
	}
	pi = 0;
	while(!feof(fin)) {
		fputc(fgetc(fin) + passwd[pi], fout);
		pi++;
		if(pi >= plen) {
			pi = 0;
		}
	}
	fclose(fin);
	fclose(fout);
	return 0;
}


/*
 * 主函数
 *
 * 命令行参数:
 *   参数1:待处理文件,未提供时将询问用户
 *   参数2:密码,未提供时将询问用户
 * 返回值:
 *   0:一切正常
 *   1:打开待处理文件失败
 *   2:打开处理后文件失败
 *   3:缓冲区溢出
 */
int main(int argc, char *argv[]) {
	fprintf(stdout, "***********************************************************\n本软件使用GPL协议发布,您可以随意更改、复制、使用它的源代码\n***********************************************************\n\n");
	fprintf(stdout, "由于算法不同,本软件能解密同一软件加密的数据,当然,您可以自己修改它的源码来更改算法 XD\n");

	char filename[MAX_FILENAME_LENGTH];
	char passwd[MAX_PASSWORD_LENGTH];
	char *stype;
	int type;

	if(argc >= 2) {
		strncpy(filename, argv[1], strlen(argv[1]));
	} else {
		fprintf(stdout, "请输入您将要处理的文件,输完请按回车:\n", stype);
		fscanf(stdin, "%s", filename);
	}

	int len = strlen(filename);
	if(len >= MAX_FILENAME_LENGTH) {
		exit(2);
	}
	if(len > 4 && !strcmp(".mout", &filename[len - 5])) {
		type = 1;
		stype = "解密";
	} else {
		type = 0;
		stype = "加密";
	}

	if(argc >= 3) {
		strncpy(passwd, argv[2], strlen(argv[2]));
	} else {
		fprintf(stdout, "请输入%s密码,最大%d位:", stype, MAX_PASSWORD_LENGTH - 1);
    		fscanf(stdin, "%s", passwd);
	}
	if(strlen(passwd) >= MAX_PASSWORD_LENGTH) {
		exit(2);
	}
    return core(filename, passwd, type);
}
头像
liu滔
帖子: 7212
注册时间: 2010-10-09 23:01

Re: 自己写了个程序

#11

帖子 liu滔 » 2011-01-10 15:30

astolia 写了:
liu滔 写了:暂时没空看,还得复习概率论呢~
嘿嘿,我也自己写了个Base64的加密算法,不过只能对从命令行输入的字符串加密,至于关键的源代码嘛~在我的签名所指向的个人博客上有,如果有人要.c文件,我也给…… :em03
严格来讲你这个只能叫编码,不能叫加密
厄……为什么这么说的?不是都说Base64加密的吗? :em20 :em06
头像
astolia
论坛版主
帖子: 6433
注册时间: 2008-09-18 13:11

Re: 自己写了个程序

#12

帖子 astolia » 2011-01-10 16:07

liu滔 写了: 厄……为什么这么说的?不是都说Base64加密的吗? :em20 :em06
加密的目的是为了保密。base64只是将一种格式的数据转换成另一种格式方便传输而已
头像
mopperwhite
帖子: 330
注册时间: 2010-05-02 20:25
来自: 柯伊伯带外奥尔特云内轨道与黄道错开的空间站里

Re: 自己写了个程序

#13

帖子 mopperwhite » 2011-01-12 21:50

astolia 写了:自己改着玩的,楼主的问题都解决了

代码: 全选

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MAX_FILENAME_LENGTH 65536
#define MAX_PASSWORD_LENGTH 65536

/*
 * 处理文件加解密
 *
 * 参数:
 *   filename:待处理文件名
 *   passwd:密码
 *   type:操作类型,0为加密,1为解密
 * 返回值:
 *   0:一切正常
 *   1:打开待处理文件失败
 *   2:打开处理后文件失败
 */
int core(char *filename,char *passwd,int type) {
	FILE *fin = fopen(filename, "rb");
	if(fin == NULL) {
		fprintf(stderr, "出错:文件 %s 不存在\n按回车退出", filename);
		fgetc(stdin);
		return 1;
	}

	char wfilename[MAX_FILENAME_LENGTH] = {0};
	if(type == 0) {
		strncpy(wfilename, filename, strlen(filename) + 1);
		strcat(wfilename, ".mout");
	} else {
		filename[strlen(filename) - 5] = 0;
		strncpy(wfilename, filename, strlen(filename));
	}

	FILE *fout = fopen(wfilename, "wb");
	if (fout == NULL) {
		fprintf(stderr, "出错:无法保存处理后的文件\n按回车退出");
		fgetc(stdin);
		return 2;
	}

	fprintf(stdout, "\n\n========================我是分割线~=========================\n处理完毕的文件将在软件关闭后被存储在 %s\n最后说一下,本软件是开源软件,理论上您应该可以从装它的压缩包里找到源代码\n感谢您的使用~~~~~  XD\n", wfilename);

	int plen = strlen(passwd);
	int pi;
	for(pi = 0; pi < plen; pi++) {
		if(type == 1) {
			passwd[pi] -= 43;
		} else {
			passwd[pi] = 43 - passwd[pi];
		}
	}
	pi = 0;
	while(!feof(fin)) {
		fputc(fgetc(fin) + passwd[pi], fout);
		pi++;
		if(pi >= plen) {
			pi = 0;
		}
	}
	fclose(fin);
	fclose(fout);
	return 0;
}


/*
 * 主函数
 *
 * 命令行参数:
 *   参数1:待处理文件,未提供时将询问用户
 *   参数2:密码,未提供时将询问用户
 * 返回值:
 *   0:一切正常
 *   1:打开待处理文件失败
 *   2:打开处理后文件失败
 *   3:缓冲区溢出
 */
int main(int argc, char *argv[]) {
	fprintf(stdout, "***********************************************************\n本软件使用GPL协议发布,您可以随意更改、复制、使用它的源代码\n***********************************************************\n\n");
	fprintf(stdout, "由于算法不同,本软件能解密同一软件加密的数据,当然,您可以自己修改它的源码来更改算法 XD\n");

	char filename[MAX_FILENAME_LENGTH];
	char passwd[MAX_PASSWORD_LENGTH];
	char *stype;
	int type;

	if(argc >= 2) {
		strncpy(filename, argv[1], strlen(argv[1]));
	} else {
		fprintf(stdout, "请输入您将要处理的文件,输完请按回车:\n", stype);
		fscanf(stdin, "%s", filename);
	}

	int len = strlen(filename);
	if(len >= MAX_FILENAME_LENGTH) {
		exit(2);
	}
	if(len > 4 && !strcmp(".mout", &filename[len - 5])) {
		type = 1;
		stype = "解密";
	} else {
		type = 0;
		stype = "加密";
	}

	if(argc >= 3) {
		strncpy(passwd, argv[2], strlen(argv[2]));
	} else {
		fprintf(stdout, "请输入%s密码,最大%d位:", stype, MAX_PASSWORD_LENGTH - 1);
    		fscanf(stdin, "%s", passwd);
	}
	if(strlen(passwd) >= MAX_PASSWORD_LENGTH) {
		exit(2);
	}
    return core(filename, passwd, type);
}
强人啊!
话说完全看不懂…………
菜鸟果然还是菜鸟……
谢谢!
最近期末考~
愿他们残酷,但是永远正义
愿恐惧永远不会主宰他们的行动并愿民族的荣誉在他们心中高于一切
最后,愿他们最终可以理解,为完成我们建立民族社会主义国家的任务,需要数百年时间并需要每一个人永远将共同的利益置于个人利益之上。
----希特勒绝笔
讨厌我的人可以试着点一下
讨厌我的人可以试着点一下2.0bate
头像
astolia
论坛版主
帖子: 6433
注册时间: 2008-09-18 13:11

Re: 自己写了个程序

#14

帖子 astolia » 2011-01-12 22:39

mopperwhite 写了: 强人啊!
话说完全看不懂…………
菜鸟果然还是菜鸟……
谢谢!
最近期末考~
就是按你的代码来改的。主要修改点:
1、自动根据文件名称来决定是加密还是解密。
2、可以通过命令行参数接受文件名和密码
3、修改算法,将原来的“将整个文件读入内存 -> 处理 -> 输出全部处理后的数据”改成了“一次读入一个字节数据 -> 处理 -> 输出处理后的字节数据 -> 读取下一个字节”,这样就不必预留大量内存,也去除了文件大小的限制,并防止缓冲区出错
4、修改算法,将加密与解密过程合并,减少不必要的重复计算。
5、将出错信息的printf改成fprintf(stderr),输出到标准错误输出

其他的一些修改基本就是个人习惯了,不管也罢。
另外文件路径的最大长度,windows下ansi系的是255,unicode是65535,linux的也差不多。所以我就将最大长度定为65536了

话说这种加密算法我初中时也写过,想想看都是十几年前的事了
头像
TeliuTe
论坛版主
帖子: 7668
注册时间: 2007-11-25 13:29
系统: 16/18/20/w7
来自: 新疆博乐
联系:

Re: 自己写了个程序

#15

帖子 TeliuTe » 2011-01-12 22:55

先存下,有机会细致地看看
回复