Расчет контрольной суммы CRC

Обсуждение вопросов автоматизации Total Commander с помощью сторонних программ и скриптовых технологий.

Модераторы: Моторокер, Avada, CaptainFlint, Nik, d-view

Andruxa
Сообщения: 3
Зарегистрирован: Вс июн 21, 2009 18:38

Расчет контрольной суммы CRC

Сообщение Andruxa »

Здравствуйте.
При работе с Total Commander возникла следующая необходимость.
При расчете контрольной суммы, чтобы имя архива и сама контрольная сумма автоматом копировалась в Excel (Например в ячейку A1).
С помощью чего это можно реализовать?

[mod="Моторокер"]Перенесено в Автоматизацию - просто средствами Тотала это не сделать.[/mod]
Аватара пользователя
Batya
Сообщения: 2237
Зарегистрирован: Ср дек 15, 2004 09:51
Откуда: Москва, Россия

Сообщение Batya »

vbs-скрипт:

Код: Выделить всё

'====================================================================================
' Подсчет CRC32 у файлов из файла-списка. Сохранение CRC32 в excel-файле.

' Параметры скрипта:
'   {файл-список} {excel-файл}

' Для работы скрипта необходимо зарегистрировать в системе компонент DynamicWrapperX
'====================================================================================
Option Explicit
'=============== Изменяемые параметры ===============================================
Const StartCell = "A1" 'Первая ячейка таблицы
'====================================================================================

Dim WRP, FSO, WSH, Mess, FileList, XlsFile, FCrc, F, K, objXL, i, j
Set FSO = CreateObject("Scripting.FileSystemObject")
Set WSH = CreateObject("WScript.Shell")
Set WRP = CreateObject("DynamicWrapperX")
WRP.Register "ImageHlp.DLL", "MapFileAndCheckSum", "i=sUU", "r=u"

MessDefine
CheckParams

Set FCrc = CreateObject("Scripting.Dictionary")
For Each F In Split(FSO.OpenTextFile(FileList).ReadAll, vbNewLine)
  If F <> "" Then
    F = GetPath(F)
    If Not FCrc.Exists(F) Then FCrc.Add F, GetCrc(F)
  End If
Next

Set objXL = WScript.CreateObject("Excel.Application")
objXL.Workbooks.Open XlsFile
i = objXL.Range(StartCell).Row
j = objXL.Range(StartCell).Column

For Each K In FCrc.Keys
  objXL.Cells(i,j  ).Value = K
  objXL.Cells(i,j+1).Value = FCrc(K)
  i = i + 1
Next

'Сохранение результатов
objXL.Application.ActiveWorkbook.Save
objXL.Quit()

MsgBox Mess(5), vbInformation + vbOKOnly, Mess(0)
Quit

'===== Процедуры и функции ===============================================================
'Проверка входных параметров
Sub CheckParams
  With WScript
    If .Arguments.Count = 0 Then
      MsgBox Mess(1), vbCritical + vbOKOnly, Mess(0)
      Quit
    End If
    FileList = GetPath(.Arguments(0))
    If Not FSO.FileExists(FileList) Then
      MsgBox Mess(2), vbCritical + vbOKOnly, Mess(0)
      Quit
    End If
    If .Arguments.Count < 2 Then
      MsgBox Mess(3), vbCritical + vbOKOnly, Mess(0)
      Quit
    End If
    XlsFile = GetPath(.Arguments(1))
    If Not FSO.FileExists(XlsFile) Then
      MsgBox Mess(4), vbCritical + vbOKOnly, Mess(0)
      Quit
    End If
  End With
End Sub

'Подсчет контрольной суммы файла
Function GetCrc(pPath)
  Dim lRess, lsHeader, lsCalcd
  lsHeader = 0: lsCalcd = 0
  lRess = WRP.MapFileAndCheckSum(pPath, lsHeader, lsCalcd)
  GetCrc = lsCalcd
End Function

'Путь
Function GetPath(pPath)
  GetPath = FSO.GetAbsolutePathName(WSH.ExpandEnvironmentStrings(pPath))
End Function

'Описание сообщений
Sub MessDefine
  Set Mess = CreateObject("Scripting.Dictionary")
  With Mess
    .Add 0,  "Подсчет CRC32"
    .Add 1,  "Не указаны параметры!"
    .Add 2,  "Файл-список не существует!"
    .Add 3,  "Указаны не все параметры!"
    .Add 4,  "Excel-файл не существует!"
    .Add 5,  "Операция завершена."
  End With
End Sub

'Выход
Sub Quit
  Set objXL = Nothing
  Set Mess  = Nothing
  Set FCrc  = Nothing
  Set WRP   = Nothing
  Set WSH   = Nothing
  Set FSO   = Nothing
  WScript.Quit
End Sub
Для работы скрипта необходим DynamicWrapperX.

Для работы скрипта по выделенным файлам в TC первым параметром нужно указать %L, вторым - имя существующего Excel-файла, в который сбрасываются результаты.
Нет, я не сплю. Я просто медленно моргаю.
Аватара пользователя
Volniy
Сообщения: 585
Зарегистрирован: Ср дек 15, 2004 00:17
Откуда: Местный

Сообщение Volniy »

Batya, а с чего ты вообще решил, что MapFileAndCheckSum выдает результатом CRC32? Насколько мне это известно - это вообще какая-то левая (т.е. недокументированная) контрольная сумма.
Аватара пользователя
Batya
Сообщения: 2237
Зарегистрирован: Ср дек 15, 2004 09:51
Откуда: Москва, Россия

Сообщение Batya »

Нет, я не сплю. Я просто медленно моргаю.
Andruxa
Сообщения: 3
Зарегистрирован: Вс июн 21, 2009 18:38

Сообщение Andruxa »

Batya писал(а):vbs-скрипт:

Код: Выделить всё

'====================================================================================
' Подсчет CRC32 у файлов из файла-списка. Сохранение CRC32 в excel-файле.

' Параметры скрипта:
'   {файл-список} {excel-файл}

' Для работы скрипта необходимо зарегистрировать в системе компонент DynamicWrapperX
'====================================================================================
Option Explicit
'=============== Изменяемые параметры ===============================================
Const StartCell = "A1" 'Первая ячейка таблицы
'====================================================================================

Dim WRP, FSO, WSH, Mess, FileList, XlsFile, FCrc, F, K, objXL, i, j
Set FSO = CreateObject("Scripting.FileSystemObject")
Set WSH = CreateObject("WScript.Shell")
Set WRP = CreateObject("DynamicWrapperX")
WRP.Register "ImageHlp.DLL", "MapFileAndCheckSum", "i=sUU", "r=u"

MessDefine
CheckParams

Set FCrc = CreateObject("Scripting.Dictionary")
For Each F In Split(FSO.OpenTextFile(FileList).ReadAll, vbNewLine)
  If F <> "" Then
    F = GetPath(F)
    If Not FCrc.Exists(F) Then FCrc.Add F, GetCrc(F)
  End If
Next

Set objXL = WScript.CreateObject("Excel.Application")
objXL.Workbooks.Open XlsFile
i = objXL.Range(StartCell).Row
j = objXL.Range(StartCell).Column

For Each K In FCrc.Keys
  objXL.Cells(i,j  ).Value = K
  objXL.Cells(i,j+1).Value = FCrc(K)
  i = i + 1
Next

'Сохранение результатов
objXL.Application.ActiveWorkbook.Save
objXL.Quit()

MsgBox Mess(5), vbInformation + vbOKOnly, Mess(0)
Quit

'===== Процедуры и функции ===============================================================
'Проверка входных параметров
Sub CheckParams
  With WScript
    If .Arguments.Count = 0 Then
      MsgBox Mess(1), vbCritical + vbOKOnly, Mess(0)
      Quit
    End If
    FileList = GetPath(.Arguments(0))
    If Not FSO.FileExists(FileList) Then
      MsgBox Mess(2), vbCritical + vbOKOnly, Mess(0)
      Quit
    End If
    If .Arguments.Count < 2 Then
      MsgBox Mess(3), vbCritical + vbOKOnly, Mess(0)
      Quit
    End If
    XlsFile = GetPath(.Arguments(1))
    If Not FSO.FileExists(XlsFile) Then
      MsgBox Mess(4), vbCritical + vbOKOnly, Mess(0)
      Quit
    End If
  End With
End Sub

'Подсчет контрольной суммы файла
Function GetCrc(pPath)
  Dim lRess, lsHeader, lsCalcd
  lsHeader = 0: lsCalcd = 0
  lRess = WRP.MapFileAndCheckSum(pPath, lsHeader, lsCalcd)
  GetCrc = lsCalcd
End Function

'Путь
Function GetPath(pPath)
  GetPath = FSO.GetAbsolutePathName(WSH.ExpandEnvironmentStrings(pPath))
End Function

'Описание сообщений
Sub MessDefine
  Set Mess = CreateObject("Scripting.Dictionary")
  With Mess
    .Add 0,  "Подсчет CRC32"
    .Add 1,  "Не указаны параметры!"
    .Add 2,  "Файл-список не существует!"
    .Add 3,  "Указаны не все параметры!"
    .Add 4,  "Excel-файл не существует!"
    .Add 5,  "Операция завершена."
  End With
End Sub

'Выход
Sub Quit
  Set objXL = Nothing
  Set Mess  = Nothing
  Set FCrc  = Nothing
  Set WRP   = Nothing
  Set WSH   = Nothing
  Set FSO   = Nothing
  WScript.Quit
End Sub
Для работы скрипта необходим DynamicWrapperX.

Для работы скрипта по выделенным файлам в TC первым параметром нужно указать %L, вторым - имя существующего Excel-файла, в который сбрасываются результаты.
Можно поподробнее про установку.
Это макрос?
Что куда вставлять? спасибо
Аватара пользователя
Batya
Сообщения: 2237
Зарегистрирован: Ср дек 15, 2004 09:51
Откуда: Москва, Россия

Сообщение Batya »

Andruxa
Сразу хочу попросить - не нужно лишнего цитирования. Повторение скрипта в цитате выглядит слишком неуместно.

Инструкция:
1. Скачай по ссылке DynamicWrapperX.
2. Установи этот компонент, как написано в инструкции к нему.
3. Сохрани код скрипта в текстовый файл с расширением vbs.
4. Перетащи получившийся файл на панель TC - получится кнопка.
5. На кнопке нажми правую кнопку мыши -> Изменить. В строке "Параметры" напиши

Код: Выделить всё

%L "{полный путь к Excel-файлу}"
где вместо {полный путь к Excel-файлу} укажи свой путь к тому Excel-файлу, в котором нужно сохранить результаты. (Внимание! В момент выполнения скрипта Excel-файл НЕ должен быть открыт.) -> ОК
6. Выдели архивы, контрольные суммы которых нужно посчитать.
7. Нажми кнопку.
8. После сообщения о выполнении операции открой Excel-файл. В первом столбце будет полный путь к файлу, во втором - контрольная сумма.

Однако, по сообщению Volniy мой скрипт, может быть, считает совсем не CRC32, а какую-то недокументированную контрольную сумму.
Нет, я не сплю. Я просто медленно моргаю.
Andruxa
Сообщения: 3
Зарегистрирован: Вс июн 21, 2009 18:38

Сообщение Andruxa »

Batya писал(а):Andruxa
Сразу хочу попросить - не нужно лишнего цитирования. Повторение скрипта в цитате выглядит слишком неуместно.

Инструкция:
1. Скачай по ссылке DynamicWrapperX.
2. Установи этот компонент, как написано в инструкции к нему.
3. Сохрани код скрипта в текстовый файл с расширением vbs.
4. Перетащи получившийся файл на панель TC - получится кнопка.
5. На кнопке нажми правую кнопку мыши -> Изменить. В строке "Параметры" напиши

Код: Выделить всё

%L "{полный путь к Excel-файлу}"
где вместо {полный путь к Excel-файлу} укажи свой путь к тому Excel-файлу, в котором нужно сохранить результаты. (Внимание! В момент выполнения скрипта Excel-файл НЕ должен быть открыт.) -> ОК
6. Выдели архивы, контрольные суммы которых нужно посчитать.
7. Нажми кнопку.
8. После сообщения о выполнении операции открой Excel-файл. В первом столбце будет полный путь к файлу, во втором - контрольная сумма.

Однако, по сообщению Volniy мой скрипт, может быть, считает совсем не CRC32, а какую-то недокументированную контрольную сумму.
Спасибо с установкой разобрался.
Я так понимаю он считает в десятичной системе. А можно в шестнадцатеричную? в ТС Есть ведь расчет контрольной суммы нельзя его програмно поправить, чтобы он сохранял в Excel ?
Аватара пользователя
Tol!k
Сообщения: 1727
Зарегистрирован: Вт апр 01, 2008 20:02
Откуда: Арзамас

Сообщение Tol!k »

Andruxa
Способ 1
настрой свой набор колонок с использованием crc32tag.wdx и разделителями ',' или ';';
сохрани содержимое колонок в текстовый файл с расширением .CSV;
открой .CSV в Excel
Способ 2
подправь готовую схему "Directory -> CSV" в плагине WdxInfoPacker.wcx, чтобы она сохраняла и значение CRC.
Например:

Код: Выделить всё

[Directory -> CSV (+CRC32)]
use="abcdeh"
Extension=".csv"
Divider=","
header="File,Size,Date,CRC32"
before="%N"
name="@Mod=size.kbytes@filesys.wdx; kB"
between="@Mod=writedate@filesys.wdx; ;@Mod=writetime.h:m@filesys.wdx;"
wdxinfo="@Mod=GetCrc32FromFile.NoBrackets@crc32tag.wdx;"
DoNotWriteEmpty=1
SaveErrorLog=1
MaxRight=12
X-myRzA
Сообщения: 3
Зарегистрирован: Пт окт 15, 2010 15:51

Сообщение X-myRzA »

Добрый день.
Как можно реализовать такую функцию.
Есть каталог файлами и папками, файлы упакованы через lzma архиватор. Теперь над вытащить информацию: filename="файл" checksum="crc32_сумма_упак_файл", original="crc32_сумма_ориг_файл", size="размер_ориг_файла" и информацию выгрузить в xml файл.
по этому порядку:

Код: Выделить всё

<list>
<archive filename="file.exe" checksum="46FAA0C9" original="68C6D920" size="45056"/>
***
</list>
Можно сделать? :) [/quote]
Последний раз редактировалось X-myRzA Сб окт 16, 2010 09:59, всего редактировалось 1 раз.
Аватара пользователя
Batya
Сообщения: 2237
Зарегистрирован: Ср дек 15, 2004 09:51
Откуда: Москва, Россия

Сообщение Batya »

X-myRzA
Тот механизм, который используется в приведённом здесь скрипте, предполагает наличие файла, для которого считается CRC32-сумма. Других возможностей я не знаю. Т.е. для описанной задачи придётся всё распаковывать (создавать временные файлы).
Нет, я не сплю. Я просто медленно моргаю.
X-myRzA
Сообщения: 3
Зарегистрирован: Пт окт 15, 2010 15:51

Сообщение X-myRzA »

Можно создать временные файлы или можно взять сразу два каталога, один упакованный другой оригинал. Только надо информацию выгрузить в xml файл.
Аватара пользователя
Batya
Сообщения: 2237
Зарегистрирован: Ср дек 15, 2004 09:51
Откуда: Москва, Россия

Сообщение Batya »

X-myRzA писал(а):... или можно взять сразу два каталога, один упакованный другой оригинал.
Ну так, если есть незапакованый оригинал, то всё просто.

Добавлено:
А как соотнести имя файла и имя архива?
Т.е., предположим, что есть файл-список архивов. Варианты:
1. Оригинальные файлы искать в определённой папке? Тогда какие имена у оригинальных файлов?
2. Или существует соответствующий (соответствие по строкам) файл-список оригинальных файлов?
Нет, я не сплю. Я просто медленно моргаю.
Аватара пользователя
Tol!k
Сообщения: 1727
Зарегистрирован: Вт апр 01, 2008 20:02
Откуда: Арзамас

Сообщение Tol!k »

X-myRzA
На форуме бывает человек, знакомый с LZMA-сжатием . Попробуй попросить его написать WDX-плагин или консольную утилиту для получения контрольных сумм.
Аватара пользователя
Tol!k
Сообщения: 1727
Зарегистрирован: Вт апр 01, 2008 20:02
Откуда: Арзамас

Сообщение Tol!k »

Оказывается, консольные версии 7z умеют показывать CRC файлов
-slt (Show technical information) switch
Sets technical mode for l (List) command.

Example
7z l -slt archive.7z
Аватара пользователя
Flasher
Сообщения: 14229
Зарегистрирован: Пт ноя 06, 2009 00:33
Откуда: Москва

Сообщение Flasher »

Вспомнилось. В обсуждении с SVM тут и тут была мысль написать аналог рекурсивного создания файлов с размерами только уже с CRC. Вот что вышло:

Код: Выделить всё

'===================================================================================
' Создание/перезапись хэш-файла в активном каталоге или в каждой ветви его структуры
' Ссылка на утилиту RHash: http://sourceforge.net/projects/rhash/files/rhash/

' Условия: путь запуска - пустой;
'          положить в каталог программы 64-битную версию с именем rhash64.exe

' Параметры: <хэш-формат> <маска расширения> <не/включать рекурсию: 0/1>
' Хэш-формат: crc32, md4, md5, sha1, sha-224, sha-256, sha-384, sha-512, sha3-224,
' sha3-256, sha3-384, sha3-512, tiger, tth, has160, aich, ed2k, gost-cryptopro,
' gost, btih, ripemd160, whirlpool, snefru128, snefru256, edon-r256, edon-r512

' Примеры:  md5 *.* 0  |  sha1 *.avi 1

' Автор: Flasher ©
'===================================================================================
Option Explicit
Dim RHash, Alg, Filt, Test, ShA, Ext, Ps, Flt, FN, Title, Path, F, Items, Sum, Fold
'========================== Путь к утилите RHash (32 bit) ==========================
RHash = """%COMMANDER_PATH%\Utils\RHash\rhash.exe"""
'===================================================================================
With WScript.Arguments Alg = .Item(0) : Filt = .Item(1) : Test = .Item(2) End With
Dim C(2), WSH : Set WSH = CreateObject("WScript.Shell")
Ext = Alg : Set ShA = CreateObject("Shell.Application")
Select Case Alg : Case "crc32" Ext = "sfv" : Case "sha1" Ext = "sha" End Select
If InStr(Alg, "sha-") Then Ext = "sha" & Mid(Alg, 5)
If Filt <> "*.*" Then Ps = UCase(Mid(Filt,3)) : Flt = "_for_" & Ps Else Ps = "(объекты)"
If WSH.Environment("System")("PROCESSOR_ARCHITECTURE") = "AMD64" Then _
RHash = Left(RHash, InStrRev(RHash, ".") - 1) & "64.exe"""
ForFolder WSH.CurrentDirectory, FN : Title = " Создание CRC-файлов " & Ucase(Ext)
If C(0) = "" Then
  MsgBox "Файлы " & Ps & " отсутствуют!", 48, Title
ElseIf C(0) = 1 And C(1) = "" Then WSH.Run """%COMMANDER_EXE%"" /O /S /L=""" & FN & """"
Else MsgBox Ucase(Ext) & "-файлов:" & String(2, vbTab) & C(0) & vbCr &_
"Контрольных сумм:" & vbTab & C(2), 64, Title & " (результат) :" End If

Sub ForFolder(Path, F)
  Set Items = ShA.NameSpace(Path).Items
  Items.Filter  64, "*." & Ext
  If Items.Count = 1 And Filt = "*.*" Then _
  F = Items.Item(0).Path Else F = Path & "\Checksum" & Flt & "." & Ext
  Items.Filter 192, Filt : Sum = Items.Count
  If Sum Then
    Items.Filter 64, Right(F, Len(F) - InStrRev(F,"\")): If Items.Count Then Sum = Sum - 1
    WSH.Run RHash &_
    " -i -p""%{" & Alg & "} *%f\n"" -o""" & F & """ """ & Path &"\" & Filt & """", 0, True
    With CreateObject("ADODB.Stream")
      .Open : .CharSet = "UTF-8" : .LoadFromFile F : .Type = 1 : .SaveToFile F, 2 : .Close
    End With : C(0) = C(0) + 1 : C(2) = C(2) + Sum
  End If
  If Test Then
    Items.Filter 160, "*"
    If Items.Count Then C(1) = 1 : For Each Fold in Items : ForFolder Fold.Path, F : Next
  End If
End Sub
Для TC, как известно, актуальны: crc32, md5, sha1, sha-256, sha-512. Поддерживаются имена с Юникодом.
+ Автопереход к корневому CRC-файлу при отключённой рекурсии.
К сожалению, обновление по --update отпало, RHash косячит, дописывая суммы во все соседние текстовые файлы.
Автору сборки TC Image (Andrey_A) настоятельно рекомендуется не распространять на иных ресурсах любую предоставленную мной где-либо техническую информацию по автоматизации и оптимизации в работе с ТС и системой.
Ответить