CRC32: Дополнить файл для получения контрольной суммы FFFFFFFF - VB
Формулировка задачи:
Привет!
Имеется произвольный бинарный файл.
Цель: дополнить его как можно меньшим кол-вом байт, чтобы его КС по CRC32 стала = FFFFFFFF.
Можете для меня такое сочинить?
P.S. Долгое время пользуюсь модулем подсчета CRC32 от Catstail, который меня не подводил.
Настало время чего то более сложного. Т.к. не математик, сам такого боюсь не сделаю.
Решение задачи: «CRC32: Дополнить файл для получения контрольной суммы FFFFFFFF»
textual
Листинг программы
Option Explicit Const poly As Long = &HEDB88320 Public Declare Function Mul Lib "msvbvm60.dll" Alias "_allmul" (ByVal dw1 As Long, ByVal Reserved As Long, ByVal dw3 As Long, ByVal Reserved As Long) As Long Dim Tab_CRC(255) As Long Dim pTable(255) As Long Sub Make_CRC_32_Table() Dim bx&, cx&, eax& For bx = 0& To 255& eax = bx For cx = 0& To 7& If (eax And 1) Then eax = ((eax And &HFFFFFFFE) \ 2&) And &H7FFFFFFF 'eax >> 1 eax = eax Xor poly Else eax = ((eax And &HFFFFFFFE) \ 2&) And &H7FFFFFFF End If Next Tab_CRC(bx) = eax pTable(((eax And &HFF000000) \ &H1000000) And &HFF) = bx Next End Sub Sub SplitInto4bytes(Src As Long, bit3 As Byte, bit2 As Byte, bit1 As Byte, bit0 As Byte) bit3 = ((Src And &HFF000000) \ &H1000000) And &HFF bit2 = ((Src And &HFF0000) \ &H10000) And &HFF bit1 = ((Src And &HFF00) \ &H100) And &HFF bit0 = Src And &HFF End Sub Public Sub RecoverCRC() Dim oldCRC&, newCRC&, ChkCRC&, a(3) As Byte, b(3) As Byte, c(3) As Byte, d(3) As Byte, e(3) As Byte, f(3) As Byte, r(3) As Byte, i& Dim InitStri$, NewStri$, PatchAddr&, ForwardCRC&, BackwardCRC&, AddBytes$ ' Исходные данные InitStri = "Some Data" ' Указать адрес для добавочных (или заменяемых) байтов (считаем с нуля). PatchAddr = Len(InitStri) 'Len(InitStri) - пишем в конец If PatchAddr > Len(InitStri) Then Err.Raise 14 Make_CRC_32_Table ' Какую КС нужно получить newCRC = &H12345678 oldCRC = CalcCRC(InitStri) Debug.Print "Initial CRC: " & Hex(oldCRC) Debug.Print "New CRC: " & Hex(newCRC) ForwardCRC = CalcCRC(Left$(InitStri, PatchAddr)) Xor -1 BackwardCRC = newCRC Xor -1 If (PatchAddr + 4) < Len(InitStri) Then BackwardCRC = CalcCRCReverse(Right$(InitStri, Len(InitStri) - (PatchAddr + 4)), BackwardCRC) SplitInto4bytes ForwardCRC, a(3), a(2), a(1), a(0) SplitInto4bytes BackwardCRC, f(3), f(2), f(1), f(0) e(3) = f(3): SplitInto4bytes Tab_CRC(pTable(e(3))), e(3), e(2), e(1), e(0) d(3) = f(2) Xor e(2): SplitInto4bytes Tab_CRC(pTable(d(3))), d(3), d(2), d(1), d(0) c(3) = f(1) Xor e(1) Xor d(2): SplitInto4bytes Tab_CRC(pTable(c(3))), c(3), c(2), c(1), c(0) b(3) = f(0) Xor e(0) Xor d(1) Xor c(2): SplitInto4bytes Tab_CRC(pTable(b(3))), b(3), b(2), b(1), b(0) r(3) = pTable(b(3)) Xor a(0) r(2) = pTable(c(3)) Xor b(0) Xor a(1) r(1) = pTable(d(3)) Xor c(0) Xor b(1) Xor a(2) r(0) = pTable(e(3)) Xor d(0) Xor c(1) Xor b(2) Xor a(3) AddBytes = Chr$(r(3)) & Chr$(r(2)) & Chr$(r(1)) & Chr$(r(0)) ' Вставляем корректирующие байты в исходную строку NewStri = InitStri If PatchAddr - Len(InitStri) + 4 > 0 Then NewStri = NewStri & Space$(PatchAddr - Len(InitStri) + 4) Mid(NewStri, PatchAddr + 1) = Chr$(r(3)) & Chr$(r(2)) & Chr$(r(1)) & Chr$(r(0)) ' Контрольная проверка КС ChkCRC = CalcCRC(NewStri) ' Если КС не совпадает If ChkCRC <> newCRC Then Err.Raise 17 Debug.Print "Check CRC: " & Hex(ChkCRC) Debug.Print "Исходная строка: " & InitStri Debug.Print "Новая строка: " & NewStri Debug.Print "Адрес для вставки: " & PatchAddr Debug.Print "Корректирующие байты: " & Hex(Mul(r(3), 0, &H1000000, 0) Or Mul(r(2), 0, &H10000, 0) Or Mul(r(1), 0, &H100, 0) Or r(0)) End End Sub Public Function CalcCRC(Stri As String) As Long Dim CRC&, i&, m&, n& If Tab_CRC(1) = 0 Then Make_CRC_32_Table CRC = -1 For i = 1& To Len(Stri) m = Asc(Mid$(Stri, i, 1&)) n = (CRC Xor m) And &HFF& CRC = (Tab_CRC(n) Xor (((CRC And &HFFFFFF00) \ &H100) And &HFFFFFF)) And -1 ' Tab ^ (crc >> 8) Next CalcCRC = -(CRC + 1&) End Function Public Function CalcCRCReverse(Stri As String, Optional nextValue As Long = -1) As Long Dim CRC&, i&, m&, n&, prevValueL&, prevValueH&, b3 As Byte If Tab_CRC(1) = 0 Then Make_CRC_32_Table CRC = nextValue For i = Len(Stri) To 1 Step -1 m = Asc(Mid$(Stri, i, 1&)) b3 = ((CRC And &HFF000000) \ &H1000000) And &HFF prevValueL = (pTable(b3) Xor m) And &HFF prevValueH = Mul(CRC Xor Tab_CRC(pTable(b3)), 0, &H100, 0) ' << 8 CRC = prevValueH Or prevValueL Next CalcCRCReverse = CRC End Function
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д