Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/15: Рейтинг темы: голосов - 15, средняя оценка - 4.67
6 / 6 / 2
Регистрация: 07.11.2012
Сообщений: 95
1

Сравнение бинарных файлов

11.09.2014, 00:57. Показов 2838. Ответов 9
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте. Сначала теоретический вопрос, мне необходимо отслеживать изменился файл или нет, тип файла может быть абсолютна различным. Решил для этой цели загружать в буфер файл и файл зафиксировавший его состояние (пока использовал простое копирование), ну а далее по средствам команды "CompareMem(...)" сравнивать. Недостатком такого метода является сильная нагрузка на память компьютера при проверки больших файлов. Собственно вопрос: как по вашему мнение, адекватный это способ проверки изменения файла или нет? если нет, то пожалуйста подскажите другой способ.
Второй же вопрос хотелось бы фиксировать состояние файла в СУБД. Но вот как это сделать? То есть как записать в базу данных файл различного формата (будь то doc или же exe, ну или другого формата).

Для реализации задачи использую язык С++ в среде Rad studio, в качестве базы данных решил использовать Access (выбор был временным, но раз начал, то стоит научиться в access помещать файлы).
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
11.09.2014, 00:57
Ответы с готовыми решениями:

Перезапись текстовых и бинарных файлов
Добрый день, кто может подсказать как перезаписать текстовые и бинарные файлы. Есть папка в которой...

Загрузка данных из бинарных файлов и сохранение построчно в .dat файл
Добрый день. Помогите разобраться как написать программу, пожалуйста. У меня есть готовая...

Сравнение 2х файлов
как можно проверить по символьно , один файл вводит пользователь , затем по нажатию клавиши...

Бинарное сравнение файлов
Приветствую всех! Необходимо проверить, являются ли 2 файла копиями друг друга, то есть, равны ли...

9
3176 / 1935 / 312
Регистрация: 27.08.2010
Сообщений: 5,131
Записей в блоге: 1
11.09.2014, 03:03 2
Цитата Сообщение от Nicrom Посмотреть сообщение
посредством
Хэш, подходящей битности (от murmur3 до blake2).
1
6 / 6 / 2
Регистрация: 07.11.2012
Сообщений: 95
11.09.2014, 10:16  [ТС] 3
gazlan, спасибо за совет использовать хеш.
Но у меня возникла ещё одна проблема, как загрузить файл в 16-тиричном виде, ну или другом, главное чтоб далее можно применять хеш функцию. До этого применял
C++
1
2
3
TMemoryStream *MS1 = new TMemoryStream;
if (!OpenDialog1->Execute()) return;
MS1->LoadFromFile(OpenDialog1->FileName);
Но с данным типом я к сожалению не могу работать (либо просто не умею). Так же пробовал
C++
1
2
3
TStringList* data1 = new TStringList;
if (!OpenDialog1->Execute()) return;
data1->LoadFromFile(OpenDialog1->FileName);
Тут во-первых файл загружается не полностью (понять почему так и не удалось), во-вторых же он не в шестнадцатеричном виде.

Добавлено через 52 минуты

