标题:关于文件的问题, 大家一起来研究。
只看楼主
xueyuhanhai
Rank: 4
等 级:业余侠客
帖 子:90
专家分:238
注 册:2010-4-5
结帖率:100%
已结贴  问题点数:50 回复次数:14 
关于文件的问题, 大家一起来研究。
我的程序实现的要求是这样的:我事先在E盘上建立了文件e.txt文件。目的是对他进行加解密,并把加解密的内容替换源文件中的内容(即加解密后的结果任然在e.txt文件中,当然是相同的密钥),程序编译通过了,但是结果却是把e.txt中的内容清空了。大家一起来,找错啊,我有些头大啊。希望版主看一下。


/*……………some header files………………*/
#include "stdafx.h"
#include"stdio.h"
#include<iostream>
using namespace std;
#define MIN 32//从32到125是可以打印的字符
#define LENTH 94
/*…………globle variable……………………*/
char table[LENTH][LENTH];
/*…………statement……………………………*/
bool Init();// 初始化维吉尼亚方阵
bool Encode(char* key, char* source, char* destination);// 加密
bool Dncode(char* key, char* source, char* destination);// 解密
void on_jiami();
void on_jiemi();
/*…………………main function……………*/


int k1=0,k2=0;
char key1[256],key2[256];

int main(int argc, char* argv[])
{

    if(!Init())
    {
        cout << "初始化错误!" << endl;
        return 1;
    }


    int operation;
    printf("\n");
    while(1)
    {
        do
        {
            cout << "请选择一个操作:1. 加密; 2. 解密; -1. 退出\n";
            cin >> operation;
        }while(operation != -1 && operation != 1 && operation != 2);

        if(operation == -1)
            return 0;
        else if(operation == 1)//加密
        {
            cout << "请输入密钥:";
            cin >> key1;
            on_jiami();
        }
        else if(operation == 2)//解密
        {
            cout << "请输入密钥:";
            cin >> key2;
            on_jiemi();
        }
        cout << endl;
    }
    printf("\n");
    printf("Hello World!\n");
    return 0;
}


void on_jiami()
{
    //加密代码
    Init();// 初始化维吉尼亚方阵
    FILE *fp;
    fp=fopen("e:\\e.txt","rb");//打开待加密的文件
    if(fp==NULL)
    {
        printf("cannot open the file!\n");
        
    }
    char ch,string1[94]={'\0'}; //里面存放待加密的字符串并初始化
    do
    {
        char string2[94]={'\0'};
        int j=0;
        int i=1;
        ch=fgetc(fp);
        while((i<94)&&(ch!=EOF))//每次从文件读93个字符,
        {
            i++;
            string1[j]=ch;
            j++;
            ch=fgetc(fp);
        }
        string1[93]='\0';
        Encode(key1, string1, string2);//加密
        fclose(fp);
        fp=fopen("e:\\e.txt","rb+");
        fseek(fp,1L*k1,SEEK_SET);
        fputs(string2,fp);
        fclose(fp);
        fp=fopen("e:\\e.txt","rb");
        k1=k1+strlen(string1);
        fseek(fp,1L*k1,SEEK_SET);
    }while(ch!=EOF);//直到文件的结束
    fclose(fp);
}




void on_jiemi()
{
    //解密代码
    Init();// 初始化维吉尼亚方阵
    FILE *fp;
    fp=fopen("e:\\e.txt","rb");//打开待解密的文件
    if(fp==NULL)
    {
        printf("cannot open the file!\n");
        
    }
   
    char ch,string1[94]={'\0'}; //里面存放待解密的字符串并初始化
    do
    {
        char string2[94]={'\0'};
        int j=0;
        int i=1;
        ch=fgetc(fp);
        while((i<94)&&(ch!=EOF))//每次从文件读93个字符,
        {
            i++;
            string1[j]=ch;
            j++;
            ch=fgetc(fp);
        }
        string1[93]='\0';
        Dncode(key2, string1, string2);//解密
        fclose(fp);
        fp=fopen("e:\\e.txt","rb+");
        fseek(fp,1L*k2,SEEK_SET);
        fputs(string2,fp);
        fclose(fp);
        fp=fopen("e:\\e.txt","rb");
        k2=k2+strlen(string2);
        fseek(fp,1L*k2,SEEK_SET);
    }while(ch!=EOF);//直到文件的结束
    fclose(fp);
}

// 初始化维吉尼亚方阵
bool Init()
{
    int i, j;
    for(i = 0; i < LENTH; i++)
    {
        for(j = 0; j < LENTH; j++)
        {
            table[i][j] = MIN + (i + j) % LENTH;
        }
    }

    return true;
}
// 加密
// key:密钥
// source:待加密的字符串
// dest:经过加密后的字符串
bool Encode(char* key, char* source, char* destination)
{
    char* tempSource = source;
    char* tempKey = key;
    char* tempDest = destination;

    do
    {
        *tempDest = table[(*tempKey) - MIN][(*tempSource) - MIN];
        tempDest++;

        if(!(*(++tempKey)))
            tempKey = key;//密钥的重复
    }while(*tempSource++);//直到明文到最后一个字符为止

    destination[strlen(source)] = '\0';

    return true;
}
// 解密
// key:密钥
// source:待解密的字符串
// dest:经过解密后的字符串
bool Dncode(char* key, char* source, char* destination)
{
    char* tempSource = source;
    char* tempKey = key;
    char* tempDest = destination;
    char offset;

    do
    {
        offset = (*tempSource) - (*tempKey);
        offset = offset >= 0 ? offset : offset + LENTH;
        *tempDest = MIN + offset;
        tempDest++;

        if(!(*(++tempKey)))
            tempKey = key;
    }while(*++tempSource);

    destination[strlen(source)] = '\0';

    return true;
}

我刚刚就大家给出的意见,对文件做了局部的修改,文件可以运行,编译可以通过。也可以加解密,就是相同的加密密钥,加解密的结果是不同的,好像字符的个数也有问题。有兴趣的可以一同讨论。韩明海和南国利剑的建议不错。13楼的zhujianiu的意见也不错。希望大家帮帮忙。
我又从新编辑了代码。为最后的正确代码。谢谢大家的意见。


[ 本帖最后由 xueyuhanhai 于 2010-5-26 10:41 编辑 ]
搜索更多相关主题的帖子: 文件 研究 
2010-05-25 15:12
韩明海
Rank: 8Rank: 8
等 级:蝙蝠侠
帖 子:253
专家分:749
注 册:2010-4-3
得分:30 
给我讲一下Encode(key1, string1, string2);中的三个参数都是怎么用的么?因为你的string2是空的,我怀疑是不是它搞的,
还有,你打开文件感觉也有问题,每次都是从头开始读啊,虽然设置了k1但是只有写的时候用到了,读的时候没用啊,再说也不用一会开一会关的,用好fseek就可以完成你的意思的
2010-05-25 15:31
xueyuhanhai
Rank: 4
等 级:业余侠客
帖 子:90
专家分:238
注 册:2010-4-5
得分:0 
回复 2楼 韩明海
Encode(key1, string1, string2);中的三个参数都是怎么用的么?
答:key1表示的是加密的时候的密钥。string1是从文件e.txt中读出的93个字节的待加密的字符串,并在最后加了'\0'。string2是加密后输出的字符串,是94个字节。最后一个也是\0;
你打开文件感觉也有问题,
答;我是这样的:先读打开把93个字节取到 string1中,后关闭文件。然后调用Encode加密。再写打开,把加密后的string2中的字符串写到文件中,然后关闭文件。再做读打开,进行继续的读字符串。。。。没有用“w+"或是"r+"以防读写的死锁,或出错。用fsee指示下次读写的位置。
2010-05-25 15:55
韩明海
Rank: 8Rank: 8
等 级:蝙蝠侠
帖 子:253
专家分:749
注 册:2010-4-3
得分:0 
哦,知道了你用fseek指示了写的位置,但是我没看到哪里用它指示了读的位置,都是重新打开文件开始读的啊
2010-05-25 16:05
xueyuhanhai
Rank: 4
等 级:业余侠客
帖 子:90
专家分:238
注 册:2010-4-5
得分:0 
回复 4楼 韩明海
哦,我粗心了。但是在加上后,编译没有问题,但是就是加密后,相同的密钥不能解密啊。结果不一样。
Dncode(key2, string1, string2);//解密
        fclose(fp);
        fp=fopen("e:\\e.txt","w");
        fseek(fp,1L*k2,SEEK_SET);
        fputs(string2,fp);
        fclose(fp);
        fp=fopen("e:\\e.txt","r");
        k2=k2+strlen(string2);
       fseek(fp,1L*k2,SEEK_SET);//此处是加代码处
    }while((ch=fgetc(fp))!=EOF);//直到文件的结束
    fclose(fp);


