Форум программистов, компьютерный форум CyberForum.ru

Зашифровать файл, используя исключающее или - C++

Восстановить пароль Регистрация
 
LostDok
 Аватар для LostDok
0 / 0 / 0
Регистрация: 15.06.2014
Сообщений: 49
15.06.2014, 13:54     Зашифровать файл, используя исключающее или #1
Здравствуйте.

Задача:

Есть файл, в котором записаны какие-то символы. Надо поочередно брать каждый символ и менять в нем 1 на 0 и 0 на 1 с помощью XOR. Например, символ 'a' это 01100001. После выполнения программы должно быть: 10011110
Еще обязательное условие. Можно использовать только один указатель на файл! Работаем с одним указателем на файл и используем функцию fseek.


Вот что я написал:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include "stdafx.h"
#include <iostream>
#include <cstdio>
 
#pragma warning(disable: 4996);
 
using namespace std;
 
int _tmain(int argc, _TCHAR* argv[])
{
    FILE *fp;
    char ch;
 
    fp = fopen("D:\\file.txt", "r+");
 
    if(fp == NULL)
    {
        cout << "File is not opened" << endl;
        exit(1);
    }
 
    cout << "File is open." << endl;
 
    while( (ch = fgetc(fp)) != EOF)
    {
        fseek(fp, -1, SEEK_CUR);
        ch ^= 0xFF;
        fputc(ch, fp);
    }
 
    fcloseall();
    
    system("D:\\file.txt");
 
    return 0;
}
Цикл зацикливается.
Выяснил, что у меня почему-то fgetc(fp) постоянно присваивает в ch второй символ из файла.


Логика моего цикла следующая:

1. ch = fgetc(fp) - присвоил в ch символ из файла и сдвинул указатель на 1 вперед (допустим была позиция 0, сейчас - 1).
2. fseek(fp, -1, SEEK_CUR) - сдвинул указатель на 1 назад (была 1, стала 0).
3. fputc(ch, fp) - положил ch в нужную позицию в файле и сдвинул указатель на 1 вперед (было 0, стало 1).

В чем моя ошибка?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.06.2014, 13:54     Зашифровать файл, используя исключающее или
Посмотрите здесь:

C++ Поразрядное исключающее ИЛИ с присваиванием
C++ Произвести шифрование с использованием поразрядной операции «исключающее или»
C++ Побитовое исключающее ИЛИ (XOR)
C++ Используя треугольник паскаля, зашифровать исходное предложение
C++ Шифрование и дешифрование с использованием алгоритма "исключающее ИЛИ"
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
15.06.2014, 14:05     Зашифровать файл, используя исключающее или #2
LostDok, ты работает с текстовым файлом. Насколько я понял, происходит следующее:
Файл исходный: "тест" (предположим, что Т преобразовывается в А)
Файл выходной после каждой итерации:
"тест"
"атест"
"аатест"
"ааатест"
Так мне кажется. Ты не перезаписываешь char, а добавляешь его

Добавлено через 2 минуты
Ещё вариант.
Документация по fseek говорит:
offset
Binary files: Number of bytes to offset from origin.
Text files: Either zero, or a value returned by ftell.
Иначе говоря, "-1" не прокатит. До fgetc() используешь ftell, а затем уже fseek туда.

Вообще, я бы предложил тебе открыть файл, как бинарный, т.е. "rb+". Но я не уверен, что с ним обычные fgetc() и прочие работаю. Тогда придется использовать соответствующие бинарные write/read.
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9371 / 5421 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
15.06.2014, 14:11     Зашифровать файл, используя исключающее или #3
LostDok, это замысловатые заморочки с буферизацией, я думаю. Задание, простите, абсолютно идиотское, и решение должно быть соответствующим - запоминайте позиции последнего чтения и записи в отдельные переменные, их соответственно меняйте, и на них указатель файла двигайте.

Цитата Сообщение от LostDok Посмотреть сообщение
ch ^= 0xFF;
C
1
ch = ~ch;
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
15.06.2014, 14:13     Зашифровать файл, используя исключающее или #4
LostDok, вообще да. Как сказал easybudda, можно попробовать исключить буферизацию с помощью fflush() после каждой записи в файл
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9371 / 5421 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
15.06.2014, 17:18     Зашифровать файл, используя исключающее или #5
Цитата Сообщение от nexen Посмотреть сообщение
Вообще, я бы предложил тебе открыть файл, как бинарный, т.е. "rb+". Но я не уверен, что с ним обычные fgetc() и прочие работаю.
fread/fwrite работают, а из "оригинальных решений" - я бы файл в память отобразил...

Добавлено через 3 часа 4 минуты
В линухе вот так сделать можно:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
#include <cassert>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
 
int main(int argc, char ** argv) {
    if ( argc < 2 ) {
        std::cerr << "Usage: " << *argv << " <file_name>" << std::endl;
        return 1;
    }
    
    int fd = open(argv[1], O_RDWR);
    assert(fd > -1);
    
    struct stat st;
    assert(fstat(fd, &st) == 0);
    long len = st.st_size;
    unsigned char ch;
    
    while ( len-- ) {
        assert(pread(fd, (void*)&ch, 1, len) == 1);
        ch = ~ch;
        assert(pwrite(fd, (const void*)&ch, 1, len) == 1);
    }
    
    assert(close(fd) == 0);
    return 0;
}
Код
[andrew@easybook files]$ g++ -o codec codec.cpp 
[andrew@easybook files]$ cat > f.txt
any many money more
[andrew@easybook files]$ ./codec f.txt 
[andrew@easybook files]$ cat f.txt 
���ߒ���ߒ����ߒ���[andrew@easybook files]$ ./codec f.txt 
[andrew@easybook files]$ cat f.txt 
any many money more
[andrew@easybook files]$
в WinAPI должно что-нибудь в том же духе быть.
Только это всё-таки C-way, в С++ с файлами по-другому работают. ТС, Вы таки уточните, Вас какому языку учат?
LostDok
 Аватар для LostDok
0 / 0 / 0
Регистрация: 15.06.2014
Сообщений: 49
15.06.2014, 18:15  [ТС]     Зашифровать файл, используя исключающее или #6
Учат C.
Спасибо большое за ответы. Буду разбираться. Отпишу что и как.
Yandex
Объявления
15.06.2014, 18:15     Зашифровать файл, используя исключающее или
Ответ Создать тему
Опции темы

Текущее время: 10:43. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru