Вверх ↑
Этот топик читают: Гость
Ответов: 4579
Рейтинг: 730
#16: 2021-10-13 17:03:29 ЛС | профиль | цитата
Ну, а почему именно по 5 байт? Вероятно, там будет циклический поиск с постепенно увеличивающейся длиной. Если для выявления отличий байты сравниваются, то для выявления вставки/удаления фрагментов начиная с первого отличия ищутся совпадения (при этом длина для совпадающего фрагмента постепенно увеличивается). Это позволит выявить границы вставленных и удаленных фрагментов. Но опять же, некоторые случаи, типа, вставки нескольких байт и изменения нескольких последующих байт могут затруднять принятие решения.

Потренируйся, например, на сравнении файлов в TotalCommander - как он ведет себя с текстовыми и двоичными файлами. Например, при вставке в текстовый файл фрагмента и небольшого изменения последующего текста TotalCommander иногда показывает отличия с места вставки и до конца файла, не имея возможности определить конец добавленного фрагмента. Тогда на помощь приходит команда "установить маркер ручного сопоставления" - мы вручную указываем конец вставленного фрагмента, а дальнейшее сравнение покажет корректный результат.

Редактировалось 5 раз(а), последний 2021-10-13 17:09:20
карма: 26

0
Ответов: 270
Рейтинг: 5
#17: 2021-10-14 13:37:19 ЛС | профиль | цитата
Я думаю сравнивать нужно по одному байту.В строках это должно прокатить т.к. там смещение не важно.А вот в жестко кодированных строках уже засада там каждый лишний символ, даже пробел в основном приводит к краху программы.
карма: 0

0
Ответов: 4579
Рейтинг: 730
#18: 2021-10-15 10:31:36 ЛС | профиль | цитата
Udokanec писал(а):
там каждый лишний символ
Для строк в ресурсах используются корректные функции редактирования ресурсов, которые правильно прописывают новые размеры в исполняемом файле и смещают последующие данные, чтобы они не перекрывались вновь добавленными.
карма: 26

0
Ответов: 270
Рейтинг: 5
#19: 2021-10-15 14:30:24 ЛС | профиль | цитата
Блин почему первый байт не читает

Add(FileStream,5579189,434,280)
{
Point(doPosition)
link(onLoad,14482734:doConvert,[])
}
Add(Button,6901598,224,280)
{
Left=15
Top=45
link(onClick,10644980:doExecute,[])
}
Add(ODialog,10644980,280,280)
{
link(onExecute,7672151:doEvent1,[])
}
Add(Memo,8413688,700,280)
{
Left=20
Top=135
Width=735
Height=360
ScrollBars=3
}
Add(StreamConvertor,14482734,497,280)
{
Point(Data)
}
Add(MainForm,2953706,336,133)
{
Caption="Пример использования компонента FileStream"
}
Add(Hub,7672151,336,280)
{
OutCount=5
link(onEvent1,5579189:doOpen,[])
link(onEvent3,7228710:doFor,[(364,300)(364,398)])
link(onEvent4,5579189:doClose,[(392,307)(392,293)])
}
Add(For,7228710,378,392)
{
IncludeEnd=1
link(onEvent,8206227:doEvent1,[])
link(End,5579189:Size,[(391,353)(447,353)])
}
Add(Convertor,7177771,567,399)
{
Mode=6
link(onResult,8413688:doAdd,[(649,405)(649,286)])
link(Data,15470337:Data,[(573,387)(517,387)(517,443)(461,443)])
}
Add(DataToFileEx,15470337,455,399)
{
BigEndian=0
Point(doPosition)
link(onGet,7177771:doConvert,[])
link(Stream,5579189:Stream,[(461,367)(440,367)])
}
Add(Hub,8206227,420,392)
{
link(onEvent1,5579189:doPosition,[(446,398)(446,349)(422,349)(422,300)])
link(onEvent2,15470337:doGet,[])
}

карма: 0

0
Ответов: 4579
Рейтинг: 730
#20: 2021-10-15 14:46:53 ЛС | профиль | цитата

Add(FileStream,5579189,483,329)
{
Point(doPosition)
link(onLoad,7672151:doEvent1,[])
}
Add(Button,6901598,315,329)
{
Left=10
Top=10
link(onClick,10644980:doExecute,[])
}
Add(ODialog,10644980,371,329)
{
link(onExecute,5579189:doOpen,[])
}
Add(Memo,8413688,875,434)
{
Left=5
Top=45
Width=250
Height=250
ScrollBars=3
}
Add(MainForm,6044688,385,182)
{
Height=347
Caption="Пример использования компонента FileStream"
}
Add(Hub,7672151,532,329)
{
link(onEvent1,7228710:doFor,[(581,335)(581,433)])
link(onEvent2,5579189:doClose,[(565,342)(565,382)(443,382)(443,342)])
}
Add(For,7228710,616,427)
{
IncludeEnd=1
link(onEvent,8206227:doEvent1,[])
link(End,5579189:Size,[(629,402)(496,402)])
}
Add(Convertor,7177771,798,434)
{
Mode=6
link(onResult,8413688:doAdd,[])
}
Add(DataToFileEx,15470337,721,434)
{
BigEndian=0
Point(doPosition)
link(onGet,7177771:doConvert,[])
link(Stream,5579189:Stream,[(727,416)(489,416)])
}
Add(Hub,8206227,665,427)
{
link(onEvent2,15470337:doGet,[])
}

Вероятно, данные из диалога выбора файла попадали на вход компонента For и сбивали начальное значение цикла. Надо следить за подаваемыми на компоненты данными.
1) Работать с файлом надо после того как этот файл успешно открыт - после события FileStream.onLoad, а не выбора файла в диалоге.
2) После чтения/записи любых данных из файла Position автоматически сдвигается вперед на "после прочитанных данных" - необязательно двигать её вручную (если только не надо установить в какую-то другую позицию).
карма: 26

0
Ответов: 270
Рейтинг: 5
#21: 2021-10-15 15:00:58 ЛС | профиль | цитата
Спасибо разобрался

--- Добавлено в 2021-10-15 15:15:14

[b]Netspirit [/b] А как обойти такую байду.Мне при сравнивании строк в оригинальном файле нужен шаг 1 байт,а в переведенном 2 байта.Сравнение будет некорректным.
Add(MainForm,2953706,294,35)
{
Width=616
Height=342
Caption="Пример использования компонента FileStream"
}
Add(FileStream,5579189,392,147)
{
Point(doPosition)
link(onLoad,7672151:doEvent1,[])
}
Add(Button,6901598,224,147)
{
Left=60
Top=15
Width=65
Caption="Оригинал"
link(onClick,10644980:doExecute,[])
}
Add(ODialog,10644980,280,147)
{
link(onExecute,5579189:doOpen,[])
}
Add(Memo,8413688,784,252)
{
Left=5
Top=45
Width=250
Height=250
ScrollBars=3
}
Add(Hub,7672151,441,147)
{
link(onEvent1,7228710:doFor,[(490,153)(490,251)])
link(onEvent2,5579189:doClose,[(474,160)(474,200)(352,200)(352,160)])
}
Add(For,7228710,525,245)
{
IncludeEnd=1
link(onEvent,8206227:doEvent1,[])
link(End,5579189:Size,[(538,220)(405,220)])
}
Add(Convertor,7177771,707,252)
{
Mode=6
link(onResult,8413688:doAdd,[])
}
Add(DataToFileEx,15470337,630,252)
{
BigEndian=0
Point(doPosition)
link(onGet,7177771:doConvert,[])
link(Stream,5579189:Stream,[(636,234)(398,234)])
}
Add(Hub,8206227,574,245)
{
link(onEvent2,15470337:doGet,[])
}
Add(FileStream,12186776,413,357)
{
Point(doPosition)
link(onLoad,7330781:doEvent1,[])
}
Add(Button,7326642,245,357)
{
Left=390
Top=15
Width=90
Caption="Измененный"
link(onClick,8129174:doExecute,[])
}
Add(ODialog,8129174,301,357)
{
link(onExecute,12186776:doOpen,[])
}
Add(Memo,3411457,805,462)
{
Left=320
Top=45
Width=250
Height=250
ScrollBars=3
}
Add(Hub,7330781,462,357)
{
link(onEvent1,4366585:doFor,[(511,363)(511,461)])
link(onEvent2,12186776:doClose,[(495,370)(495,410)(373,410)(373,370)])
}
Add(For,4366585,546,455)
{
Step=2
IncludeEnd=1
link(onEvent,15601516:doEvent1,[])
link(End,12186776:Size,[(559,430)(426,430)])
}
Add(Convertor,3180973,728,462)
{
Mode=6
link(onResult,3411457:doAdd,[])
}
Add(DataToFileEx,13955297,651,462)
{
BigEndian=0
Point(doPosition)
link(onGet,3180973:doConvert,[])
link(Stream,12186776:Stream,[(657,444)(419,444)])
}
Add(Hub,15601516,595,455)
{
link(onEvent2,13955297:doGet,[])
}


Редактировалось 4 раз(а), последний 2021-10-15 15:24:08
карма: 0

0
Ответов: 4579
Рейтинг: 730
#22: 2021-10-18 10:51:51 ЛС | профиль | цитата
Раздели понятие "шаг" и понятие "длина считываемой последовательности". При сравнении длины считываемой последовательности должны быть одинаковыми (это свойство DataToFileEx.DataSize). Поскольку позиция считывания автоматически увеличивается на длину считываемых данных, то в том месте, где "шаг" не равен длине последовательности (или новая позиция не устраивает по другой причине), нужно добавить ручную установку позиции для следующего считывания.
карма: 26

0
Ответов: 270
Рейтинг: 5
#23: 2021-10-18 12:55:07 ЛС | профиль | цитата
Я так понял что DataSize должно быть одинаковым у обоих файлов?А как мне тогда искать измененные файлы?Я думал например счетчик встал на позицию 10 в оригинальном файле сравнил количество байт с переведенным.А у них разный размер-значит это перевод.Занес в таблицу позицию,оригинальное слово,и переведенное.Добавил разницу байт в конец исходный слова и встал на эту позицию.И дальше до конца файла.Или так не получится?
карма: 0

0
Ответов: 4579
Рейтинг: 730
#24: 2021-10-18 13:25:31 ЛС | профиль | цитата
Udokanec писал(а):
А как мне тогда искать измененные файлы?
Искать отличия побайтово. Потому что если сравнивать два фрагмента разной длины то определенно они НЕ РАВНЫ.
Простой способ - искать только измененные данные. Читаешь 1 байт из первого файла и 1 байт из второго, сравниваешь. Если не равны - сообщаешь позицию этого байта. Не подходит если требуется определить вставку или удаление данных.

Сложный способ - определение вставок/удалений. Я не владею конкретным алгоритмом для этого и на словах это описывать сложно.
Примем что файл 1 - это НОВЫЙ (ИЗМЕНЕННЫЙ) ФАЙЛ, файл 2 - ЭТАЛОННЫЙ ФАЙЛ
1) Находишь первый отличающийся байт в обеих файлах
Новый: ABCxyzDEFGHIMNOPQRSTU
Эталон: ABCDEFGHIJKLMNOPQRSTU
2) Проверяем вставка ли это в 1-м файле. Для этого читаем следующий байт в 1-м файле и сравниваем с найденным в п.1 байтом 2-го файла (отличающимся). Если не равны - берем третий байт из 1-го файла и опять сравниваем. Делаем так, пока байты не совпадут
Новый: ABCxyzDEFGHIMNOPQRSTU
Эталон: ABCDEFGHIJKLMNOPQRSTU
Если нашли совпадающий байт дальше - между позицией первого отличающегося байта и позицией совпадающего байта в 1-м файле был вставлен фрагмент.
2) Проверяем удаление фрагмента в 1-м файле. Для этого тот же отличный байт в 1-м файле и ищем во 2-м начиная с позиции различного байта (в п.1).
Если нашли дальше чем текущая позиция - между позицией первого отличающегося байта и позицией следующего совпадающего байта 2-го файла в 1-м файле был удален фрагмент. (Алгоритм тот же что и при вставке, только ищем "вставку" во 2-м файле).
Новый: ABCGHIMNOPQRSTU
Эталон: ABCDEFGHIJKLMNOPQRSTU

Новый: ABCGHIMNOPQRSTU
Эталон: ABCDEFGHIJKLMNOPQRSTU
3) Если по результатам п.2-3 не было вставки-удаления - значит это просто 1 измененный байт в данной позиции
4) В зависимости от предыдущих результатов подправляется позиция для следующего сравнения и повторяем из п.1.
Вероятно это будет давать неопределенные результаты при наличии цепочек повторяющихся байт и изменениях в них.

Udokanec писал(а):
счетчик встал на позицию 10 в оригинальном файле сравнил количество байт с переведенным
Не совсем понятно. С указанных позиций обеих файлов можно только прочитать УКАЗАННОЕ количество байт и сравнить их. Если прочитать разное количество - то сравнение всегда будет ложно (если сравнивать как строки).
Udokanec писал(а):
А у них разный размер-значит это перевод.
Количество считываемых байт каждый раз задаёшь ты - как узнать что у них "разный размер", что в твоем случае "размер"? Размер, например, может быть у файла - для того чтобы узнать его из него не надо ничего читать, есть соответственная точка.

Редактировалось 20 раз(а), последний 2021-10-18 15:59:22
карма: 26

0
Ответов: 270
Рейтинг: 5
#25: 2021-10-18 13:55:46 ЛС | профиль | цитата
Я начал делать так.В файле программы-любой,В начале слова-в строках обычно стоит один или несколько пробелов.Я на этом решил сыграть.

Add(MainForm,2953706,294,35)
{
Width=711
Height=411
Caption="Пример использования компонента FileStream"
}
Add(FileStream,5579189,392,147)
{
Point(doPosition)
link(onLoad,7672151:doEvent1,[])
link(FileName,3229096:Value,[])
}
Add(Button,6901598,280,98)
{
Left=90
Top=20
Width=65
Caption="Оригинал"
link(onClick,10644980:doExecute,[])
}
Add(ODialog,10644980,336,98)
{
link(onExecute,3229096:doValue,[])
}
Add(Memo,8413688,938,259)
{
Left=5
Top=45
Width=250
Height=250
ScrollBars=3
}
Add(Hub,7672151,441,147)
{
link(onEvent1,7228710:doFor,[(490,153)(490,251)])
link(onEvent2,5579189:doClose,[(474,160)(474,200)(352,200)(352,160)])
}
Add(For,7228710,525,245)
{
IncludeEnd=1
Point(onBreak)
link(onEvent,8206227:doEvent1,[])
link(End,5579189:Size,[(538,220)(405,220)])
}
Add(Convertor,7177771,707,252)
{
Mode=6
link(onResult,5772768:doCompare,[])
}
Add(DataToFileEx,15470337,630,252)
{
BigEndian=0
Point(doPosition)
Point(Size)
link(onGet,7177771:doConvert,[])
link(Stream,5579189:Stream,[(636,234)(398,234)])
}
Add(Hub,8206227,574,245)
{
link(onEvent2,15470337:doGet,[])
}
Add(If_else,5772768,770,252)
{
Op2=String(20)
link(onTrue,6817673:doEvent1,[(814,258)(814,349)])
link(onFalse,8413688:doAdd,[])
}
Add(Hub,6817673,826,343)
{
OutCount=3
link(onEvent1,7228710:doStop,[(866,349)(866,307)(513,307)(513,258)])
link(onEvent2,12330014:doText,[(852,356)(852,391)(618,391)(618,356)])
}
Add(Edit,12330014,637,350)
{
Left=10
Top=320
Width=235
link(Str,7228710:Position,[(643,314)(531,314)])
}
Add(Memory,3229096,392,98)
{
}
Add(Button,6697792,210,147)
{
Left=265
Top=175
link(onClick,9830807:doEvent1,[])
}
Add(Hub,9830807,266,147)
{
link(onEvent1,5579189:doOpen,[])
}
Add(FileStream,11601875,406,392)
{
Point(doPosition)
link(onLoad,4543568:doEvent1,[])
link(FileName,10588058:Value,[])
}
Add(Button,9982498,294,343)
{
Left=410
Top=10
Width=130
Caption="Переведенный"
link(onClick,15567409:doExecute,[])
}
Add(ODialog,15567409,350,343)
{
link(onExecute,10588058:doValue,[])
}
Add(Memo,2066704,952,504)
{
Left=345
Top=45
Width=250
Height=250
ScrollBars=3
}
Add(Hub,4543568,455,392)
{
link(onEvent1,11727105:doFor,[(504,398)(504,496)])
link(onEvent2,11601875:doClose,[(488,405)(488,445)(366,445)(366,405)])
}
Add(For,11727105,539,490)
{
IncludeEnd=1
Point(onBreak)
link(onEvent,15592265:doEvent1,[])
link(End,11601875:Size,[(552,465)(419,465)])
}
Add(Convertor,11929277,721,497)
{
Mode=6
link(onResult,8197454:doCompare,[])
}
Add(DataToFileEx,8102585,644,497)
{
BigEndian=0
Point(doPosition)
Point(Size)
link(onGet,11929277:doConvert,[])
link(Stream,11601875:Stream,[(650,479)(412,479)])
}
Add(Hub,15592265,588,490)
{
link(onEvent2,8102585:doGet,[])
}
Add(If_else,8197454,784,497)
{
Op2=String(20)
link(onTrue,2257770:doEvent1,[(828,503)(828,594)])
link(onFalse,2066704:doAdd,[])
}
Add(Hub,2257770,840,588)
{
OutCount=3
link(onEvent1,11727105:doStop,[(880,594)(880,552)(527,552)(527,503)])
link(onEvent2,15668748:doText,[(866,601)(866,636)(632,636)(632,601)])
}
Add(Edit,15668748,651,595)
{
Left=350
Top=315
Width=235
link(Str,11727105:Position,[(657,559)(545,559)])
}
Add(Memory,10588058,406,343)
{
}
Add(Button,2227539,224,392)
{
Left=605
Top=170
link(onClick,9058230:doEvent1,[])
}
Add(Hub,9058230,280,392)
{
link(onEvent1,11601875:doOpen,[])
}


Находим слово.Потом в переведенном то же самое и Сравниваем и так по очереди.Естественно через For
--- Добавлено в 2021-10-18 14:14:34

Не правильно выразил мысль.Включаем перебор по байтово через for первый файл.Как только доходит до пробела счетчик останавливается.У нас целое слово в Hex.Переходим к перебору второго файла по байтово до пробела.останавливаем перебор.Сравниваем оба слова если есть разница в кол-ве байт Записываем позицию и слова в таблицу.Дописываем недостающие байты пробелами в первый файл и дальше перебор с новой позиции.Так нельзя?

Редактировалось 1 раз(а), последний 2021-10-18 14:14:34
карма: 0

0
25
Сообщение
...
Прикрепленные файлы
(файлы не залиты)