Encode(key1, string1, string2);//加密
        fclose(fp);
        fp=fopen("e:\\e.txt","w");
        fseek(fp,1L*k1,SEEK_SET);
        fputs(string2,fp);
        fclose(fp);
        fp=fopen("e:\\e.txt","r");
        k1=k1+strlen(string1);
        fseek(fp,1L*k1,SEEK_SET);
    }while((ch=fgetc(fp))!=EOF);//直到文件的结束
    fclose(fp);




期待你的解答。我还有一个帖子你看了吧。你如果可以在明天晚上之前作出来我,两个帖子的分都给你。

[ 本帖最后由 xueyuhanhai 于 2010-5-25 16:28 编辑 ]
2010-05-25 16:25
韩明海
Rank: 8Rank: 8
等 级:蝙蝠侠
帖 子:253
专家分:749
注 册:2010-4-3
得分:0 
bool Encode(char* key, char* source, char* destination)
{
    char* tempSource = source;
    char* tempKey = key;
    char* tempDest = destination;

    do
    {
        *tempDest = table[(*tempKey) - MIN][(*tempSource) - MIN];
        tempDest++;

        if(!(*(++tempKey)))
            tempKey = key;//密钥的重复
    }while(*tempSource++);//直到明文到最后一个字符为止

    destination[strlen(source)] = 0;

    return true;
}
有问题啊,你的table 里是什么啊?空的啊,
2010-05-25 16:47
xueyuhanhai
Rank: 4
等 级:业余侠客
帖 子:90
专家分:238
注 册:2010-4-5
得分:0 
没有问题啊。table里面放的是94*94的矩阵啊,全部都是可以打印的字符串啊,在 init函数里面初始化了。还有改过后每运行的文件里面的内容一次(加解密),逐渐减少。最后为0个。字节啊。
2010-05-25 16:54
韩明海
Rank: 8Rank: 8
等 级:蝙蝠侠
帖 子:253
专家分:749
注 册:2010-4-3
得分:0 
*tempDest = table[(*tempKey) - MIN][(*tempSource) - MIN];
你给string2赋值了一大堆数字啊,感觉你的这个加密函数有问题,看不太懂,不明白你想干什么
2010-05-25 17:25
xueyuhanhai
Rank: 4
等 级:业余侠客
帖 子:90
专家分:238
注 册:2010-4-5
得分:0 
这个函数很简单嘛。table矩阵是94*94的矩阵,就相当于知道坐标找点一样。(*tempKey) - MIN是横坐标,(*tempSource) - MIN是列坐标。
2010-05-25 19:43
韩明海
Rank: 8Rank: 8
等 级:蝙蝠侠
帖 子:253
专家分:749
注 册:2010-4-3
得分:0 
呵呵,这个我当然知道,我关心的是你要往文件里写的string2的内容,*tempDest = table[(*tempKey) - MIN][(*tempSource) - MIN];
也就是,赋值给tempDest 的内容,也就是table里存的值,你再初始化的时候在里面写了一堆数字,以后就没有对这个数组的值改变过,那些数字就是你要往文件里写的东西么?这么说明白我的意思了吧?
2010-05-25 20:15



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-308086-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.138461 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved