中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 搜索 | 上传 | 帮助 »
中国DOS联盟论坛 » DOS开发编程 & 发展交流 (开发室) » [分享]我写的ROT13加编/解码程序!
作者:
标题: [分享]我写的ROT13加编/解码程序! 上一主题 | 下一主题
bush
银牌会员




积分 2165
发帖 730
注册 2004-4-21
状态 离线
『楼 主』:  [分享]我写的ROT13加编/解码程序!

用TC编写,大小9.84kB,可以用来对文本文件加密。大家可以来试一下,看看有没有什么问题,rot13.exe 压缩包 用法是 rot13 源文件 编码文件 但不要使两个参数同名。 ROT13 是一种简单的编码,它把字母分成前后两组,每组13个,编码和解码 的算法相同,仅仅交换字母的这两个部分。 我发现标准的程序无法正确地处理中文,原因好像是几个ctype.h标准函数处理非ASCII字符不太严密 所以我重写了一个,可以处理中文, 以下是源代码: #include int main(int argc,char*argv[]) { FILE *in,*out; char c,tmp; if(argc<3) { printf("SYNTAX: rot13 sourcefile output\n"; exit(1); } in=fopen(argv[1],"r"; if(!in) { printf("cannot open sourcefile!\n"; exit(2); } out=fopen(argv[2],"w"; if(!out) { printf("cannot open output!\n"; exit(3); } while((c=getc(in))+1) if(c&0x40) { tmp=c&0x1f; if(tmp&&tmp0x0d&&tmp<0x1b) putc(c-13,out); else putc(c,out); } else putc(c,out); /*putch(isalpha(c)? tolower(c)<''n''? c+13: c-13: c);*/ return 0; } 

[此贴子已经被作者于2004-6-20 下午 09:05:38编辑过]



2004-6-20 00:00
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
bush
银牌会员




积分 2165
发帖 730
注册 2004-4-21
状态 离线
『第 2 楼』:  

原来的 程序是: main(c){putch(isalpha(c)? tolower(c)<'n'? c+13: c-13: c);} 只处理英文字母!


2004-6-20 00:00
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
Kinglion
铂金会员

痴迷DOS者


积分 5798
发帖 1924
注册 2003-6-20
来自 金獅電腦軟體工作室
状态 离线
『第 3 楼』:  

支持原创!




熟能生巧,巧能生精,一艺不精,终生无成,精亦求精,始有所成,臻于完美,永无止境! 金狮電腦軟體工作室愿竭诚为您服务! QQ群:8393170(定期清理不发言者) 个人网站:www.520269.cn 电子邮件:doujiehui@vip.qq.com 微信公众号: doujiehui
2004-6-20 00:00
查看资料  发送邮件  访问主页  发短消息  网志  OICQ (79207959)  编辑帖子  回复  引用回复
jihao1234567
中级用户




积分 258
发帖 58
注册 2003-10-11
状态 离线
『第 4 楼』:  

唔,楼主强大……但是我不会C………………




奋发向上!!!
2004-6-21 00:00
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
willsort
元老会员

Batchinger


积分 4432
发帖 1512
注册 2002-10-18
状态 离线
『第 5 楼』:  

Re bush:   同 Kinglion 兄,支持原创,本版的优秀代码仍然是"物以稀为贵"的,可惜水平有限,心有余而力不足。   楼主的代码没有什么大问题,只是作为一个加密程序来说,功能还是略显不足了些。再提一个小建议,while((c=getc(in))+1) 我认为还是改为 while((c=getc(in)) != EOF) 好些,因为EOF是标准的一部分,而-1却不是。类似的技巧,虽然可以体现编程者的机智,但仍然少用为妙。   另有一个疑惑,我知道c&0x40是判断字母表以上的字符,但是c&0x1f是什么意思呢?

[此贴子已经被作者于2004-6-21 下午 07:58:35编辑过]





※ Batchinger 致 Bat Fans:请访问 [讨论]批处理编程的异类 ,欢迎交流与共享批处理编程心得!
2004-6-21 00:00
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
bush
银牌会员




积分 2165
发帖 730
注册 2004-4-21
状态 离线
『第 6 楼』:  好!

