Оптимальный способ расчета контрольной суммы объекта/записи регистра (CRC32, MD5, SHA1, SHA256)

01.06.23

Разработка - Инструментарий разработчика

Была задача сравнить документы в распределенных базах и пометить на выгрузку измененные. Но сравнение изменений документов методом перебора реквизитов - долгоиграющий процесс, особенно если общее количество сравниваемых данных переваливает за миллион. Был найден выход, который ускоряет процесс сравнения - расчет контрольной суммы объекта и сравнение ее с другой контрольной суммой. Скорость сравнения увеличивается во много раз.

Скачать файл

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование По подписке [?] Купить один файл
Контрольная сумма объекта
.epf 5,96Kb
10
10 Скачать (1 SM) Купить за 1 850 руб.

В данной обработке приведен способ расчета контрольной суммы объекта базы данных 1С. При любом изменении данных объекта, контрольная сумма меняется. Вариант расчета контрольной суммы меняем программно. В моем случае CRC32 как раз подходит - это число.

Это может быть полезно:

  • При сравнении документов в различных базах, и не только РИБ
  • В механизме определения, изменен ли объект в журналах изменений.
  • В тех областях, о которых я еще не знаю.

Вот сам код обработки:

&НаСервере
Процедура Рассчитать()
    Объект=Ссылка.ПолучитьОбъект();
	ПолучитьХешОбъекта(Объект);
КонецПроцедуры

&НаСервере
Процедура ПолучитьХешОбъекта(Объект)
	ЗаписьXML = Новый ЗаписьXML;
	ЗаписьXML.УстановитьСтроку();
	
	СериализаторXDTO.ЗаписатьXML(ЗаписьXML,Объект);
	ДанныеСтрока=ЗаписьXML.Закрыть();
	
	Хеш=Новый ХешированиеДанных(ХешФункция.CRC32);
	Хеш.Добавить(ДанныеСтрока);
	
	Сообщить(Хеш.ХешСумма);
КонецПроцедуры

Обновлено от 03.08.2016! Если нужно получить контрольную сумму ссылочного объекта, то код выше это делает. Если нужно получить контрольную сумму записей регистров сведений, например, то лучше использовать либо наборы записей (медленный способ), либо получить данные записей запросом, и каждую запись преобразовать в структуру, и уже ее использовать для расчета контрольной суммы (быстрый способ). 

Вот примерный код:

СтрокаИзмерений="";

Для каждого Измерение Из ОбъектМетаданных.Измерения Цикл
	СтрокаИзмерений=СтрокаИзмерений+?(ПустаяСтрока(СтрокаИзмерений),Измерение.Имя,","+Измерение.Имя);
КонецЦикла;

Если ОбъектМетаданных.ПериодичностьРегистраСведений<>Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.Непериодический Тогда
	СтрокаИзмерений=СтрокаИзмерений+?(ПустаяСтрока(СтрокаИзмерений),"Период",",Период");	 
КонецЕсли;

Для каждого Ресурс Из ОбъектМетаданных.Ресурсы Цикл
	СтрокаИзмерений=СтрокаИзмерений+?(ПустаяСтрока(СтрокаИзмерений),Ресурс.Имя,","+Ресурс.Имя);
КонецЦикла;

Для каждого Реквизит Из ОбъектМетаданных.Реквизиты Цикл
	СтрокаИзмерений=СтрокаИзмерений+?(ПустаяСтрока(СтрокаИзмерений),Реквизит.Имя,","+Реквизит.Имя);
КонецЦикла;

СтруктураДанных=Новый Структура(СтрокаИзмерений);

Выборка=РегистрыСведений[Имя].Выбрать();

Пока Выборка.Следующий() Цикл
	ЗаполнитьЗначенияСвойств(СтруктураДанных,Выборка);
	ХешСумма=ПолучитьХешОбъекта(СтруктураДанных);
КонецЦикла;

Обновлено от 09.08.2016! Как показала практика, применение способа ПолучитьОбъект() для расчета контрольной суммы не всегда оптимально (если много объектов и немного оперативной памяти) и приводит к нехватке памяти т.к. полученные объекты не удаляются из оперативной памяти, а остаются там до окончания процесса. Код вида "Объект=Неопределено"  никогда не помогает!

Был найден обходной путь, через запрос. При этом память не забивается, а скорость даже возросла.

Вот пример кода для документов:

Запрос = Новый Запрос;
Запрос.Текст ="ВЫБРАТЬ * ИЗ "+ОбъектМетаданных.ПолноеИмя(); 
				
Результат=Запрос.Выполнить();
Выборка=Результат.Выбрать();
			
СтрокаРеквизитов="";
Для каждого Колонка Из Результат.Колонки Цикл
	Если Колонка.Имя="ВерсияДанных" ИЛИ Колонка.Имя="МоментВремени" ИЛИ Колонка.Имя="Предсталение" Тогда Продолжить; КонецЕсли;
	
    СтрокаРеквизитов=СтрокаРеквизитов+?(ПустаяСтрока(СтрокаРеквизитов),"",",")+Колонка.Имя;
КонецЦикла;
			
СтруктураОбъекта=Новый Структура(СтрокаРеквизитов);
			
Пока Выборка.Следующий() Цикл
	ЗаполнитьЗначенияСвойств(СтруктураОбъекта,Выборка);
	Для каждого ТабЧасть Из ОбъектМетаданных.ТабличныеЧасти Цикл
		 СтруктураОбъекта.Вставить(ТабЧасть.Имя,Выборка[ТабЧасть.Имя].Выгрузить()); 
	КонецЦикла; 
	ХешСумма=ПолучитьХешОбъекта(СтруктураОбъекта);
КонецЦикла;

Функция ПолучитьХешОбъекта(Объект)
	ЗаписьXML = Новый ЗаписьXML;
	ЗаписьXML.УстановитьСтроку();
	
	СериализаторXDTO.ЗаписатьXML(ЗаписьXML,Объект);
	ДанныеСтрока=ЗаписьXML.Закрыть();
	
	Хеш=Новый ХешированиеДанных(ХешФункция.CRC32);
	Хеш.Добавить(ДанныеСтрока);
	
	Возврат Хеш.ХешСумма;
КонецФункции;

 

контрольная сумма CRC32 MD5 SHA1 SHA256 объект изменения

См. также

SALE! 15%

Инструментарий разработчика Роли и права Запросы СКД Программист Платформа 1С v8.3 Управляемые формы Запросы Система компоновки данных Конфигурации 1cv8 Платные (руб)

Набор инструментов программиста и специалиста 1С для всех конфигураций на управляемых формах. В состав входят инструменты: Консоль запросов, Консоль СКД, Консоль кода, Редактор объекта, Анализ прав доступа, Метаданные, Поиск ссылок, Сравнение объектов, Все функции, Подписки на события и др. Редактор запросов и кода с раскраской и контекстной подсказкой. Доработанный конструктор запросов тонкого клиента. Продукт хорошо оптимизирован и обладает самым широким функционалом среди всех инструментов, представленных на рынке.

10000 руб.

02.09.2020    159371    872    399    

861

SALE! 15%

Инструментарий разработчика Чистка данных Свертка базы Инструменты администратора БД Системный администратор Программист Руководитель проекта Платформа 1С v8.3 Конфигурации 1cv8 1С:Управление торговлей 10 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 Россия Платные (руб)

Инструмент представляет собой обработку для проведения свёртки или обрезки баз данных. Работает на ЛЮБЫХ конфигурациях (УТ, БП, ERP и т.д.). Поддерживаются управляемые и обычные формы. Может выполнять свертку сразу нескольких баз данных и выполнять их автоматически без непосредственного участия пользователя.

8400 7140 руб.

20.08.2024    7763    55    22    

66

Инструментарий разработчика Программист Платформа 1С v8.3 Конфигурации 1cv8 Платные (руб)

Инструмент для написания и отладки кода в режиме «1С:Предприятие». Представляет собой консоль кода с возможностью пошаговой отладки, просмотра значений переменных любых типов, использования процедур и функций, просмотра стека вызовов, вычисления произвольных выражений на встроенном языке в контексте точки останова, синтаксического контроля и остановки по ошибке. В консоли используется удобный редактор кода с подсветкой, контекстной подсказкой, возможностью вызова конструкторов запроса и форматной строки.

9360 руб.

17.05.2024    23426    68    45    

117

SALE! 15%

Инструменты администратора БД Инструментарий разработчика Роли и права Программист Платформа 1С v8.3 Конфигурации 1cv8 Россия Платные (руб)

Расширение позволяет без изменения кода конфигурации выполнять проверки при вводе данных, скрывать от пользователя недоступные ему данные, выполнять код в обработчиках. Не изменяет данные конфигурации, легко устанавливается практически на любую конфигурацию на управляемых формах.

10000 8500 руб.

10.11.2023    10412    36    20    

61

SALE! 15%

Пакетная печать Печатные формы Инструментарий разработчика Программист Платформа 1С v8.3 Запросы 1С:Зарплата и кадры бюджетного учреждения 1С:Конвертация данных 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 Платные (руб)

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

22200 19980 руб.

06.10.2023    15393    35    7    

70

SALE! 35%

Инструментарий разработчика Инструменты администратора БД Системный администратор Программист Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Россия Платные (руб)

Универсальный инструмент программиста для администрирования конфигураций. Сборник наиболее часто используемых обработок под единым интерфейсом.

4800 3120 руб.

14.01.2013    187969    1138    0    

912

SALE! 15%

Инструментарий разработчика Программист 8.3.14 1С:Конвертация данных Россия Платные (руб)

Расширение для конфигурации “Конвертация данных 3”. Добавляет подсветку синтаксиса, детальную контекстную подсказку, глобальный поиск по коду.

15000 12750 руб.

07.10.2021    17299    6    32    

42

Инструментарий разработчика Программист Платные (руб)

Менеджер конфигураций 1С — альтернативный стартер информационных баз 1С:Предприятие.

1800 руб.

21.02.2023    7694    8    35    

23
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. klinval 343 01.08.16 11:50 Сейчас в теме
Не понял в чём суть алгоритма вычисления контрольной суммы?
Или в этом и фишка: скачай обработку, посмотри код и увидишь алгоритм?
2. hakerxp 3108 01.08.16 12:02 Сейчас в теме
(1), в обработке пример расчета контрольной суммы.
3. gubanoff 63 01.08.16 13:08 Сейчас в теме
Неплохо бы в статье рассказать, как и что.
5. ditp 94 01.08.16 13:49 Сейчас в теме
(3) gubanoff,
Ой та шо там рассказывать... получаем некое описание объекта и считаем от него хеш.
Например так:

Функция ХэшДокумента(СсылкаНаДокум)
	Докум	= СсылкаНаДокум.ПолучитьОбъект();
	мтДок	= Докум.Метаданные();
	зап		= Новый ЗаписьXML;
	зап.УстановитьСтроку();
	зап.ЗаписатьНачалоЭлемента("obj");
	зап.ЗаписатьАтрибут("Дата"	, XMLСтрока(Докум.Дата));
	зап.ЗаписатьАтрибут("Номер"	, XMLСтрока(Докум.Номер));
	зап.ЗаписатьАтрибут("Пров"	, XMLСтрока(Докум.Проведен));
	зап.ЗаписатьАтрибут("Удал"	, XMLСтрока(Докум.ПометкаУдаления));
	Для Каждого рекв Из мтДок.Реквизиты Цикл
		зап.ЗаписатьАтрибут(рекв.Имя, XMLСтрока(Докум[рекв.Имя]));
	КонецЦикла;
	Для Каждого тч Из мтДок.ТабличныеЧасти Цикл
		зап.ЗаписатьНачалоЭлемента(тч.Имя);
		Для Каждого стр Из Докум[тч.Имя] Цикл
			зап.ЗаписатьНачалоЭлемента("line");
			Для Каждого рекв из тч.Реквизиты Цикл
				зап.ЗаписатьАтрибут(рекв.Имя, XMLСтрока(стр[рекв.Имя]));
			КонецЦикла;
			зап.ЗаписатьКонецЭлемента();
		КонецЦикла;
		зап.ЗаписатьКонецЭлемента();
	КонецЦикла;
	зап.ЗаписатьКонецЭлемента();

	хеш	= Новый ХешированиеДанных(ХешФункция.SHA1);
	хеш.Добавить(зап.Закрыть());
	
	Возврат хеш.ХешСумма;
КонецФункции
Показать


В примере -- документ, но для всего остального аналогично.
Вместо SHA1 можно использовать CRC, MD5 или SHA256.
6. hakerxp 3108 01.08.16 14:42 Сейчас в теме
(5), сложно у вас написано. Все намного проще. По просьбе трудящихся выкладываю текст.
7. gubanoff 63 01.08.16 16:01 Сейчас в теме
(6) ну вот, все стало понятно. Как и предполагалось, выгрузка в ХМЛ и получение хеша от файла. Эталонный подход :)
8. cleaner_it 209 03.08.16 11:45 Сейчас в теме
(6) (7) gubanoff, тогда непонятно, откуда взялся выигрыш по скорости. Для начала нужно рассчитать хеш для миллионов записей, а это тоже время.
9. hakerxp 3108 03.08.16 12:21 Сейчас в теме
(8), получение объекта или создание структуры данных записи, намного быстрее, чем перебирать реквизиты, измерения, ресурсы и искать отличия. Ну и проще. Приведу пример. У меня система сравнивает данные независимых регистров сведений в различных базах РИБ. Таблица общая получается более 1 млн. записей. Так вот - затраты на создание данной таблица по времени - около 10 мин. в одной базе и столько же в другой. Время сравнения по моему алгоритму - так же 10-15 мин. (больше времени тратится на регистрацию данных для обмена, чем на сравнение). Железо не серверное. База и СУБД пашут на простом жестком, не SSD.
4. davdykin 25 01.08.16 13:48 Сейчас в теме
Действительно, вы бы хоть принцип рассказали, я так понимаю эти алгоритмы считают хэш строк, как вы получаете эту строку
10. Поручик 4692 08.10.21 12:31 Сейчас в теме
У нас CRC32 рассчитывается для прикреплённых файлов при каждом изменении. Нужно для записи в XML с последующей загрузкой куда-то ещё.
Оставьте свое сообщение