Добавлено через 21 минуту
Уважаемые гуру, помогите пожалуйста разобраться с алгоритмом murmur3.
Вот нашел реализованный алгоритм
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
37
38
39
40
41
42
43
44
45
46
47
48
49
uint32_t murmur3_32(const char *key, uint32_t len, uint32_t seed) {
    static const uint32_t c1 = 0xcc9e2d51;
    static const uint32_t c2 = 0x1b873593;
    static const uint32_t r1 = 15;
    static const uint32_t r2 = 13;
    static const uint32_t m = 5;
    static const uint32_t n = 0xe6546b64;
 
    uint32_t hash = seed;
 
    const int nblocks = len / 4;
    const uint32_t *blocks = (const uint32_t *) key;
    int i;
    for (i = 0; i < nblocks; i++) {
        uint32_t k = blocks[i];
        k *= c1;
        k = (k << r1) | (k >> (32 - r1));
        k *= c2;
 
        hash ^= k;
        hash = ((hash << r2) | (hash >> (32 - r2))) * m + n;
    }
 
    const uint8_t *tail = (const uint8_t *) (key + nblocks * 4);
    uint32_t k1 = 0;
 
    switch (len & 3) {
    case 3:
        k1 ^= tail[2] << 16;
    case 2:
        k1 ^= tail[1] << 8;
    case 1:
        k1 ^= tail[0];
 
        k1 *= c1;
        k1 = (k1 << r1) | (k1 >> (32 - r1));
        k1 *= c2;
        hash ^= k1;
    }
 
    hash ^= len;
    hash ^= (hash >> 16);
    hash *= 0x85ebca6b;
    hash ^= (hash >> 13);
    hash *= 0xc2b2ae35;
    hash ^= (hash >> 16);
 
    return hash;
}
Взят здесь http://en.wikipedia.org/wiki/MurmurHash
Насколько я понял переменные которые использует функция: const char *key, uint32_t len, uint32_t seed
const char *key - это ключ по которому идёт шифрование. Так как в моей задаче необходимо лишь проверять целостность, можно ли от неё избавиться?
uint32_t len - размер файла.
uint32_t seed - набор символов для обработки, именно в этой переменной и будет подаваться на обработку файл.

Теперь по применению этой функции, вот как её вызываю:
C++
1
2
3
4
5
6
7
char *key;
uint32_t len;
uint32_t seed;
*key='8';
seed = /*огромное число*/;
len = sizeof(seed);
uint32_t murmur3_32(*key,len,seed);
в ответ от компилятора получаю
[BCC32 Error] Unit1.cpp(171): E2293 ) expected
Full parser context
Unit1.cpp(164): parsing: void _fastcall TForm1::Button3Click(TObject *)

Добавлено через 8 минут
хм, нужно бы поспать, по поводу применения моя глупая ошибка, нужно вызывать
C++
1
murmur3_32(*key,len,seed);
0
3176 / 1935 / 312
Регистрация: 27.08.2010
Сообщений: 5,131
Записей в блоге: 1
11.09.2014, 16:04 4
Цитата Сообщение от Nicrom Посмотреть сообщение
16-тЕричном виде
Это еще зачем? Хэш считается от (бинарного) файла.

const char* key - это ключ по которому идёт шифрование
Нет никакого шифрования. char* key - это указатель на буфер, в котором находятся данные. Лучший для вас вариант - использовать мэппинг файла в память.

uint32_t seed - набор символов для обработки
Это именно то, что заявлено в названии - соль (DWORD). Например, 0x12345678.
1
6 / 6 / 2
Регистрация: 07.11.2012
Сообщений: 95
14.09.2014, 21:12  [ТС] 5
И снова я с глупым вопросом. Вот код вызова функции:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
TMemoryStream *MS1 = new TMemoryStream ;
if (!OpenDialog1->Execute()) return;
MS1->LoadFromFile(OpenDialog1->FileName);
 
int len=MS1->Size;
int seed=0x12345678;;
char *buf = new char[MS1->Size];
 buf[len] = 0;
int dat;
 MS1->Position = 0;
for (unsigned int i=0;i<len;i++) {
  MS1->Read(&buf, 1);
  MS1->Position++;
}
dat =murmur3_32(buf,len,seed);
 
RichEdit1->Lines->Add(IntToStr(dat));
 
*buf = 0;
MS1->Clear();
После проверки на одном файле выдаётся разная хеш сумма. Предполагаю ошибка в фрагменте перевода файла в указатель на чар, но вот разобраться как это исправить не удаётся... Помогите пожалуйста разобраться как сделать чтоб результат был постоянный и правильный...

И ещё один момент который я так же не могу понять, функция которую я вызываю использует return на переменную типа uint32_t, если я правильно понимаю, то это unsigned int, но почему то порой выводятся отрицательные числа.
0
3176 / 1935 / 312
Регистрация: 27.08.2010
Сообщений: 5,131
Записей в блоге: 1
14.09.2014, 22:23 6
Цитата Сообщение от Nicrom Посмотреть сообщение
код вызова функции
На Delphi (или что там у вас с TMemoryStream) не пишу, но подозреваю, что строки 5-14 совершенно излишни. Если MS1 - указатель на файл в памяти, то судя по Google, у него есть property Memory: Pointer;

Use Memory to get access to the memory for the stream. The memory for the stream holds the data that is being transferred by means of the memory stream. Size is the number of bytes of Memory that were allocated, and Position is the current position within Memory.
И, значит, именно его и надо передавать в качестве буфера в хэш-функцию.

это unsigned int, но почему-то порой выводятся отрицательные числа
Измените формат вывода на корректный - беззнаковый.
0
6 / 6 / 2
Регистрация: 07.11.2012
Сообщений: 95
14.09.2014, 22:59  [ТС] 7
Уважаемый gazlan, огромное спасибо в помощи!
Последнюю проблему решил после того как вы указали, посмотреть на этот TMemoryStream. Правильный код вызова:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
TMemoryStream *MS1 = new TMemoryStream ;
if (!OpenDialog1->Execute()) return;
MS1->LoadFromFile(OpenDialog1->FileName);
 
int len=MS1->Size;
int seed=0x12345678;;
char *buf = new char[MS1->Size];
 buf[len] = 0;
int dat;
 MS1->Position = 0;
for (unsigned int i=0;i<len;i++) {
  MS1->Read(&buf[i], 1);   //<-Именно тут ошибка, нужно было приписать [i], я ведь в конце концов с массивом работаю =) 
  MS1->Position++;
}
dat =murmur3_32(buf,len,seed);
 
RichEdit1->Lines->Add(IntToStr(dat));
 
*buf = 0;
MS1->Clear();
0
3176 / 1935 / 312
Регистрация: 27.08.2010
Сообщений: 5,131
Записей в блоге: 1
14.09.2014, 23:14 8
Я все еще не понимаю, зачем нужен char *buf = new char[MS1->Size];. IMHO, TMemoryStream уже имеет собственный буфер (Memory) и нет нужды ничего побайтно из него копировать - прямо передайте указатель на Memory в хэш-функцию.
0
6 / 6 / 2
Регистрация: 07.11.2012
Сообщений: 95
15.09.2014, 00:41  [ТС] 9
gazlan, я пробовал так делать:
C++
1
data= murmur3_32(MS->Memory,len,seed);
В результате получал:
[BCC32 Error] Unit1.cpp(143): E2034 Cannot convert 'void * const' to 'const char *'
Full parser context
Unit1.cpp(109): parsing: void _fastcall TForm1::FiksClick(TObject *)
0
3176 / 1935 / 312
Регистрация: 27.08.2010
Сообщений: 5,131
Записей в блоге: 1
15.09.2014, 01:43 10
Ну, так сделайте явное приведение типа:
C++
1
data= murmur3_32((char*)MS->Memory,len,seed);
0
15.09.2014, 01:43
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
15.09.2014, 01:43
Помогаю со студенческими работами здесь

Сравнение звуковых файлов
Подскажите пожалуйста как можно сравнивать два или более звуковых файлов, желательно в wav формате,...

Запись, сравнение звуковых файлов
Недавно заинтересовался вопросом как сделать программу, которая бы записывала и сравнивала звуковые...

Поиск и Сравнение файлов по дате создания
Доброго времени суток, прошу совет. Задача такова, нужно найти файлы с расширением txt и узнать...

Сравнение бинарных файлов
В общем задача такая: открыть 2 бинарных файла и,если так можно вообще, циклом+ветвлением сравнить...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru