1,昨天的作业题经典C语言题型
1将全局区二维字符拷贝到堆中
2将栈区二维字符拷贝到堆中
3合并栈区与全局区的二维字符数组
4把数组排序
5打印堆区的二维数组
6释放堆空间
chunli@Linux:~/high$ cat main.c #include <stdio.h> #include <stdlib.h> #include <string.h> /********** 释放二级指针方式1,只释放堆中内存 ********/ void free_two_level_pointer01(char **p,int num) { if(p == NULL) return ; int i =0; for(i = 0;i<num;i++) { if(p[i] != NULL) { free(p[i]); p[i] = NULL; } } free(p); } /********** 释放二级指针方式2,只释放堆中内存,同时修改实参的值 ********/ void free_two_level_pointer02(char ***p,int count) { int num = 0; if(p == NULL) return ; int i; for(i = 0;i<count;i++)//先释放几个子串的空间 { if(*(p) + i != NULL) { printf("%d 正在释放 %p \n",++num,*( *(p) + i) ); free(*( *(p) + i)); *( *(p) + i) = NULL; } } if(*p != NULL)//再释放存放子串数目的空间 { printf("%d 正在释放 %p \n",++num, *(p) ); free(*p); *p = NULL; } return ; } int sort(char **myp1,int len1,char (*myp2)[30],int len2,char ***myp3,int *len3) { if(myp1 == NULL) return -1; if(myp2 == NULL) return -2; if(myp3 == NULL) return -3; int i =0; int j =0; char **p3 = NULL; p3 = (char **)malloc((len1 + len2) * sizeof(char *));//注意这里面装的是指针 if(p3 == NULL) { return -4; } //把全局区的字符拷贝到堆区 for(i =0;i<len1;i++) { int tmp_len = strlen(myp1[i]) +1; p3[i] = (char *)malloc(tmp_len * sizeof(char)); if(p3 == NULL) { return -4; } strcpy(p3[i],myp1[i]); } //把栈区的字符拷贝到堆区 for(j =0;j<len2;j++,i++) { int tmp_len = strlen(myp2[i]) +1; p3[i] = (char *)malloc(tmp_len * sizeof(char)); if(p3 == NULL) { return -4; } strcpy(p3[i],myp2[j]); } //把结果传回去 *len3 = len1 + len2; //排序 指针 for(i = 0;i<len1 + len2;i++) { for(j = i+1;j<len1 + len2;j++) { if( strcmp(p3[i],p3[j]) > 0 ) { char *tmp_p = p3[i]; p3[i] = p3[j]; p3[j] = tmp_p; } } } //把结果传回去 *myp3 = p3; return 0; } int main() { int ret = 0; int i = 0; char *p1[] = {"aaaa","cccc","bbbb"}; int len1 = sizeof(p1)/sizeof(char *); char p2[3][30] = {"1111","3333","2222"}; int len2 = sizeof(p2)/sizeof(p2[0]); char **p3 = NULL; int len3 = 0; ret = sort(p1,len1,p2,len2,&p3,&len3); if(ret != 0) { printf("ERROR CODE:%d in main.c:sort(p1,len1,p2,len2,&p3,&len3 )\n",ret); return ret; } for(i = 0;i<len3;i++) { printf("%s\n",p3[i]); } free_two_level_pointer02(&p3,len3); return 0; } chunli@Linux:~/high$ 编译运行 chunli@Linux:~/high$ gcc -Wall main.c && ./a.out 1111 2222 3333 aaaa bbbb cccc 1 正在释放 0x20410b0 2 正在释放 0x20410f0 3 正在释放 0x20410d0 4 正在释放 0x2041050 5 正在释放 0x2041090 6 正在释放 0x2041070 7 正在释放 0x2041010 chunli@Linux:~/high$
这是老师的答案
chunli@Linux:~/high$ cat teacher.c #include <stdlib.h> #include <string.h> #include <stdio.h> int sort(char **myp1 /*in*/, int num1, char (*myp2)[30], int num2, char ***myp3, int *num3) { int i = 0, j = 0, k= 0; int tmplen = 0; char **p3 = NULL; char *tmpP = NULL; p3 = (char **)malloc( (num1 + num2) * sizeof(char *) ); //里面装的是指针 if (p3 == NULL) { return -1; } //根据 for (i=0; i<num1; i++) { tmplen= strlen(myp1[i]) + 1; p3[i] = (char *)malloc( tmplen * sizeof(char)) ; if (p3[i] == NULL) { return -2; } strcpy(p3[i], myp1[i]); } for (j=0; j<num2; j++, i++) { tmplen = strlen(myp2[j]) + 1; p3[i] = (char *)malloc (tmplen * sizeof(char)); if (p3[i] == NULL) { return -3; } strcpy(p3[i], myp2[j]); } tmplen = num1 + num2; //*num3 = num1 + num2; //排序 for (i=0; i<tmplen; i++) { for (j=i+1; j<tmplen; j++) { if ( strcmp(p3[i], p3[j]) > 0 ) { tmpP = p3[i]; p3[i] = p3[j]; p3[j] = tmpP; } } } //间接赋值 *num3 = tmplen; *myp3 = p3; return 0; } void sortFree01(char **p, int len) { int i = 0; if (p == NULL) { return ; } for (i=0; i<len ; i++) { free(p[i]); } free(p); } void sortFree02(char ***myp, int len) //把二级指针指向二维内存释放掉,,同时间接的修改了实参的值 { int i = 0; char **p = NULL; if (myp == NULL) { return ; } p = *myp; //还原成二级指针 if (p == NULL) { return ; } for (i=0; i<len ; i++) { free(p[i]); } free(p); //myp 是实参的地址 *myp = NULL; //间接赋值是指针存在的最大意义 } int main() { int ret = 0; char *p1[] = {"aa", "ccccccc", "bbbbbb"}; char buf2[10][30] = {"111111", "3333333", "222222"}; char **p3 = NULL; int len1, len2, len3, i = 0; len1 = sizeof(p1)/sizeof(*p1); len2 = 3; ret = sort(p1, len1, buf2, len2, &p3, &len3); if (ret != 0) { printf("func sort() err:%d \n", ret); return ret; } for (i=0; i<len3; i++) { printf("%s\n", p3[i]); } printf("hello...\n"); return ret; } chunli@Linux:~/high$ 编译 chunli@Linux:~/high$ gcc teacher.c && ./a.out 111111 222222 3333333 aa bbbbbb ccccccc hello... chunli@Linux:~/high$
结构体浅拷贝
chunli@Linux:~/high$ cat main.c #include <stdio.h> #include <stdlib.h> #include <string.h> struct teacher { char name[60]; int age; char *alias_name; }; int main() { struct teacher t1; struct teacher t2; strcpy(t1.name,"chunli"); t1.age = 22; t1.alias_name = (char *)malloc(100); strcpy(t1.alias_name,"chunli_alias"); printf("%s \n",t1.name); printf("%d \n",t1.age); printf("%s \n",t1.alias_name); //t2 = t1; //这两个拷贝方式的效果一样 //编译器的 = 操作只会把指针变量的值 拷贝过去 //但不会把指针指向的内存空间拷贝过去 memcpy(&t2,&t1,sizeof(struct teacher)); printf("%s \n",t2.name); printf("%d \n",t2.age); printf("%s \n",t2.alias_name); if(t1.alias_name != NULL) { free(t1.alias_name); t1.alias_name =NULL; } if(t2.alias_name != NULL) { free(t2.alias_name);//程序会在这里宕掉因为别人已经释放了那片区域 t2.alias_name =NULL; } return 0; } chunli@Linux:~/high$ chunli@Linux:~/high$ chunli@Linux:~/high$ gcc -g main.c && ./a.out chunli 22 chunli_alias chunli 22 chunli_alias *** Error in `./a.out‘: double free or corruption (fasttop): 0x00000000025a8010 *** Aborted (core dumped) chunli@Linux:~/high$
结构体深度拷贝
chunli@Linux:~/high$ cat main.c #include <stdio.h> #include <stdlib.h> #include <string.h> struct teacher { char name[60]; int age; char *alias_name; }; int main() { struct teacher t1; struct teacher t2; strcpy(t1.name,"chunli"); t1.age = 22; t1.alias_name = (char *)malloc(100); strcpy(t1.alias_name,"chunli_alias"); printf("%s \n",t1.name); printf("%d \n",t1.age); printf("%s \n",t1.alias_name); //编译器的 = 操作只会把指针变量的值 拷贝过去 //但不会把指针指向的内存空间拷贝过去 //t2 = t1; //这两个拷贝方式的效果一样 memcpy(&t2,&t1,sizeof(struct teacher)); t2.alias_name = (char*)malloc(100); //为t2 打造内存空间 strcpy(t2.alias_name,t1.alias_name); //深度拷贝 printf("%s \n",t2.name); printf("%d \n",t2.age); printf("%s \n",t2.alias_name); if(t1.alias_name != NULL) { free(t1.alias_name); t1.alias_name =NULL; } if(t2.alias_name != NULL) { free(t2.alias_name);//程序会在这里不会宕掉因为t2有自己的内存空间 t2.alias_name =NULL; } return 0; } chunli@Linux:~/high$ gcc -g main.c && ./a.out chunli 22 chunli_alias chunli 22 chunli_alias chunli@Linux:~/high$ chunli@Linux:~/high$ chunli@Linux:~/high$
结构体高级话题偏移量1
#include <stdio.h> #include <stdlib.h> #include <string.h> struct teacher { char name[60]; int age; char *alias_name; }; int main() { struct teacher t1; struct teacher *p1; p1 -1; p1 -2; p1 -3; p1 - p1; int offsize = (int)&(p1->age); printf("%d\n",offsize); return 0; } 编译 chunli@Linux:~/high$ gcc -g main.c && ./a.out main.c: In function ‘main’: main.c:20:16: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] int offsize = (int)&(p1->age); ^ 1327912356
结构体高级话题偏移量2
#include <stdio.h> #include <stdlib.h> #include <string.h> struct teacher { char name[60]; int age; char *alias_name; }; int main() { struct teacher t1; struct teacher *p1; p1 -1; p1 -2; p1 -3; p1 - p1; //告诉编译器struct teacher *从0到age有多大 int offsize = (int)&(((struct teacher *)0)->age); printf("%d\n",offsize); return 0; } 编译 chunli@Linux:~/high$ gcc -g main.c && ./a.out main.c: In function ‘main’: main.c:21:16: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] int offsize = (int)&(((struct teacher *)0)->age); ^ 60
【文件操作】
// 把字符写入文件
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { FILE *p = fopen("./hello","w"); if(p == NULL) { printf("error in fopen\n"); } char *str = "Hello World!\n"; int i = 0; for(i = 0;i<strlen(str);i++) { fputc(str[i],p); } fclose(p); return 0; } 编译 chunli@Linux:~/high$ gcc -g main.c && ./a.out chunli@Linux:~/high$ cat hello Hello World!
// 读文件
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { FILE *p = fopen("./hello","r+"); if(p == NULL) { printf("error in fopen\n"); } while(!feof(p)) { char c = fgetc(p); printf("%c",c); } if(p != NULL) { fclose(p); } return 0; } chunli@Linux:~/high$ gcc -g main.c && ./a.out Hello World!
// fputs写文件
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { FILE *p = fopen("./hello","r+"); if(p == NULL) { printf("error in fopen\n"); } char *str = "Hello ...\n"; fputs(str,p); if(p != NULL) { fclose(p); } return 0; } 编译运行 chunli@Linux:~/high$ cat hello Hello ... d! 可以看出残缺覆盖
fgets读文件
// fgets读文件 #include <stdio.h> #include <stdlib.h> #include <string.h> int main() { FILE *p = fopen("./hello","r+"); if(p == NULL) { printf("error in fopen\n"); } char buf[1024]; while(!feof(p)) { fgets(buf,1024,p); printf("%s",buf); } if(p != NULL) { fclose(p); } return 0; } Linux下运行 chunli@Linux:~/high$ cat hello 2222222222222222222222 ffffffffffffffffff 3333 chunli@Linux:~/high$ gcc -g main.c && ./a.out 2222222222222222222222 ffffffffffffffffff 3333 3333 不明白为什么会多一行 在win下面就是正常的 网上查了一下linux的feof函数有问题
把结构体写入文件
chunli@Linux:~/high$ cat main.c #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct teacher { char name[64]; int age; }teacher; int main() { FILE *fp = NULL; char *filename = "./hello"; teacher teacher_arr[3]; int i = 0; for(i = 0;i<3;i++) //初始化结构体 { sprintf(teacher_arr[i].name,"%d,%d,%d",i,i+i,i*i); teacher_arr[i].age = i + 30; } fp = fopen(filename,"wb"); //打开文件 if(fp == NULL) { return -1; } for(i = 0;i<3;i++) //写入数据到文件 { size_t write_num = fwrite(&teacher_arr[i],sizeof(teacher),1,fp); if(!write_num) { printf("磁盘满\n"); } } if(fp != NULL) { fclose(fp); } return 0; } chunli@Linux:~/high$ gcc -g main.c && ./a.out chunli@Linux:~/high$ cat hello 0,0,0ɡ .1,2,1-..N=栀戀-..h愀嘂2,4,4@pa-.僻戀-. chunli@Linux:~/high$ Xshell^C chunli@Linux:~/high$ hexdump hello 0000000 2c30 2c30 0030 0000 e1c8 569c 7ff4 0000 0000010 0000 0000 0000 0000 0000 0000 0000 0000 * 0000030 0000 0000 0000 0000 e520 569c 7ff4 0000 0000040 001e 0000 2c31 2c32 0031 0e2d 7ffe 0000 0000050 4e2e f63d 0000 0000 03a4 0040 0000 0000 0000060 ffff ffff 0000 0000 6268 0e2d 7ffe 0000 0000070 51f8 563f 7ff4 0000 b568 569c 7ff4 0000 0000080 e1c8 569c 001f 0000 2c32 2c34 0034 0000 0000090 0001 0000 0000 0000 083d 0040 0000 0000 00000a0 6170 0e2d 7ffe 0000 0000 0000 0000 0000 00000b0 07f0 0040 0000 0000 0570 0040 0000 0000 00000c0 6250 0e2d 7ffe 0000 0020 0000 00000cc chunli@Linux:~/high$
从二进制文件中读取结构体数据
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct teacher { char name[64]; int age; }teacher; int main() { FILE *fp = NULL; char *filename = "./hello"; teacher teacher_arr[3]; int i = 0; fp = fopen(filename,"rb"); //打开文件 if(fp == NULL) return -1; for(i = 0;i<3;i++) //写入数据到文件 { size_t write_num = fread(&teacher_arr[i],sizeof(teacher),1,fp); } if(fp != NULL) fclose(fp); for(i = 0;i<3;i++) //初始化结构体 { printf("%s ->",teacher_arr[i].name); printf("%d \n",teacher_arr[i].age); } return 0; } 编译 chunli@Linux:~/high$ gcc -g main.c && ./a.out 0,0,0 ->30 1,2,1 ->31 2,4,4 ->32 chunli@Linux:~/high$
【C语言 文件项目】
1程序的配置文件
2配置文件信息以key value存放
3应用层 与 底层文件操作分开
4应用层查的时候输入key返回value
5应用层改的时候输入keyvalue。如果key存在就修改。如果key不存在则追加一条记录
我的代码文件
chunli@Linux:~/high$ ll total 36K -rw-rw-r-- 1 chunli chunli 2.6K Jun 21 15:50 cfg_op.c -rw-rw-r-- 1 chunli chunli 340 Jun 21 12:35 cfg_op.h -rw-rw-r-- 1 chunli chunli 1.4K Jun 21 15:49 main.c -rw-r--r-- 1 chunli chunli 34 Jun 21 15:51 mycfg.ini
文件1
chunli@Linux:~/high$ cat cfg_op.h #ifndef __CFG_OP_H__ #define __CFG_OP_H__ #ifdef __cplusplus extern "C"{ #endif int GetCfgItem(char *pFileNmae/*in*/,char *pKey/*in*/,char*pValue/*in out*/,int *pValueLen/*out*/); int WriteCfgItem(char *pFilename/*in*/,char *pItemName /*in*/,char *pItemValue/*in*/,int itemCalueLen/*in*/ ); #ifdef __cplusplus } #endif #endif chunli@Linux:~/high$
文件2
chunli@Linux:~/high$ cat cfg_op.c #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAXline 1024 int GetCfgItem(char *pFileNmae/*in*/,char *pKey/*in*/,char*pValue/*in out*/,int *pValueLen/*out*/) { int ret = 0; FILE *fp = NULL; fp = fopen(pFileNmae,"r+"); if(fp == NULL) { return -1; printf("open file %s error\n",pFileNmae); } char linebuf[MAXline]; while(!feof(fp)) { memset(linebuf,0,1024); char *find = NULL; fgets(linebuf,MAXline,fp); find = strstr(linebuf,pKey); if(find == NULL){continue;} //没找到key find = strstr(linebuf,"="); if(find == NULL){continue;} //也没有"=" find = find + strlen("="); char *p_head = NULL; char *p_tail = NULL; while(1) { if(*find == ‘ ‘) {find++;} else { p_head = find; if(*find == ‘\n‘) { ret = -1; goto End; printf("没有找到 %s 对应的value\n",pKey); } break; } } while(1) { if( (*find == ‘ ‘) || (*find == ‘\n‘) ) { break; } else { *find++; } } p_tail = find; *pValueLen = p_tail - p_head; memcpy(pValue,p_head,p_tail - p_head); } End: fclose(fp); return ret; } int WriteCfgItem(char *pFilename/*in*/,char *pKey /*in*/,char *pValue/*in*/,int ValueLen/*in*/ ) { int ret = 0; int iTag = 0; int leng = 0; char linebuf[MAXline]; FILE *fp = NULL; char *pTmp = NULL; char *pBegin = NULL; char *pEnd = NULL; char filebuf[1024 *8] = {0}; if(pFilename == NULL) {return -1;} if(pKey == NULL) {return -2;} if(pValue == NULL) {return -3;} fp = fopen(pFilename,"r+"); if(fp == NULL) { printf("文件打开失败,正在创建\n"); fp = fopen(pFilename,"w+t"); if(fp == NULL) { ret = -4; printf("文件创建也失败了\n"); goto End; } } fseek(fp,0L,SEEK_END); leng = ftell(fp); fseek(fp,0L,SEEK_SET); if(leng > 1024 * 8) { ret = -5; printf("文件太大了\n"); goto End; } while(!feof(fp)) { memset(linebuf,MAXline,sizeof(linebuf)); pTmp = fgets(linebuf,MAXline,fp); if(pTmp == NULL) { break; } pTmp = strstr(linebuf,pKey); if(pTmp == NULL) { strcat(filebuf,linebuf); continue; } else { sprintf(linebuf,"%s = %s\n",pKey,pValue); strcat(filebuf,linebuf); iTag = 1; } } if(iTag == 0) { fprintf(fp,"%s = %s\n",pKey,pValue); } else { if(fp == NULL) { fclose(fp); fp = NULL; } fp = fopen(pFilename,"w+t"); if(fp == NULL) { ret = -5; printf("ERROR Create file!\n"); goto End; } fputs(filebuf,fp); //fwrtite(filebuf,sizeof(char),strlen(filebuf),fp); } End: if(fp != NULL) { fclose(fp); fp = NULL; } return ret; } chunli@Linux:~/high$
文件3
chunli@Linux:~/high$ cat main.c #include <stdio.h> #include <stdlib.h> #include <string.h> #include "cfg_op.h" char *filename = "mycfg.ini"; void printf_menu() { printf("\t\t*********************************\n"); printf("\t\t[1]读配置文件\n"); printf("\t\t[2]写配置文件\n"); printf("\t\t[0]退出\n"); printf("\t\t*********************************\n"); } int TGetCfg() { char name[1024] = {0}; char valude[1024] = {0}; int vlen = 0; printf("进入读文件模式\n"); printf("请输入key "); scanf("%s",name); int ret = GetCfgItem(filename,name,valude,&vlen); if(ret != 0) { printf("ERROR in GetCfgItem \n"); return ret; } printf("读取结果%s -> %s \n",name,valude); return ret; } int TWriteCfg() { char name[1024] = {0}; char valude[1024] = {0}; printf("进入配置文件的修改或添加模式\n"); printf("请输入key valude: "); scanf("%s %s",name,valude); int ret = WriteCfgItem(filename,name,valude,strlen(valude)); if(ret != 0) { printf("ERROR in WriteCfgItem \n"); return ret; } printf("您的输入是:%s -> %s \n",name,valude); return ret; } int main() { int choice_num; while(1) { printf_menu(); scanf("%d",&choice_num); switch(choice_num) { case 0: exit(0); case 1: TGetCfg(); break; case 2: TWriteCfg(); break; default: exit(0); } } return 0; } chunli@Linux:~/high$
编译运行
chunli@Linux:~/high$ gcc -g -o run main.c cfg_op.c && ./run ********************************* [1]读配置文件 [2]写配置文件 [0]退出 ********************************* 1 进入读文件模式 请输入key 1 读取结果1 -> 2 ********************************* [1]读配置文件 [2]写配置文件 [0]退出 ********************************* 2 进入配置文件的修改或添加模式 请输入key valude: 1 haha 您的输入是:1 -> haha ********************************* [1]读配置文件 [2]写配置文件 [0]退出 ********************************* 1 进入读文件模式 请输入key 1 读取结果1 -> haha ********************************* [1]读配置文件 [2]写配置文件 [0]退出 ********************************* 0 chunli@Linux:~/high$
上面这道题老师的代码VS环境编译
文件1cfg_op.h
#ifndef __CFG_OP_H__ #define __CFG_OP_H__ #ifdef __cplusplus extern "C" { #endif //获取配置项 int GetCfgItem(char *pFileName /*in*/, char *pKey /*in*/, char * pValue/*in out*/, int * pValueLen /*out*/); //写配置项 int WriteCfgItem(char *pFileName /*in*/, char *pItemName /*in*/, char *pItemValue/*in*/, int itemValueLen /*in*/); #ifdef __cplusplus } #endif #endif
文件2
cfg_op.c
#define _CRT_SECURE_NO_WARNINGS #include <stdlib.h> #include <string.h> #include <stdio.h> #define MaxLine 2048 //获取配置项 int GetCfgItem(char *pFileName /*in*/, char *pKey /*in*/, char * pValue/*in out*/, int * pValueLen /*out*/) { int ret = 0; FILE *fp = NULL; char *pTmp = NULL, *pEnd = NULL, *pBegin = NULL; char lineBuf[MaxLine]; fp = fopen(pFileName, "r"); if (fp == NULL) { ret = -1; return ret; } while (!feof(fp)) { memset(lineBuf, 0, sizeof(lineBuf)); //fgets(_Out_z_cap_(_MaxCount) char * _Buf, _In_ int _MaxCount, _Inout_ FILE * _File); fgets(lineBuf, MaxLine, fp); //printf("lineBuf:%s ",lineBuf ); pTmp = strchr(lineBuf, ‘=‘); // if (pTmp == NULL) //没有=号 { continue; } pTmp = strstr(lineBuf, pKey); if (pTmp == NULL) //判断key是不是在 //所在行 是不是有key { continue; } pTmp = pTmp + strlen(pKey); //mykey1 = myvalude11111111 ==> "= myvalude1111111" pTmp = strchr(pTmp, ‘=‘); if (pTmp == NULL) //判断key是不是在 //所在行 是不是有key { continue; } pTmp = pTmp + 1; // //printf("pTmp:%s ", pTmp); //获取value 起点 while (1) { if (*pTmp == ‘ ‘) { pTmp ++ ; } else { pBegin = pTmp; if (*pBegin == ‘\n‘) { //没有配置value //printf("配置项:%s 没有配置value \n", pKey); goto End; } break; } } //获取valude结束点 while (1) { if ((*pTmp == ‘ ‘ || *pTmp == ‘\n‘)) { break; } else { pTmp ++; } } pEnd = pTmp; //赋值 *pValueLen = pEnd-pBegin; memcpy(pValue, pBegin, pEnd-pBegin); } End: if (fp == NULL) { fclose(fp); } return 0; } //写配置项 //实现流程 //循环读每一行检查key配置项是否存在 若存在修改对应value值 //若不存在在文件末尾 添加 "key = value" //难点如何修改文件流中的值 int WriteCfgItem(char *pFileName /*in*/, char *pKey /*in*/, char * pValue/*in*/, int ValueLen /*in*/) { int rv = 0, iTag = 0, length = 0; FILE *fp = NULL; char lineBuf[MaxLine]; char *pTmp = NULL, *pBegin = NULL, *pEnd = NULL; char filebuf[1024*8] = {0}; if (pFileName==NULL || pKey==NULL || pValue==NULL) { rv = -1; printf("SetCfgItem() err. param err \n"); goto End; } fp = fopen(pFileName, "r+"); if (fp == NULL) { rv = -2; printf("fopen() err. \n"); //goto End; } if (fp == NULL) { fp = fopen(pFileName, "w+t"); if (fp == NULL) { rv = -3; printf("fopen() err. \n"); goto End; } } fseek(fp, 0L, SEEK_END); //把文件指针从0位置开始移动到文件末尾 //获取文件长度; length = ftell(fp); fseek(fp, 0L, SEEK_SET); if (length > 1024*8) { rv = -3; printf("文件超过1024*8, nunsupport"); goto End; } while (!feof(fp)) { //读每一行 memset(lineBuf, 0, sizeof(lineBuf)); pTmp = fgets(lineBuf, MaxLine, fp); if (pTmp == NULL) { break; } //key关键字是否在本行 pTmp = strstr(lineBuf, pKey); if (pTmp == NULL) //key关键字不在本行 copy到filebuf中 { strcat(filebuf, lineBuf); continue; } else //key关键在在本行中替换旧的行再copy到filebuf中 { sprintf(lineBuf, "%s = %s\n", pKey, pValue); strcat(filebuf, lineBuf); //若存在key iTag = 1; } } //若key关键字不存在 追加 if (iTag == 0) { fprintf(fp, "%s = %s\n", pKey, pValue); } else //若key关键字存在则重新创建文件 { if (fp != NULL) { fclose(fp); fp = NULL; //避免野指针 } fp = fopen(pFileName, "w+t"); if (fp == NULL) { rv = -4; printf("fopen() err. \n"); goto End; } fputs(filebuf, fp); //fwrite(filebuf, sizeof(char), strlen(filebuf), fp); } End: if (fp != NULL) { fclose(fp); } return rv; }
文件3
#define _CRT_SECURE_NO_WARNINGS #include <stdlib.h> #include <string.h> #include <stdio.h> #include "cfg_op.h" #define CFGNAME "c:/mycfg.ini" void mymenu() { printf("=============================\n"); printf("1 测试写配置文件\n"); printf("2 测试读配置文件\n"); printf("0 退出\n"); printf("=============================\n"); } //获取配置项 int TGetCfg() { int ret = 0; //读配置项 char name[1024] = {0}; char valude[1024] = {0}; int vlen = 0; printf("\n请键入key:"); scanf("%s", name); ret = GetCfgItem(CFGNAME /*in*/, name /*in*/, valude/*in*/, &vlen); if (ret != 0) { printf("func WriteCfgItem err:%d \n", ret); return ret; } printf("valude:%s \n", valude); } //写配置项 int TWriteCfg() { int ret = 0; //写配置项 char name[1024] = {0}; char valude[1024] = {0}; printf("\n请键入key:"); scanf("%s", name); printf("\n请键入valude:"); scanf("%s", valude); ret = WriteCfgItem(CFGNAME /*in*/, name /*in*/, valude/*in*/,strlen(valude) /*in*/); if (ret != 0) { printf("func WriteCfgItem err:%d \n", ret); return ret; } printf("你的输入是%s = %s \n", name , valude); return ret; } void main() { int choice; for (;;) { //显示一个菜单 mymenu(); scanf("%d", &choice); switch (choice) { case 1: //写配置项 TWriteCfg(); break; case 2: TGetCfg(); //读配置项 break; case 0: exit(0); default:; exit(0); } } printf("hello...\n"); system("pause"); return ; }
文件专业加密:
VS编译OK
GCC编译不正常。
4个文件:
文件1:des.h
/********************************************************* * des.h * 用户使用des算法头文件 * *********************************************************/ #ifndef _OPENDESS_H_ #define _OPENDESS_H_ #ifdef __cplusplus extern "C" { #endif //ab\0defg //用户使用的函数 int DesEnc( unsigned char *pInData, int nInDataLen, unsigned char *pOutData, int *pOutDataLen); //用户使用函数des解密 int DesDec( unsigned char *pInData, int nInDataLen, unsigned char *pOutData, int *pOutDataLen); #ifdef __cplusplus } #endif #endif
文件2,des.c
/****************************************************** * * des.c * common des...... * ******************************************************/ #include <stdlib.h> #include <string.h> #include <stdio.h> #include "des.h" /********************************************************* data type definition for Des; **********************************************************/ #define EN0 0 #define DE1 1 #define DES_KEYBYTES 128 #define DES_KEYLONGS 32 #define DES_BLOCKLEN 8 typedef struct { unsigned char ek[DES_KEYBYTES]; int ekLen; unsigned char dk[DES_KEYBYTES]; int dkLen; unsigned char CbcCtx[DES_BLOCKLEN]; } DES_CTX; typedef struct { unsigned char ek1[DES_KEYBYTES]; int ek1Len; unsigned char dk1[DES_KEYBYTES]; int dk1Len; unsigned char ek2[DES_KEYBYTES]; int ek2Len; unsigned char dk2[DES_KEYBYTES]; int dk2Len; unsigned char CbcCtx[DES_BLOCKLEN]; //int IsFirstBlock; } DES3_CTX; static unsigned char pc1[56] = { 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 }; static unsigned char pc2[48] = { 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 }; static unsigned short bytebit[8] = {0200,0100,040,020,010,04,02,01 }; static unsigned char totrot[16] = {1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28}; static unsigned long bigbyte[24] = { 0x800000L, 0x400000L, 0x200000L, 0x100000L, 0x80000L, 0x40000L, 0x20000L, 0x10000L, 0x8000L, 0x4000L, 0x2000L, 0x1000L, 0x800L, 0x400L, 0x200L, 0x100L, 0x80L, 0x40L, 0x20L, 0x10L, 0x8L, 0x4L, 0x2L, 0x1L }; //insert digits static unsigned long SP1[64] ={ 0x01010400l,0x00000000l,0x00010000l,0x01010404l, 0x01010004l,0x00010404l,0x00000004l,0x00010000l, 0x00000400l,0x01010400l,0x01010404l,0x00000400l, 0x01000404l,0x01010004l,0x01000000l,0x00000004l, 0x00000404l,0x01000400l,0x01000400l,0x00010400l, 0x00010400l,0x01010000l,0x01010000l,0x01000404l, 0x00010004l,0x01000004l,0x01000004l,0x00010004l, 0x00000000l,0x00000404l,0x00010404l,0x01000000l, 0x00010000l,0x01010404l,0x00000004l,0x01010000l, 0x01010400l,0x01000000l,0x01000000l,0x00000400l, 0x01010004l,0x00010000l,0x00010400l,0x01000004l, 0x00000400l,0x00000004l,0x01000404l,0x00010404l, 0x01010404l,0x00010004l,0x01010000l,0x01000404l, 0x01000004l,0x00000404l,0x00010404l,0x01010400l, 0x00000404l,0x01000400l,0x01000400l,0x00000000l, 0x00010004l,0x00010400l,0x00000000l,0x01010004l }; static unsigned long SP2[64]={ 0x80108020l,0x80008000l,0x00008000l,0x00108020l, 0x00100000l,0x00000020l,0x80100020l,0x80008020l, 0x80000020l,0x80108020l,0x80108000l,0x80000000l, 0x80008000l,0x00100000l,0x00000020l,0x80100020l, 0x00108000l,0x00100020l,0x80008020l,0x00000000l, 0x80000000l,0x00008000l,0x00108020l,0x80100000l, 0x00100020l,0x80000020l,0x00000000l,0x00108000l, 0x00008020l,0x80108000l,0x80100000l,0x00008020l, 0x00000000l,0x00108020l,0x80100020l,0x00100000l, 0x80008020l,0x80100000l,0x80108000l,0x00008000l, 0x80100000l,0x80008000l,0x00000020l,0x80108020l, 0x00108020l,0x00000020l,0x00008000l,0x80000000l, 0x00008020l,0x80108000l,0x00100000l,0x80000020l, 0x00100020l,0x80008020l,0x80000020l,0x00100020l, 0x00108000l,0x00000000l,0x80008000l,0x00008020l, 0x80000000l,0x80100020l,0x80108020l,0x00108000l }; static unsigned long SP3[64]={ 0x00000208l,0x08020200l,0x00000000l,0x08020008l, 0x08000200l,0x00000000l,0x00020208l,0x08000200l, 0x00020008l,0x08000008l,0x08000008l,0x00020000l, 0x08020208l,0x00020008l,0x08020000l,0x00000208l, 0x08000000l,0x00000008l,0x08020200l,0x00000200l, 0x00020200l,0x08020000l,0x08020008l,0x00020208l, 0x08000208l,0x00020200l,0x00020000l,0x08000208l, 0x00000008l,0x08020208l,0x00000200l,0x08000000l, 0x08020200l,0x08000000l,0x00020008l,0x00000208l, 0x00020000l,0x08020200l,0x08000200l,0x00000000l, 0x00000200l,0x00020008l,0x08020208l,0x08000200l, 0x08000008l,0x00000200l,0x00000000l,0x08020008l, 0x08000208l,0x00020000l,0x08000000l,0x08020208l, 0x00000008l,0x00020208l,0x00020200l,0x08000008l, 0x08020000l,0x08000208l,0x00000208l,0x08020000l, 0x00020208l,0x00000008l,0x08020008l,0x00020200l }; static unsigned long SP4[64]={ 0x00802001l,0x00002081l,0x00002081l,0x00000080l, 0x00802080l,0x00800081l,0x00800001l,0x00002001l, 0x00000000l,0x00802000l,0x00802000l,0x00802081l, 0x00000081l,0x00000000l,0x00800080l,0x00800001l, 0x00000001l,0x00002000l,0x00800000l,0x00802001l, 0x00000080l,0x00800000l,0x00002001l,0x00002080l, 0x00800081l,0x00000001l,0x00002080l,0x00800080l, 0x00002000l,0x00802080l,0x00802081l,0x00000081l, 0x00800080l,0x00800001l,0x00802000l,0x00802081l, 0x00000081l,0x00000000l,0x00000000l,0x00802000l, 0x00002080l,0x00800080l,0x00800081l,0x00000001l, 0x00802001l,0x00002081l,0x00002081l,0x00000080l, 0x00802081l,0x00000081l,0x00000001l,0x00002000l, 0x00800001l,0x00002001l,0x00802080l,0x00800081l, 0x00002001l,0x00002080l,0x00800000l,0x00802001l, 0x00000080l,0x00800000l,0x00002000l,0x00802080l }; static unsigned long SP5[64]={ 0x00000100l,0x02080100l,0x02080000l,0x42000100l, 0x00080000l,0x00000100l,0x40000000l,0x02080000l, 0x40080100l,0x00080000l,0x02000100l,0x40080100l, 0x42000100l,0x42080000l,0x00080100l,0x40000000l, 0x02000000l,0x40080000l,0x40080000l,0x00000000l, 0x40000100l,0x42080100l,0x42080100l,0x02000100l, 0x42080000l,0x40000100l,0x00000000l,0x42000000l, 0x02080100l,0x02000000l,0x42000000l,0x00080100l, 0x00080000l,0x42000100l,0x00000100l,0x02000000l, 0x40000000l,0x02080000l,0x42000100l,0x40080100l, 0x02000100l,0x40000000l,0x42080000l,0x02080100l, 0x40080100l,0x00000100l,0x20000000l,0x42080000l, 0x42080100l,0x00080100l,0x42000000l,0x42080100l, 0x02080000l,0x02000100l,0x40000100l,0x00080000l, 0x00080100l,0x02000100l,0x40000100l,0x00080000l, 0x00000000l,0x40080000l,0x02080100l,0x40000100l }; static unsigned long SP6[64]={ 0x20000010l,0x20400000l,0x00004000l,0x20404010l, 0x20400000l,0x00000010l,0x20404010l,0x00400000l, 0x20004000l,0x00404010l,0x00400000l,0x20000010l, 0x00400010l,0x20004000l,0x20000000l,0x00004010l, 0x00000000l,0x00400010l,0x20004010l,0x00004000l, 0x00404000l,0x20004010l,0x00000010l,0x20400010l, 0x20400010l,0x00000000l,0x00404010l,0x20404000l, 0x00004010l,0x00404000l,0x20404000l,0x20000000l, 0x20004000l,0x00000010l,0x20400010l,0x00404000l, 0x20404010l,0x00400000l,0x00004010l,0x20000010l, 0x00400000l,0x20004000l,0x20000000l,0x00004010l, 0x20000010l,0x20404010l,0x00404000l,0x20400000l, 0x00404010l,0x20404000l,0x00000000l,0x20400010l, 0x00000010l,0x00004000l,0x20400000l,0x00404010l, 0x00004000l,0x00400010l,0x20004010l,0x00000000l, 0x20404000l,0x20000000l,0x00400010l,0x20004010l }; static unsigned long SP7[64] = { 0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L, 0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L, 0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L, 0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L, 0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L, 0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L, 0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L, 0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L, 0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L, 0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L, 0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L, 0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L, 0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L, 0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L, 0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L, 0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L }; static unsigned long SP8[64] = { 0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L, 0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L, 0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L, 0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L, 0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L, 0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L, 0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L, 0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L, 0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L, 0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L, 0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L, 0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L, 0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L, 0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L, 0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L, 0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L }; void deskey(unsigned char *key,short edf, unsigned long *kn); void cookey(register unsigned long *raw1, unsigned long *dough); //void cpkey(register unsigned long *into); //void usekey(register unsigned long *from); //void des(unsigned char *inblock,unsigned char *outblock); void scrunch(register unsigned char *outof, register unsigned long *into); void unscrun(register unsigned long *outof, register unsigned char *into); void desfunc(register unsigned long *block,register unsigned long *keys); /***************** DES Function *****************/ unsigned long OPENCOMM_DesExpandEncKey( unsigned char *pbDesKey, unsigned long ulDesKeyLen, unsigned char *pbDesEncKey, unsigned long *ulDesEncKeyLen); unsigned long OPENCOMM_DesExpandDecKey( unsigned char *pbDesKey, unsigned long ulDesKeyLen, unsigned char *pbDesDecKey, unsigned long *ulDesDecKeyLen); unsigned long OPENCOMM_DesEncRaw( unsigned char *pbDesEncKey, unsigned long ulDesEncKeyLen, unsigned char *pbInData, unsigned long ulInDataLen, unsigned char *pbOutData, unsigned long *ulOutDataLen); unsigned long OPENCOMM_DesDecRaw( unsigned char *pbDesDecKey, unsigned long ulDesDecKeyLen, unsigned char *pbInData, unsigned long ulInDataLen, unsigned char *pbOutData, unsigned long *ulOutDataLen); int myic_DESDecrypt( unsigned char *pDesKey, int nDesKeyLen, unsigned char *pInData, int nInDataLen, unsigned char *pOutData, int *pOutDataLen); int myic_DESEncrypt( unsigned char *pDesKey, int nDesKeyLen, unsigned char *pInData, int nInDataLen, unsigned char *pOutData, int *pOutDataLen); void deskey(unsigned char *key,short edf, unsigned long *kn) { register int i, j, l, m, n; unsigned long pc1m[56],pcr[56]; for ( j = 0; j < 56; j++ ) { l = pc1[j]; m = l & 07; pc1m[j] = (((unsigned long) key[l >> 3] & (unsigned long)bytebit[m] ) ? 1:0); } for ( i = 0;i < 16; i++) { if ( edf == DE1 ) m = (15 - i) << 1; else m = i << 1; n = m + 1; kn[m] = kn[n] = 0L; for ( j = 0; j < 28; j++ ) { l = j + totrot[i]; if ( l < 28 ) pcr[j] = pc1m[l]; else pcr[j] = pc1m[l-28]; } for (j = 28; j < 56; j++ ) { l = j + totrot[i]; if ( l < 56 ) pcr[j] = pc1m[l]; else pcr[j] = pc1m[l-28]; } for ( j = 0; j < 24; j++ ) { if ( pcr[pc2[j]] ) kn[m] |= bigbyte[j]; if ( pcr[pc2[j+24]] ) kn[n] |= bigbyte[j]; } } return; } void cookey(register unsigned long *raw1, unsigned long *dough) { register unsigned long *cook,*raw0; register int i; cook = dough; for ( i = 0; i < 16; i++, raw1++ ) { raw0 = raw1++; *cook = (*raw0 & 0x00fc0000L) << 6; *cook |= (*raw0 & 0x00000fc0L) << 10; *cook |= (*raw1 & 0x00fc0000L) >> 10; *cook++ |= (*raw1 & 0x00000fc0L) >> 6; *cook = (*raw0 & 0x0003f000L) << 12; *cook |= (*raw0 & 0x0000003fL) << 16; *cook |= (*raw1 & 0x0003f000L) >> 4; *cook++ |= (*raw1 & 0x0000003fL); } return; } void scrunch(register unsigned char *outof, register unsigned long *into) { *into = (*outof++ & 0xffL) << 24; *into |= (*outof++ & 0xffL) << 16; *into |= (*outof++ & 0xffL) << 8; *into++ |= (*outof++ & 0xffL); *into = (*outof++ & 0xffL) << 24; *into |= (*outof++ & 0xffL) << 16; *into |= (*outof++ & 0xffL) << 8; *into++ |= (*outof & 0xffL); return; } void unscrun(register unsigned long *outof, register unsigned char *into) { *into++ = (unsigned char)((*outof >> 24) & 0xffL); *into++ = (unsigned char)((*outof >> 16) & 0xffL); *into++ = (unsigned char)((*outof >> 8) & 0xffL); *into++ = (unsigned char)( *outof++ & 0xffL); *into++ = (unsigned char)((*outof >> 24) & 0xffL); *into++ = (unsigned char)((*outof >> 16) & 0xffL); *into++ = (unsigned char)((*outof >> 8) & 0xffL); *into = (unsigned char)( *outof & 0xffL); return; } void desfunc(register unsigned long *block,register unsigned long *keys) { register unsigned long fval, work, right, leftt; register int round; leftt = block[0]; right = block[1]; work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL; right ^= work; leftt ^= (work << 4); work = ((leftt >> 16) ^ right) & 0x0000ffffL; right ^= work; leftt ^= (work << 16); work = ((right >> 2) ^ leftt) & 0x33333333L; leftt ^= work; right ^= (work << 2); work = ((right >> 8) ^ leftt) & 0x00ff00ffL; leftt ^= work; right ^= (work << 8); right = ((right << 1) | ((right >>31) & 1L)) & 0xffffffffL; work = (leftt ^ right) & 0xaaaaaaaaL; leftt ^= work; right ^= work; leftt = ((leftt << 1) | ((leftt >> 31)&1L)) & 0xffffffffL; for (round = 0; round < 8; round++) { work = (right << 28) | (right >> 4); work ^= *keys++; fval = SP7[ work & 0x3fL]; fval |= SP5[(work >> 8) & 0x3fL]; fval |= SP3[(work >> 16) & 0x3fL]; fval |= SP1[(work >> 24) & 0x3fL]; work = right ^ *keys++; fval |= SP8[ work & 0x3fL]; fval |= SP6[(work >> 8) & 0x3fL]; fval |= SP4[(work >> 16) & 0x3fL]; fval |= SP2[(work >> 24) & 0x3fL]; leftt ^= fval; work = (leftt << 28) | (leftt >> 4); work ^= *keys++; fval = SP7[ work & 0x3fL]; fval |= SP5[(work >> 8) & 0x3fL]; fval |= SP3[(work >> 16) & 0x3fL]; fval |= SP1[(work >> 24) & 0x3fL]; work = leftt ^ *keys++; fval |= SP8[ work & 0x3fL]; fval |= SP6[(work >> 8) & 0x3fL]; fval |= SP4[(work >> 16) & 0x3fL]; fval |= SP2[(work >> 24) & 0x3fL]; right ^= fval; } right = (right << 31) | (right >> 1); work = (leftt ^ right) & 0xaaaaaaaaL; leftt ^= work; right ^= work; leftt = (leftt << 31) | (leftt >> 1); work = ((leftt >> 8) ^ right) & 0x00ff00ffL; right ^= work; leftt ^= (work << 8); work = ((leftt >> 2) ^ right) & 0x33333333L; right ^= work; leftt ^= (work << 2); work = ((right >> 16) ^ leftt) & 0x0000ffffL; leftt ^= work; right ^= (work << 16); work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL; leftt ^= work; right ^= (work << 4); *block++ = right; *block = leftt; return; } /***************************************************************** OPENCOMM_DesExpandEncKey : Expand Des Enc Key 扩展des加密密钥 Return value: 0 : Success other : failed Parameters: pbDesKey : 扩展前的DES密钥(8字节) input ulDesKeyLen : 扩展前的DES密钥长度 input pbDesEncKey : 扩展后的DES加密密钥(128字节) output *ulDesEncKeyLen : 扩展后的DES加密密钥长度 output *****************************************************************/ unsigned long OPENCOMM_DesExpandEncKey( unsigned char *pbDesKey, unsigned long ulDesKeyLen, unsigned char *pbDesEncKey, unsigned long *ulDesEncKeyLen) { unsigned long kn[32], dough[32]; if (ulDesKeyLen != 8) return 0xEE20; deskey(pbDesKey, EN0, kn); cookey(kn, dough); *ulDesEncKeyLen = DES_KEYBYTES; //32 long = 128 bytes memcpy(pbDesEncKey, dough, *ulDesEncKeyLen); return 0; } /***************************************************************** OPENCOMM_DesExpandDecKey : Expand Des Dec Key 扩展des解密密钥 Return value: 0 : Success other : failed Parameters: pbDesKey : 扩展前的DES密钥(8字节) input ulDesKeyLen : 扩展前的DES密钥长度 input pbDesDecKey : 扩展后的DES解密密钥(128字节) output *ulDesDecKeyLen : 扩展后的DES解密密钥长度 output *****************************************************************/ unsigned long OPENCOMM_DesExpandDecKey( unsigned char *pbDesKey, unsigned long ulDesKeyLen, unsigned char *pbDesDecKey, unsigned long *ulDesDecKeyLen) { unsigned long kn[32], dough[32]; if (ulDesKeyLen != 8) return 0xEE20; deskey(pbDesKey, DE1, kn); cookey(kn, dough); *ulDesDecKeyLen = DES_KEYBYTES; //32 long = 128 bytes memcpy(pbDesDecKey, dough, *ulDesDecKeyLen); return 0; } /**************************************************************** OPENCOMM_DesEncRaw : Des算法加密小整块明文8字节 Return value: 0 : Success other : failed Parameters: pbDesEncKey : DES加密密钥 input ulDesEncKeyLen : DES加密密钥长度 input pbInData : 待加密的明文 input ulInDataLen : 待加密的明文长度 input pbOutData : 加密后的密文 output *ulOutDataLen : 加密后的密文长度 output *****************************************************************/ unsigned long OPENCOMM_DesEncRaw( unsigned char *pbDesEncKey, unsigned long ulDesEncKeyLen, unsigned char *pbInData, unsigned long ulInDataLen, unsigned char *pbOutData, unsigned long *ulOutDataLen) { unsigned long work[2], ek[DES_KEYLONGS]; unsigned char cp[DES_BLOCKLEN]; if (ulInDataLen != DES_BLOCKLEN) return 0xEE20; if (ulDesEncKeyLen != DES_KEYBYTES) return 0xEE20; memcpy(cp, pbInData, DES_BLOCKLEN); scrunch(cp,work); // 8 bytes -> 2 long memcpy(ek, pbDesEncKey, ulDesEncKeyLen); desfunc(work,ek); unscrun(work,cp); // 2 long -> 8 bytes memcpy(pbOutData, cp, DES_BLOCKLEN); *ulOutDataLen = DES_BLOCKLEN; return 0; } /***************************************************************** OPENCOMM_DesDecRaw : Des算法解密小整块密文8字节 Return value: 0 : Success other : failed Parameters: pbDesDecKey : DES解密密钥 input ulDesDecKeyLen : DES解密密钥长度 input pbInData : 待解密的密文 input ulInDataLen : 待解密的密文长度 input pbOutData : 解密后的明文 output *ulOutDataLen : 解密后的明文长度 output *****************************************************************/ unsigned long OPENCOMM_DesDecRaw( unsigned char *pbDesDecKey, unsigned long ulDesDecKeyLen, unsigned char *pbInData, unsigned long ulInDataLen, unsigned char *pbOutData, unsigned long *ulOutDataLen) { unsigned long work[2], dk[DES_KEYLONGS]; unsigned char cp[DES_BLOCKLEN]; if (ulInDataLen != DES_BLOCKLEN) return 0xEE20; if (ulDesDecKeyLen != DES_KEYBYTES) return 0xEE20; memcpy(cp, pbInData, DES_BLOCKLEN); scrunch(cp,work); // 8 bytes -> 2 long memcpy(dk, pbDesDecKey, ulDesDecKeyLen); desfunc(work,dk); unscrun(work,cp); // 2 long -> 8 bytes memcpy(pbOutData, cp, DES_BLOCKLEN); // des_enc(pbDesEncKey, pbInData, pbOutData); *ulOutDataLen = DES_BLOCKLEN; return 0; } /********************* DES *********************/ int myic_DESEncrypt( unsigned char *pDesKey, int nDesKeyLen, unsigned char *pInData, int nInDataLen, unsigned char *pOutData, int *pOutDataLen) { unsigned char DesKeyBuf[32]; unsigned char DesEncKeyBuf[128]; int EncKeyLen, KeyLen = 0; int retval = 0, loops, i; if(nInDataLen%8 != 0) return 0xEE20; if(nDesKeyLen != 8) return 0xEE20; KeyLen = nDesKeyLen; memcpy(DesKeyBuf, pDesKey, nDesKeyLen); retval = OPENCOMM_DesExpandEncKey(DesKeyBuf, KeyLen, DesEncKeyBuf, (unsigned long *)&EncKeyLen); if(retval != 0) return retval; loops = nInDataLen/8; for(i = 0; i < loops; i++) { retval = OPENCOMM_DesEncRaw(DesEncKeyBuf, EncKeyLen, pInData + i*8, 8, pOutData + i*8, (unsigned long *)pOutDataLen); if(retval != 0) return retval; } *pOutDataLen = nInDataLen; return retval; } int myic_DESDecrypt( unsigned char *pDesKey, int nDesKeyLen, unsigned char *pInData, int nInDataLen, unsigned char *pOutData, int *pOutDataLen) { unsigned char DesKeyBuf[32]; unsigned char DesDecKeyBuf[128]; int DecKeyLen, KeyLen = 0; int retval = 0, loops, i; if(nInDataLen%8 != 0) return 0xEE20; if(nDesKeyLen != 8) return 0xEE20; KeyLen = nDesKeyLen; memcpy(DesKeyBuf, pDesKey, nDesKeyLen); retval = OPENCOMM_DesExpandDecKey(DesKeyBuf, KeyLen, DesDecKeyBuf, (unsigned long *)&DecKeyLen); if(retval != 0) return retval; loops = nInDataLen/8; for(i = 0; i < loops; i++) { retval = OPENCOMM_DesDecRaw(DesDecKeyBuf, DecKeyLen, pInData + i*8, 8, pOutData + i*8, (unsigned long *)pOutDataLen); if(retval != 0) return retval; } *pOutDataLen = nInDataLen; return retval; } //对称明文数据打pading void CW_dataPadAdd(int tag, unsigned char *date, unsigned int dateLen, unsigned char **padDate, unsigned int *padDateLen) { int i, padLen; unsigned char *pTmp = NULL; pTmp = (unsigned char *)malloc(dateLen+24); if (pTmp == NULL) { *padDate = NULL; return ; } memset(pTmp, 0, dateLen+24); memcpy(pTmp, date, dateLen); if (tag == 0) { padLen = 8 - dateLen % 8; for (i=0; i<padLen; i++) { pTmp[dateLen+i] = (char)padLen; } *padDateLen = dateLen + padLen; } else { padLen = 16 - dateLen % 16; for (i=0; i<padLen; i++) { pTmp[dateLen+i] = (char)padLen; } } *padDateLen = dateLen + padLen; *padDate = pTmp; } #define USER_PASSWORD_KEY "abcd1234" //数据加密 int DesEnc( unsigned char *pInData, int nInDataLen, unsigned char *pOutData, int *pOutDataLen) { int rv; unsigned char *padDate = NULL; unsigned int padDateLen = 0; CW_dataPadAdd(0, pInData, (unsigned int )nInDataLen, &padDate, &padDateLen); rv = myic_DESEncrypt((unsigned char *)USER_PASSWORD_KEY, strlen(USER_PASSWORD_KEY), padDate, (int)padDateLen, pOutData, pOutDataLen); if (rv != 0) { if (padDate != NULL) { free(padDate); } return rv; } if (padDate != NULL) { free(padDate); } return 0; } //数据加密 int DesEnc_raw( unsigned char *pInData, int nInDataLen, unsigned char *pOutData, int *pOutDataLen) { int rv; unsigned char *padDate = NULL; unsigned int padDateLen = 0; rv = myic_DESEncrypt((unsigned char *)USER_PASSWORD_KEY, strlen(USER_PASSWORD_KEY), pInData, (int)nInDataLen, pOutData, pOutDataLen); if (rv != 0) { return rv; } return 0; } //解密分配内存错误 #define ERR_MALLOC 20 //密码长度不是8的整数倍, 不合法 #define ERR_FILECONT 20 //用户使用函数des解密 int DesDec( unsigned char *pInData, int nInDataLen, unsigned char *pOutData, int *pOutDataLen) { int rv; char padChar; unsigned char *tmpPlain = NULL; tmpPlain = (unsigned char *)malloc(nInDataLen+24); if (tmpPlain == NULL) { return ERR_MALLOC; } memset(tmpPlain, 0, nInDataLen+24); //解密 rv = myic_DESDecrypt((unsigned char *)USER_PASSWORD_KEY, strlen(USER_PASSWORD_KEY), pInData, nInDataLen, tmpPlain, pOutDataLen); if (rv != 0) { if (tmpPlain != NULL) free(tmpPlain); return rv; } //去pading padChar = tmpPlain[*pOutDataLen - 1]; if ( (int)padChar<=0 || (int)padChar>8) //异常处理 { if (tmpPlain) free(tmpPlain); return ERR_FILECONT; } *pOutDataLen = *pOutDataLen - (int)padChar; //memset(tmpPlain + *pOutDataLen, 0, (int)padChar); memcpy(pOutData, tmpPlain, *pOutDataLen); if (tmpPlain) free(tmpPlain); return 0; } //用户使用函数des解密 int DesDec_raw( unsigned char *pInData, int nInDataLen, unsigned char *pOutData, int *pOutDataLen) { int rv; //char padChar; //unsigned char *tmpPlain = NULL; /* tmpPlain = (unsigned char *)malloc(nInDataLen+24); if (tmpPlain == NULL) { return ERR_MALLOC; } memset(tmpPlain, 0, nInDataLen+24); */ //解密 rv = myic_DESDecrypt((unsigned char *)USER_PASSWORD_KEY, strlen(USER_PASSWORD_KEY), pInData, nInDataLen, pOutData, pOutDataLen); if (rv != 0) { //if (tmpPlain != NULL) free(tmpPlain); return rv; } /* //去pading padChar = tmpPlain[*pOutDataLen - 1]; if ( (int)padChar<=0 || (int)padChar>8) //异常处理 { if (tmpPlain) free(tmpPlain); return ERR_FILECONT; } *pOutDataLen = *pOutDataLen - (int)padChar; //memset(tmpPlain + *pOutDataLen, 0, (int)padChar); memcpy(pOutData, tmpPlain, *pOutDataLen); if (tmpPlain) free(tmpPlain); */ return 0; }
加解密测试.c
#define _CRT_SECURE_NO_WARNINGS #include <stdlib.h> #include <string.h> #include <stdio.h> #include "des.h" int main() { int ret = 0; char *plain = "1232343444"; int plainlen = strlen(plain); char plain2[4096] = {0}; int plainlen2 = 0; unsigned char cryptbuf[4096] = {0}; int cryptlen = 0; //用户使用的函数 ret = DesEnc(plain, plainlen, cryptbuf, &cryptlen); if (ret != 0) { printf("func DesEnc() err:%d \n"); return ret; } //用户使用函数des解密 ret = DesDec(cryptbuf, cryptlen, plain2, &plainlen2); if (ret != 0) { printf("func DesDec() err:%d \n"); return ret; } if (plainlen != plainlen2) { ret = -2; printf("明文长度和解密后的明文长度 不一样 \n"); return ret; } if (memcmp(plain2, plain, plainlen) == 0 ) { printf("明文长度和解密后的明文长度 一样 ok \n"); } else { printf("明文长度和解密后的明文长度 不一样 err \n"); } system("pause"); return ret ; }
文件加密框架:
#define _CRT_SECURE_NO_WARNINGS #include <stdlib.h> #include <string.h> #include <stdio.h> #include "des.h" int FileSymEnc(const char *pfile1, const char *pfile2) { int ret = 0; FILE *fp1= NULL, *fp2 = NULL; unsigned char plain[4096]; int plainlen = 0; unsigned char cryptbuf[4096] = {0}; int cryptlen = 0; int tmplen; fp1 = fopen(pfile1, "rb"); if (fp1 == NULL) { goto END; } fp2 = fopen(pfile2, "wb"); if (fp2 == NULL) { goto END; } while (!feof(fp1)) { plainlen = fread(plain, 1, 4096, fp1); if (feof(fp1)) //读完数据以后,判断是否文件结束 { break; } //加密==4k的数据 ret = DesDec_raw(plain, plainlen, cryptbuf, &cryptlen); if (ret != 0) { printf("func DesEnc() err:%d \n", ret); goto END; } tmplen = fwrite(cryptbuf, 1, cryptlen, fp2); if (tmplen != cryptlen) { ret = -3; printf("写密文文件失败,请检查是否磁盘已满\n"); goto END; } //if (plainlen == 4096) } //加密小于4k的数据 ret = DesEnc(plain, plainlen, cryptbuf, &cryptlen); if (ret != 0) { printf("func DesEnc() err:%d \n", ret); goto END; } tmplen = fwrite(cryptbuf, 1, cryptlen, fp2); if (cryptlen != tmplen) { ret = -3; printf("写小于4k文件密文失败,请检查是否磁盘已满\n"); goto END; } END: if (fp1 != NULL) { fclose(fp1); } if (fp2 != NULL) { fclose(fp2); } return 0; } void main() { int ret = 0; const char *file1 = "c:/socketclient.dll"; const char *file2 = "c:/socketclientend.dll"; //const char *file1 = "c:/22.txt"; //const char *file2 = "c:/22enc.txt"; ret = FileSymEnc(file1, file2); if (ret != 0) { printf("func FileSymEnc() err\n " ); return ; } system("pause"); return ; }
本文出自 “魂斗罗” 博客,请务必保留此出处http://990487026.blog.51cto.com/10133282/1791423
原文地址:http://990487026.blog.51cto.com/10133282/1791423