[
我之所以要用位操作取代标准函数,是因为isalpha(c)和 tolower(c) 在当c是非ascii字符时,会产生不合理的结果。 字母表以上的字符共同点都是第五位为‘1’;但c&0x40还不足以判断字母表的字符,因为还有几个符号第五位也为‘1’;如果像原来的英文程序上,用tolower(c)判断是否小于'n',则会把后面那几个符号误认为是大于'n'的字母。 同时:tolower() 不会对最高位为1的符号(汉字就是)处理;c&0x1f是为了对两种情况(ascii字符和非ascii字符)一视同仁地处理。后面就可以比大小决定是向前rot13还是向后rot13.


2004-6-22 00:00
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
willsort
元老会员

Batchinger


积分 4432
发帖 1512
注册 2002-10-18
状态 离线
『第 7 楼』:  

/* Will Sort 改编注: 本程序根据 “中国DOS联盟之联合DOS论坛 → DOS开发编程 & 发展交流 (开发室) → 浏览:[分享]我写的ROT13加编/解码程序! ”一文中所附的程序改编。欢迎原作者 bush 和其他爱好者提出宝贵意见。 改编摘要: 1,exit函数改为return语句 使用exit需要包含stdlib.h,而return关键字也可实现同样功能; 2,while((c=getc(in))+1)改为while((c=fgetc(in)) != EOF) tc中getc为宏,fgetc为函数,都调用底层io函数,虽然getc较为高效,但是文件 函数惯常使用f为首字母; -1(即 EOF,tc中定义的文本文件结束符的常数, 某些函数读取错误也会返回此 值)的用法不值得鼓励,因为它并非标准c定义的内容,在其他c编译系统中可能出现编 译错误; 3,位运算改为逻辑运算 位运算其高效性值得怀疑;而作者所说的不合理也并非因为ctype函数,而是 char 这个变量类型,几乎所有的IO函数都是返回和调用int 型字符的,因为char 的界限是 0-127,所以getc返回的非ascii值都只保存了其低7位的值,导致作者所说的问题。而 作者所说的对中文的处理似乎并非原文输出,也非对所有中文字符绕转,而只是对某些 中文字符进行处理,这样做的意义何在?这里改用逻辑运算的原因在于,实现此简单的 功能无需付出额外的包含ctype.h的代价。 4,char c,temp改为int c, temp 参见3 5,一些书写风格上的改变 无它,习惯而已。 用TC编写,大小9.84kB,可以用来对文本文件加密。大家可以来试一下,看看有没有什么问 题,rot13.exe 压缩包 用法是 rot13 源文件 编码文件 但不要使两个参数同名。 ROT13 是一种简单的编码,它把字母分成前后两组,每组13个,编码和解码 的算法相同,仅仅交换字母的这两个部分。 我发现标准的程序无法正确地处理中文,原因好像是几个ctype.h标准函数处理非ASCII字符 不太严密 所以我重写了一个,可以处理中文, 以下是源代码: */ #include int main(int argc,char*argv[]) { FILE *in, *out; int c; if (argc= 'a' && c = 'A' && c = 'n' && c = 'N' && c <= 'Z') putc(c-13, out); else putc(c, out); } /*putch(isalpha(c)? tolower(c)<''n''? c+13: c-13: c);*/ return 0; }




※ Batchinger 致 Bat Fans:请访问 [讨论]批处理编程的异类 ,欢迎交流与共享批处理编程心得!
2004-7-11 00:00
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
bush
银牌会员




积分 2165
发帖 730
注册 2004-4-21
状态 离线
『第 8 楼』:  

to Will Sort: 我所说的不用ctype函数,并非只是 因为“char其低7位的值”原因(如果是那样,程序是很好处理的): 举例说明一下: #include int main() { char s[]="你好"; int i=0; char c; for(;i<4;i++) printf("%c %s\n",s,isalpha(s)? " is a letter.":" not letter."; for(i=0;i<4;i++) printf("%c %s\n",s,islower(s)? " is a lowercase letter.":" not a lowercase letter."; for(i=0;i<4;i++) printf("%c %s\n",s,isupper(s)? " is a uppercase letter.":" not a uppercase letter."; return 0; } 上面这段小程式将对两个汉字(四个字符)进行测试——是否字母、是否大写、是否小写: 结果显示: ? is a letter. ? is a letter. ? is a letter. ? is a letter. ? is a lowercase letter. ? is a lowercase letter. ? not a lowercase letter. ? is a lowercase letter. ? is a uppercase letter. ? is a uppercase letter. ? is a uppercase letter. ? is a uppercase letter. 看见了吧,都是字母,且有几个既是大写又是小写! 这种逻辑关系让我大惑不解, 如果再使用 tolower() toupper()函数,则结果更加莫明其妙, 如果有ctype函数实现的原型就好了! 由于汉字超范围的原因:对于高低位的ASCII值都落在0x5b-0x5f、0x7b-0x7f区间的汉字不会发生变化,比例算很小的吧。


2004-7-19 00:00
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
willsort
元老会员

Batchinger


积分 4432
发帖 1512
注册 2002-10-18
状态 离线
『第 9 楼』:  

Re bush:  这两天正在整理我以前发过的旧帖,偶然见到这个未结的话题,重新测试了一下,得出以下结论。  8楼程序的问题恰恰还是出在“char其低7位的值”上。我们知道,C标准未定义char型是否有符号,所以很多编译器的实现(包括TC2),都将char分为了signed char和unsigned char,如果定义时缺省符号修饰关键词,那么与int一样,它被默认为signed char。而上述程序中的char s[]="你好";则正是定义了有符号的字符数组。  此时,问题就很明白了,"你好"二字被拆为4个大于128的字符,分别存入数组s中,但是因为s是有符号的,不能大于128,所以他们被转为负值;而ctype的函数显然对此没有准备,因为其算法大概是通过查询一个长为128/256的整型数组来实现的,数组通过位运算保存了1-128/256每个字符所具有的类型,而查询的字符就是这个数组的下标索引值。那么显然,如果这个下标值为负,结果就成了未定义的,取真值也成了可能。而toupper和tolower也基于类似的原因出错了。  所以,解决它的办法很简单,只有将字符数组的定义前加一个unsigned即可,这也是大多数C编程者经常忽略的修饰符。  至于,你所说的原型,只要查看ctype.h即可得到,录于下方,从中可以很明显的看出其中的算法。
#define _IS_SP 1 /* is space */ #define _IS_DIG 2 /* is digit indicator */ #define _IS_UPP 4 /* is upper case */ #define _IS_LOW 8 /* is lower case */ #define _IS_HEX 16 /* [A-F or [a-f] */ #define _IS_CTL 32 /* Control */ #define _IS_PUN 64 /* punctuation */extern char _Cdecl _ctype[]; /* Character type array */#define isalnum(c) (_ctype[(c) + 1] & (_IS_DIG | _IS_UPP | _IS_LOW)) #define isalpha(c) (_ctype[(c) + 1] & (_IS_UPP | _IS_LOW)) #define isascii(c) ((unsigned)(c) < 128) #define iscntrl(c) (_ctype[(c) + 1] & _IS_CTL) #define isdigit(c) (_ctype[(c) + 1] & _IS_DIG) #define isgraph(c) ((c) >= 0x21 && (c) <= 0x7e) #define islower(c) (_ctype[(c) + 1] & _IS_LOW) #define isprint(c) ((c) >= 0x20 && (c) <= 0x7e) #define ispunct(c) (_ctype[(c) + 1] & _IS_PUN) #define isspace(c) (_ctype[(c) + 1] & _IS_SP) #define isupper(c) (_ctype[(c) + 1] & _IS_UPP) #define isxdigit(c) (_ctype[(c) + 1] & (_IS_DIG | _IS_HEX))#define _toupper(c) ((c) + 'A' - 'a') #define _tolower(c) ((c) + 'a' - 'A') #define toascii(c) ((c) & 0x7f)int _Cdecl tolower(int ch); int _Cdecl toupper(int ch);




※ Batchinger 致 Bat Fans:请访问 [讨论]批处理编程的异类 ,欢迎交流与共享批处理编程心得!
2005-4-12 00:00
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复

请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: