Somit wäre die Methode meiner Ersetzungskompression sehr ähnlich, aber wesentlich schneller.
Jetzt noch Kombinationen mit 2, 3, n Bytes rein und die Kompression steigt nochmal an. Einpackzeit wird sich verhunderttausendfachen, Auspackzeit bleibt gleich.
Bsp:
Ersetzungen: 2, 2, 2, 2, 2, usw -> Komp (60%)
Ersetzungen: 3, 2, 2, 2, 2, usw -> Komp (65%)
...
Ersetzungen n, n, n, n, n, usw -> Komp (5%)
Jetzt nach Effizienz sortieren und den Besten anwenden.
![](https://autoit.de/wcf/images/avatars/08/537-0837810d31cd764f0af680dd2f279bbe96a85077.png)
Über die String-Dekompression
-
- [ gelöst ]
-
minx -
9. Februar 2013 um 18:51 -
Erledigt
-
-
Hi,
ZitatJetzt noch Kombinationen mit 2, 3, n Bytes rein und die Kompression steigt nochmal an. Einpackzeit wird sich verhunderttausendfachen, Auspackzeit bleibt gleich.
ja, das ganze habe ich aber schon hinter mir, bzw. verworfen aus einem einfachen Grund:
Mehrfach, d.h. 3er, 4er, 5er usw. -Kombinationen aus unterschiedlichen Token (123abc345abc88abc) kommen idR SEHR selten vor.
Die häufigste vorkommende 3er-Kombination kommt jedenfalls zwangsläufig seltener vor, als die am wenigsten festgestellte (und bereits komprimierte) 2er-Kombination (in abc ist nämlich schon ab enthalten) !
Ich hatte dazu in einer Schleife 3er,4er und 5er Permutationen berechnet und deren Vorkommen im String gezählt (siehe Grund des asm-Scripts)
Durch die etwas höhere Kompressionsrate und reichlich reservierte Token (die dann natürlich für die 2er wieder fehlen^^) kam ich zu einer Kompressionsrate von 49%. Die Laufzeit war allerdings mehrere Stunden, bis ich irgendwann abgebrochen hatte. UEZ komprimiert in seinem Script übrigens bei LZNT in der höchsten Stufe, und das ist kompressionstechnisch kein Stück besser als das AutoIt-Pendant!!!Sinn würde es ggf. machen, die Mehrfachkombis am Anfang zu testen und dann zu komprimieren. Allerdings ist man dann Laufzeittechnisch auch wieder angeschmiert, lediglich die Kompression würde sich verbessern, aber das tut sie ja ohnehin, wenn man die Laufzeit verlängert
Also muss ein Algorithmus her, der mit einfachen Funktionen arbeitet (AND/OR/XOR) oder den bereits komprimierten String nochmal völlig durcheinanderwürfelt (XOR würde sich da anbieten^^ )
Wenn man mit einem wie auch immer produziertem zusätzlichen String XORed und nachher wieder einen sehr gut zu komprimierenden String erhält, dann könnte sich das lohnen.
Mit Zufallsstrings XORen und nachher die Häufigkeit (s. asm-script) ermitteln, geht jedenfalls sauschnell -
Wer Lust hat, kann ja mal hier rein schauen (siehe Anhang) - ist vom 7-Zip Entwickler.
Zitat
UEZ komprimiert in seinem Script übrigens bei LZNT in der höchsten Stufe, und das ist kompressionstechnisch kein Stück besser als das AutoIt-Pendant!!!Ist eben "nur" Built-In.
Gruß,
UEZ -
Eine "Zufällige" Kompression habe ich auch schonmal angetestet.
Allerdings kam ich da nie zu einem fertigen Skript. Vorher hat das Tempo verhindert, dass man es wirklich an ein paar KB testen konnte.nochmal zum Ersetzen: Die 3 ist wahrscheinlich ungünstig, es kommt halt immer darauf an was man komprimiert.
z.B. bei 24 Bit Bitmaps sind 6er sehr häufig, bei 32ern (gibt's häufiger) kann zu Beginn ein Paar Durchläufe mit 8ern machen um die Häufigen Farben schonmal kleinzubekommen.Bei Text wie z.B. diesem Beitrag" Kommen auch einige Wörter/Zeichenkombinationen mehrfach vor. Mit anfänglichen 16Byte Tests macht man idr nichts verkehrt. Im Späteren Kompressionsverlauf sind natürlich alle großen Kombinationen überflüssig. Nach dem 20ten Durchlauf wird man keinen einzigen 16er mehr finden.
Optimal wäre glaube ich eine breite Fächerung zu Beginn (Maximalwert abhängig von einer anfänglichen Redundanzanalyse) die direkt stark abnimmt, bis man bei Runde X nur noch 2er benutzt.
Edit: Wenn bei mir die Klausuren rum sind bastele ich mal ein schönes Skript. Dann schauen wir mal wie 7Zip aussieht
-
hehe....64bit....
Ich wollte damals beim Deskstream einen Huffmann-Baum mit 64Bit bzw sogar 128Bit-Verweisen aufziehen. Das Problem ist aber bei JEDER Implementation das gleiche: Für wenig mehr an Kompression muss man einen gigantischen Aufwand betreiben. Und die gängigen Komprimierer haben ja alle mehrere Verfahren am Start. Und gerade beim Deskstream hat sich gezeigt, dass es eben nicht egal ist, ob man in 20ms oder in 500ms zum Ergebnis kommt! Bei den gängigen Verfahren ist das aber völlig egal! Da gibt es ganz andere Prioritäten! Würde man da nach schnellster Kompressionszeit wählen müssen, würden per se schon 90% der Verfahren aus der Auswahl rausfliegen!Im Deskstream-Thread gibts sogar von mir eine Anleitung, wie man die gängigen Komprimierer einbinden und testen kann...letztendlich hat´s nichts gebracht, sobald die Kompressionsrate verbessert wurde, ist die Zeit unverhältnismässig gestiegen, siehe diesen Thread^^.
Ausserdem sollte das alles noch überschaubar bleiben. Wenn man erkennt, dass man die Codegrösse verhundertfachen muss um 5% besser zu komprimieren, dann lässt man als Hobbycoder die Finger davon^^In OpenCl/OpenGl sollte da noch etwas gehen, aber die gängigen Algorithmen sind nicht sehr gut bzw einfach zu parallelisieren. Für eine Framerate von 25FPS hat man dezente 40ms für den TRANSPORT der Daten (24MB bei 1024x1024x24bpp) übers Netz, und fürs Entpacken. Mal angenommen, 20ms gehen fürs Entpacken drauf, dann hat man 20ms übrig für den Transport der 24MB (die eingestampft auf ein Viertele bleiben 20ms für 6mb) was nach Adam Riese eine Leitung von 300Mb/s entspricht 2400Mbit NETTO. Macht erfahrungsgemäss Brutto locker das doppelte bzw das dreifache.... bei einem Viertel der Full-HD-Auflösung
Ergo kommt man sehr schnell auf den Trichter, dass es heutzutage garkeine Simultan-Übertragung geben kann (für den Otto-Normalverbraucher) und man doch lieber zu einem bis zum Anschlag komprimierten Video greift, dass (s. YT und Konsorten) mit einer bescheidenen Qualität erstmal minutenlang vorgepuffert werden muss. WzBw -
Zitat
Edit: Wenn bei mir die Klausuren rum sind bastele ich mal ein schönes Skript. Dann schauen wir mal wie 7Zip aussieht
Yo, lass uns mal was machen, eine schöne Anwendung für OpenCl wäre noch der Knaller
ZitatMit anfänglichen 16Byte Tests macht man idr nichts verkehrt.
doch^^, ich hatte anfangs auch nach bis zu 30 Byte langen Ketten gesucht. Da ist die Kompressionsrate natürlich gigantisch, aber die kommen definitiv viel zu selten vor....sucht man ab maximal 6-Byte Ketten, verringert sich die Kompressionszeit um die Hälfte! Bei gerade mal ca. 1-2% schlechterer Kompressionsrate! Praktisches Bsp s. oben
Bei Bildern sieht das anders aus, im Deskstream habe ich imho 1024 gleiche Pixel durch 5 Byte ersetzt.... -
Das Erste, was ich bemerkt habe: StringRegExpReplace() ist ca. 6x schneller als StringReplace()
Hier hab ich jetzt aufgehört, weiterzulesen. Verzeiht also, wenn das dann doch schon gepostet wurde.Schalte mal bei StringReplace das Case-Sensitivity-Flag auf 1! Dann siehst du mal, wieviel schneller StringRegExpReplace dann noch sein sollte
-
SEuBo,
RegEx ist bei weitem schon aus dem Rennen, da hättest du schneller sein müssen bzw. weiterlesen sollen
Aber vielleicht hast du trotzdem eine Antwort auf mein RegEx-Problem im Post 17?
Ich gehe davon aus, dass mein Code wesentlich schneller ist, aber für kurze Strings bzw. andere ähnliche Anfragen wäre ein RegEx schnell getippert. Ausserdem muss man ja nicht dumm sterben, ich lerne trotz meines hohen Alters gerne immer noch dazu -
Aber vielleicht hast du trotzdem eine Antwort auf mein RegEx-Problem im Post 17?
Leider nicht, sorry. Ich kenne keine Möglichkeit, die Anzahl der Treffer direkt im Ergebnis wiederzugeben. -
Ein interessanter Ansatz ist hier zu sehen (von trancexx): http://www.autoitscript.com/forum/topic/14…ata-compression
Und zwar wird die PNG Komprimierung benutzt, um Daten zu komprimieren. Clever!
Gruß,
UEZ -
, das ist nicht neues...Problem ist (wie üblich bei den gängigen Kompressionen), die ZEIT.
Kein Mensch (der eine SCHNELLE Kompression/Dekompression) braucht, wandelt Binärdaten in eine Bitmap (ok, DAS ist das einzig schnelle, die 54 Byte Header davorzusetzen^^) , um diese Bitmap dann in eine JPG/JPEG/PNG oder wasauchimmer umzuwandeln bzw zu komprimieren. Wieso dann nicht direkt ein Verfahren (Deflate) nehmen, dass für die Kompression dieser Daten geeignet ist?
Da Deflate bei allen gängigen Kompressionsverfahren bzw. Zippern Verwendung findet, braucht man sich nicht zu wundern, dass auch die Ergebnisse ähnlich sind.
Im Endeffekt läuft dann doch wieder alles auf die Huffmann-Kodierung raus, jaja Räder neu erfinden wird auch immer schwerer...
-
Ich finde die Idee einfach cool, wobei die Idee vielleicht nicht neu ist, aber die Implementierung ist sehr ansehnlich.
Die Idee ist einfach, dass man nicht den "lahmen" AutoIt Interpreter nimmt, sondern Built-In Funktionen.
Oben von mir das Beispiel mit der ntdll.dll und von trancexx die gdiplus.dll als Alternativen.
Natürlich ist der Königsweg zum Komprimieren der von die genannte Weg, aber manchmal sind die alternativ Wege einfach nur genial...
Gruß,
UEZ -
Zitat
Natürlich ist der Königsweg zum Komprimieren der von die genannte Weg, aber manchmal sind die alternativ Wege einfach nur genial...
Ja, du hast natürlich völlig Recht!
Wenn es schon eine "native" AutoIt-Funktion gibt, die etwas ähnliches macht, dann sollte man die auch benutzen!
Aber wo bleibt denn da der Spass?
Letztendlich gibt es alles schon irgendwo, man muss nur noch die Funktion runterladen und aufrufen, aber der Reiz am Programmieren ist doch (jedenfalls bei mir) auch mal eigene Gedanken einfließen zu lassen und eine Lösung weit abseits vom C&P zu erarbeiten.ZitatDie Idee ist einfach, dass man nicht den "lahmen" AutoIt Interpreter nimmt, sondern Built-In Funktionen.
hehe,
, es lebe die WIN API
-
Ich bin völlig bei dir, wenn es darum geht, den Reiz am Coden zu erhalten! Aber in diesem Fall fand ich die Idee GDI+ zum Komprimieren zu benutzen, einfach genial. Erst mal auf diese Idee zu kommen, denn mir war die Idee noch "fremd".
Ich würde diese Art (GDI+) zum komprimieren nicht benutzen, doch die Möglichkeit zu haben ist einfach faszinierend.
Gruß,
UEZ -
Hi
Da meine ersten Tests vielversprechend aussahen, hab ich auch eine Funktion geschieben, um Binäre Daten als String zu komprimieren.
Das Endergebnis ist dann doch nicht ganz so rosig, wie ich am anfang dachteAutoIt3.exe kann ich auf gut 48 % zusammenschrumpfen.
Das ist nicht wirklich viel mehr Kompression, als etwa Andys AutoItOnly Version.Bei Daten, wo viele gleiche Wiederholungen auftreten (etwa Bitmaps mit großen einfärbigen Flächen), steigt die Kompressionsrate aber enorm.
Das Array 10000 mal 0xFF112233 schrumpft so auf 0.04%
Zugegeben, solche Daten kommen eher selten vorUnd Bitmaps mit großen einfäbigen Flächen sollte man dann doch zuerst als Jpg speichern und dann erst komprimieren...
Nun ja, vielleicht findet ja trotzdem jemand Verwendung dafür...
Spoiler anzeigen
[autoit];#include "ASM.au3"
[/autoit] [autoit][/autoit] [autoit];$hFile = FileOpen(@AutoItExe, 16)
[/autoit] [autoit][/autoit] [autoit]
;$bData = FileRead($hFile)
;FileClose($hFile);#cs
[/autoit] [autoit][/autoit] [autoit]
$iMax = 10000
$tData = DllStructCreate("uint[" & $iMax & "];")
For $i = 1 To $iMax
;DllStructSetData($tData, 1, Random(0, 0xFF, 1), $i)
DllStructSetData($tData, 1, 0xFF112233, $i)
Next
$tByte = DllStructCreate("byte[" & DllStructGetSize($tData) & "];", DllStructGetPtr($tData))
$bData = DllStructGetData($tByte, 1)
#ce$sComp = _Comp($bData)
[/autoit] [autoit][/autoit] [autoit]
$sConst = _CreateConst($sComp)
ClipPut($sConst)ConsoleWrite(@CRLF)
[/autoit] [autoit][/autoit] [autoit]
ConsoleWrite("> Data: " & StringLen($bData) & " " & StringLeft($bData, 1000) & @CRLF)
ConsoleWrite("> Comp: " & StringLen($sComp) & " " & StringLeft($sComp, 1000) & @CRLF)
ConsoleWrite(@CRLF)
ConsoleWrite("! Comp Rate: " & StringFormat("%.2f", StringLen($sComp) * 100 / StringLen($bData)) & " %" & @CRLF)
ConsoleWrite(@CRLF)
$bDeComp = _DeComp($sComp)_Compare($bData, $bDeComp, "Result")
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]
ConsoleWrite(@CRLF)Func _DeComp($sComp)
[/autoit] [autoit][/autoit] [autoit]
Local $t_ASM_DeCompPrepare = DllStructCreate("byte[138];")
DllStructSetData($t_ASM_DeCompPrepare, 1, "0x8B7424048B7C2408668B063C21762B3C4372182C4388C4C0EC04240F6605333366890783C70283C601EBDD6605101066890783C70283C602EBCE83C601B8000000008A2E80FD007440BA00000000B1000FB65E0180FB32771480FB23720F83C60180EB23D3E380C10409DAEBE383C60180FD52770A83C00183EA017FF8EBC383C00283EA017FF8EBB9C3")
Local $t_ASM_DeCompPMut = DllStructCreate("byte[109];")
DllStructSetData($t_ASM_DeCompPMut, 1, "0x8B7424048B7C24088B54240C8A0683C6013C217602EBF58A2E80FD00744EBB00000000B1000FB646013C3277123C23720E83C6012C23D3E080C10409C3EBE683C60180FD52770C882F83C70183EB017FF6EBC480ED530FB6C5D1E0668B0C0266890F83C70283EB017FF5EBABC3")
Local $t_ASM_DeCompBufCalcSize = DllStructCreate("byte[66];")
DllStructSetData($t_ASM_DeCompBufCalcSize, 1, "0x8B742404B800000000668B1E83C60280FB00742D80FF00742880FB42770A80FF42771483C001EBE180FF42770A0FB6D780EA3301D0EBD20FB6D780EA4301D0EBC8C3")
Local $t_ASM_DeCompBuf = DllStructCreate("byte[182];")
DllStructSetData($t_ASM_DeCompBuf, 1, "0x8B7424048B7C24088B54240C660FEFDB668B0683C6023C000F84970000003C42770E80FC437220662D13436689C1EB2B80FC437209662D43436689C1EB1D662D33336689C1EB14662D3333C0E40408E00FB6C0660F6EE0B501EB090FB6D9F30F6F641A01F30F7F270FB6C501C78A0200E83C3076282C300FB6C0F30F6F7C0201F30F6F740211F30F6F6C0221F30F7F7A01F30F7F7211F30F7F6A2128020FB602F30F7F64020100E8F30F7F5C0201002AE95BFFFFFFC3")If Not StringRegExp($sComp, "[\x{0023}-\x{FFFF}]*\x{0021}[\x{0023}-\x{FFFF}]{2,}") Then Return SetError(1, 1, False)
[/autoit] [autoit][/autoit] [autoit]
Local $iLen = StringLen($sComp)
Local $tComp = DllStructCreate("char[" & $iLen + 1 & "]")
Local $pComp = DllStructGetPtr($tComp)
DllStructSetData($tComp, 1, $sComp)Local $tPMut = DllStructCreate("word[173];")
[/autoit] [autoit][/autoit] [autoit]
Local $pPMut = DllStructGetPtr($tPMut)Local $aRet = DllCall("user32.dll", "uint", "CallWindowProcW", "ptr", DllStructGetPtr($t_ASM_DeCompPrepare), "ptr", $pComp, "ptr", $pPMut, "int", 0, "int", 0)
[/autoit] [autoit][/autoit] [autoit]
If @error Or Not IsArray($aRet) Then Return SetError(1, 2, False)
Local $iSize = $aRet[0]Local $tCompBuf = DllStructCreate("byte[" & $iSize & "]; byte[16];")
[/autoit] [autoit][/autoit] [autoit]
Local $pCompBuf = DllStructGetPtr($tCompBuf)DllCall("user32.dll", "none", "CallWindowProcW", "ptr", DllStructGetPtr($t_ASM_DeCompPMut), "ptr", $pComp, "ptr", $pCompBuf, "ptr", $pPMut, "int", 0)
[/autoit] [autoit][/autoit] [autoit]$aRet = DllCall("user32.dll", "uint", "CallWindowProcW", "ptr", DllStructGetPtr($t_ASM_DeCompBufCalcSize), "ptr", $pCompBuf, "int", 0, "int", 0, "int", 0)
[/autoit] [autoit][/autoit] [autoit]
If @error Or Not IsArray($aRet) Then Return SetError(1, 3, False)
$iSize = $aRet[0]Local $tDeComp = DllStructCreate("byte[" & $iSize & "]; byte[16];")
[/autoit] [autoit][/autoit] [autoit]
Local $pDeComp = DllStructGetPtr($tDeComp)Local $tBuf = DllStructCreate("byte[65];");[1]BufCnt + [16*3]Buffer + [16]Pad
[/autoit] [autoit][/autoit] [autoit]
Local $pBuf = DllStructGetPtr($tBuf)DllCall("user32.dll", "none", "CallWindowProcW", "ptr", DllStructGetPtr($t_ASM_DeCompBuf), "ptr", $pCompBuf, "ptr", $pDeComp, "ptr", $pBuf, "int", 0)
[/autoit] [autoit][/autoit] [autoit]Return DllStructGetData($tDeComp, 1)
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]
EndFunc ;==>_DeCompFunc _Comp($bData)
[/autoit] [autoit][/autoit] [autoit]
Local $t_ASM_CompBuf = DllStructCreate("byte[335];")
DllStructSetData($t_ASM_CompBuf, 1, "0x8B7424048B7C24088B54240C8B5C2410660F6ECBF30F6F26F30F6F6A01F30F6F7211F30F6F7A21B100660FEFD2660F6FDC660F74DD660FD7C3BB01000000B50085D8740AD1E380C50180FD0F72F2660F7ED338EF7704660F6ED1660F73DD01660F6FC6660F73F80F660FEBE8660F73DE01660F6FC7660F73F80F660FEBF0660F73DF0180C1013A0A72A3660F7ED1660F7ECB0FB6C539D8760288DD80FD02723B80F90F770F6689C86605434366890783C702EB3F80F91F77116689C82C106605433366890783C702EB296689C82C206605334366890783C702EB18660FC5C400B50188C4C0EC04240F6605333366890783C7028A0200E83C3076282C300FB6C0F30F6F7C0201F30F6F740211F30F6F6C0221F30F7F7A01F30F7F7211F30F7F6A2128020FB602F30F7F64020100E8660FEFC0F30F7F440201002A0FB6C501C6660F7ECB29C383FB000F87C2FEFFFFC3")
Local $t_ASM_Comp = DllStructCreate("byte[411];")
DllStructSetData($t_ASM_Comp, 1, "0x8B7424048B7C2408B13383C702B53366890F83C70480C50180FD5372F280C10180F95372E88B7C2408668B0683C60180FC007423662D33330FB6DC0FB6D0C1E307C1E20201D3668B0C1F6683F9FF74056683041F01EBD2B900000000BAFE03000089D6C1E6028B04378B5C37046639D87307891C37894437044A39CA7DE34181F9FF03000072D566BB002166B90000668B176683FA027244668B57028B742404B50088CB80C353668B063C00741780FC0074126639D0750866891E83C601B50183C601EBE280FD00740380C101660FB6D566891783C70480F9AD72B366BAFFFF6689178B74240489F78A0683C6013C00740B3C2176F3880783C701EBECC607008B7424088B7C240C668B166683FA007C3D6683FA007432668B560280FA42771E80FE4277196689D0662D3333C0E40408E03CBC77090443880783C701EB0B6681EA101066891783C70283C604EBBAC607218B74240489F7BA010000008A0683C6013A067424880783C70183FA02721589D3C1EA0483E30F83C323881F83C70183FA0075EBBA0000000083C2013C217202EBCA660FEFC0F30F7F07C3")If StringRegExp($bData, "[^[:xdigit:]xX]") Then Return SetError(1, 1, False)
[/autoit] [autoit][/autoit] [autoit]
Local $iSize = BinaryLen($bData)
If $iSize < 1 Then Return SetError(1, 2, False)Local $tData = DllStructCreate("byte Data[" & $iSize & "]; byte[16];")
[/autoit] [autoit][/autoit] [autoit]
Local $pData = DllStructGetPtr($tData)
DllStructSetData($tData, "Data", $bData)Local $tComp = DllStructCreate("char[" & $iSize * 2 + 1 & "];")
[/autoit] [autoit][/autoit] [autoit]
Local $pComp = DllStructGetPtr($tComp)Local $tBuf = DllStructCreate("byte[65];");[1]BufCnt + [16*3]Buffer + [16]Pad
[/autoit] [autoit][/autoit] [autoit]
Local $pBuf = DllStructGetPtr($tBuf)DllCall("user32.dll", "none", "CallWindowProcW", "ptr", DllStructGetPtr($t_ASM_CompBuf), "ptr", $pData, "ptr", $pComp, "ptr", $pBuf, "uint", $iSize)
[/autoit] [autoit][/autoit] [autoit]Local $tPMut = DllStructCreate("word[2048];");32*32*2
[/autoit] [autoit][/autoit] [autoit]
Local $pPMut = DllStructGetPtr($tPMut)Local $tDef = DllStructCreate("char[347];");173*2+1
[/autoit] [autoit][/autoit] [autoit]
Local $pDef = DllStructGetPtr($tDef)DllCall("user32.dll", "none", "CallWindowProcW", "ptr", DllStructGetPtr($t_ASM_Comp), "ptr", $pComp, "ptr", $pPMut, "ptr", $pDef, "int", 0)
[/autoit] [autoit][/autoit] [autoit]Return DllStructGetData($tDef, 1) & DllStructGetData($tComp, 1)
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]
EndFunc ;==>_CompFunc _CreateConst($sStr, $sName = "sComp")
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]
Local $sConst = 'Global Const $' & $sName & ' = '
Local $aRegExp = StringRegExp($sStr, '^.{' & 4085 - StringLen($sConst) & '}|.{4077}|.*$', 3)
If @error Or Not IsArray($aRegExp) Then Exit
If Not $aRegExp[UBound($aRegExp) - 1] Then ReDim $aRegExp[UBound($aRegExp) - 1]
For $i = 0 To UBound($aRegExp) - 1
Switch $i
Case UBound($aRegExp) - 1
$sConst &= '"' & $aRegExp[$i] & '"'
Case Else
$sConst &= '"' & $aRegExp[$i] & '" & _' & @CRLF & ' '
EndSwitch
Next
Return $sConst
EndFunc ;==>_CreateConstFunc _Compare($bData1, $bData2, $sDesc = "")
[/autoit] [autoit][/autoit] [autoit]
Local $iSize1 = BinaryLen($bData1)
Local $iSize2 = BinaryLen($bData2)
Local $iByte1, $iByte2If (BinaryMid($bData1, 1, $iSize1) = BinaryMid($bData2, 1, $iSize2)) And ($iSize1 = $iSize2) Then
[/autoit]
If $iSize1 > 10000 Then
ConsoleWrite("+ " & $sDesc & ": " & BinaryMid($bData1, 1, 10000) & @CRLF)
Else
ConsoleWrite("+ " & $sDesc & ": " & $bData1 & @CRLF)
EndIf
Else
If $iSize1 > 10000 Then
ConsoleWrite("! " & $sDesc & ": " & BinaryMid($bData1, 1, 10000) & @CRLF)
ConsoleWrite("! " & $sDesc & ": " & BinaryMid($bData2, 1, 10000) & @CRLF)
Else
ConsoleWrite("! " & $sDesc & ": " & $bData1 & @CRLF)
ConsoleWrite("! " & $sDesc & ": " & $bData2 & @CRLF)
EndIf
ConsoleWrite("! " & $sDesc & " ")
For $i = 1 To $iSize1
$iByte1 = BinaryMid($bData1, $i, 1)
$iByte2 = BinaryMid($bData2, $i, 1)
If $iByte1 = $iByte2 Then
ConsoleWrite("__")
Else
ConsoleWrite("##")
;ExitLoop
EndIf
Next
ConsoleWrite(@CRLF)
EndIf
EndFunc ;==>_CompareE
-
Kannst du noch den ASM code zu deiner Lösung bereitstellen (oder wie der ungefähr aussah)?
-
Hi,
um einen schnellen Blick auf den Code zu werfen, einfach diesen Online-Disassembler benutzen (das führende 0x nicht mit kopieren^^)
https://www.onlinedisassembler.com/odaweb/ -
Hab nur das hier gefunden, weiß jetzt auf die schnelle nicht, ob das auch der richtige Code ist... (schon lange her)
Code
Alles anzeigen#include <AssembleIt.au3> ; 33 = 1 Pad ;Comp: ; 35 - 50 = 16 Cnt Chr ; 51 - 66 = 16 Hex Chr ; 67 - 82 = 16 Buf Chr (BufferLen, BufferPos) ; 83 - 255 = 173 PM Chr ;Def: ; 35 - 50 = 16 Hex Chr ; 51 - 66 = 16 Buf Chr ; 67 - 255 = 189 Single Hex Chr 00-BD Func _ASM_CompBuf() _("use32");32Bit! ;3 Buffer ;xmm7 = Buffer 3 ;xmm6 = Buffer 2 ;xmm5 = Buffer 1 ;xmm4 = Bytes ;xmm3 = Cmp ;xmm2 = ByteLen-BufPos ;xmm1 = Size ;eax = 0,0,0,0 ;ebx = 0,0,0,0 ;ecx = 0,0,ByteLen,BufPos ;edx = pBuf _("mov esi, [esp+4]");pData _("mov edi, [esp+8]");pComp _("mov edx, [esp+12]");pBuf _("mov ebx, [esp+16]");iSize _("_Loop:") _("movd xmm1, ebx");Store iSize _("movdqu xmm4, [esi]") ;Compare Buffer ;Load Buffer _("movdqu xmm5, [edx+1]") _("movdqu xmm6, [edx+17]") _("movdqu xmm7, [edx+33]") _("mov cl, 0");Reset BufPos _("pxor xmm2, xmm2");Reset ByteLen-BufPos _("_LoopChkBuf:") _("movdqa xmm3, xmm4") _("pcmpeqb xmm3, xmm5") _("pmovmskb eax, xmm3") _("mov ebx, 1") _("mov ch, 0");Reset ByteLen _("_LoopByteLen:") _("test eax, ebx") _("jz _BufferFound") _("Shl ebx, 1") _("Add ch, 1") _("cmp ch, 15") _("jb _LoopByteLen") _("_BufferFound:") _("movd ebx, xmm2") _("cmp bh, ch");LastByteLen > CurByteLen? _("ja _OldBufLen") _("movd xmm2, ecx") _("_OldBufLen:") ;Shift Buffer: _("psrldq xmm5, 1") _("movdqa xmm0, xmm6") _("pslldq xmm0, 15") _("por xmm5, xmm0") _("psrldq xmm6, 1") _("movdqa xmm0, xmm7") _("pslldq xmm0, 15") _("por xmm6, xmm0") _("psrldq xmm7, 1") _("add cl, 1") _("cmp cl, [edx]");BufCnt _("jb _LoopChkBuf") _("_BufferWrite:") _("movd ecx, xmm2");Get ByteLen-BufPos _("movd ebx, xmm1");Restore iSize _("movzx eax, ch") _("cmp eax, ebx");CurByteLen > iSize _("jbe _ContBufWrite") _("mov ch, bl") _("_ContBufWrite:") _("cmp ch, 2") _("jb _BufWriteByte") _("cmp cl, 15") _("ja _Buffer2") _("mov ax, cx") _("add ax, 0x4343");= BufChr BufChr _("mov [edi], ax") _("add edi, 2") _("jmp _BufferAdd") _("_Buffer2:") _("cmp cl, 31") _("ja _Buffer3") _("mov ax, cx") _("sub al, 16") _("add ax, 0x3343");= BufChr HexChr _("mov [edi], ax") _("add edi, 2") _("jmp _BufferAdd") _("_Buffer3:") _("mov ax, cx") _("sub al, 32") _("add ax, 0x4333");= HexChr BufChr _("mov [edi], ax") _("add edi, 2") _("jmp _BufferAdd") _("_BufWriteByte:") _("pextrw eax, xmm4, 0") _("mov ch, 1");ByteLen = 1 _("mov ah, al") _("shr ah, 4") _("and al, 0xF") _("add ax, 0x3333");= HexChr _("mov [edi], ax") _("add edi, 2") _("_BufferAdd:") _("mov al, [edx]");BufCnt _("add al, ch");+ByteLen _("cmp al, 48") _("jbe _NoBufSHR") _("sub al, 48") _("movzx eax, al");=BufSHR _("movdqu xmm7, [edx+eax+1]") _("movdqu xmm6, [edx+eax+17]") _("movdqu xmm5, [edx+eax+33]") _("movdqu [edx+1], xmm7") _("movdqu [edx+17], xmm6") _("movdqu [edx+33], xmm5") _("sub [edx], al") _("_NoBufSHR:") _("movzx eax, byte[edx]") _("movdqu [edx+eax+1], xmm4");Add Bytes to Buffer _("add al, ch") _("pxor xmm0, xmm0") _("movdqu [edx+eax+1], xmm0");Trim to ByteLen _("add [edx], ch") _("movzx eax, ch");ByteLen _("add esi, eax") _("movd ebx, xmm1");Restore iSize _("sub ebx, eax") _("cmp ebx, 0") _("ja _Loop") _("_Exit:") _("ret ") EndFunc Func _ASM_Comp() _("use32");32Bit! _("mov esi, [esp+4]");pComp _("mov edi, [esp+8]");pPMut ;Fill PM Array _("mov cl, 0x33") _("add edi, 2") _("_LoopFillPM_LO:") _("mov ch, 0x33") _("_LoopFillPM_HI:") _("mov [edi], cx") _("add edi, 4") _("add ch, 1") _("cmp ch, 0x53") _("jb _LoopFillPM_HI") _("add cl, 1") _("cmp cl, 0x53") _("jb _LoopFillPM_LO") ;Cnt PM _("mov edi, [esp+8]");pPMut _("_LoopCntPM:") _("mov ax, [esi]") _("add esi, 1") _("cmp ah, 0") _("jz _BubbleSort") _("sub ax, 0x3333") _("movzx ebx, ah") _("movzx edx, al") _("shl ebx, 7") _("shl edx, 2") _("add ebx, edx") _("mov cx, [edi+ebx]") _("cmp cx, 0xFFFF") _("je _NoAddCnt") _("add word[edi+ebx], 1") _("_NoAddCnt:") _("jmp _LoopCntPM") ;Sort PMut Array => Cnt _("_BubbleSort:") _("mov ecx, 0") _("_LoopSort1:") _("mov edx, 1022");32x32-2 _("_LoopSort2:") _("mov esi, edx") _("shl esi, 2") _("mov eax, [edi+esi]") _("mov ebx, [edi+esi+4]");Next _("cmp ax, bx");Cnt _("jae _NoBSort") _("mov [edi+esi], ebx") _("mov [edi+esi+4], eax") _("_NoBSort:") _("dec edx") _("cmp edx, ecx") _("jge _LoopSort2") _("inc ecx") _("cmp ecx, 1023") _("jb _LoopSort1") ;Replace PM ;eax = 0,0,Byte-Byte ;ebx = 0,0,Rep-Rep ;ecx = 0,0,RepCnt,PMCnt ;edx = 0,0,PM-PM _("mov bx, 0x2100") _("mov cx, 0") _("_LoopRepPM:") _("mov dx, [edi]") _("cmp dx, 2") _("jb _ExitRepPM") _("mov dx, [edi+2]");PM _("mov esi, [esp+4]");pComp _("mov ch, 0") _("mov bl, cl") _("add bl, 83");=0x21PM _("_LoopRep:") _("mov ax, [esi]") _("cmp al, 0") _("jz _ContRepPM") _("cmp ah, 0") _("jz _ContRepPM") _("cmp ax, dx");CurWord = PM Word? _("jne _NoRepPM") _("mov [esi], bx") _("add esi, 1") _("mov ch, 1") _("_NoRepPM:") _("add esi, 1") _("jmp _LoopRep") _("_ContRepPM:") _("cmp ch, 0") _("jz _NoReplacedPM") _("add cl, 1") _("_NoReplacedPM:") _("movzx dx, ch") _("mov [edi], dx") _("add edi, 4") _("cmp cl, 173") _("jb _LoopRepPM") _("_ExitRepPM:") _("mov dx, -1");Terminate _("mov [edi], dx") ;Remove 0x21 _("mov esi, [esp+4]");pComp _("mov edi, esi") _("_LoopRem21:") _("mov al, [esi]") _("add esi, 1") _("cmp al, 0") _("jz _ExitRem21") _("cmp al, 0x21") _("jbe _LoopRem21") _("mov [edi], al") _("add edi, 1") _("jmp _LoopRem21") _("_ExitRem21:") _("mov byte[edi], 0");Terminate ;Define _("mov esi, [esp+8]");pPMut _("mov edi, [esp+12]");pDef _("_LoopDef:") _("mov dx, [esi]") _("cmp dx, 0") _("jl _ExitDef") _("cmp dx, 0") _("jz _ContDef") _("mov dx, [esi+2]");PM _("cmp dl, 0x42") _("ja _NoHexDef") _("cmp dh, 0x42") _("ja _NoHexDef") _("mov ax, dx") _("sub ax, 0x3333") _("shl ah, 4") _("or al, ah") _("cmp al, 0xBC") _("ja _NoHexDef") _("add al, 67") _("mov [edi], al") _("add edi, 1") _("jmp _ContDef") _("_NoHexDef:") _("sub dx, 0x1010") _("mov [edi], dx") _("add edi, 2") _("_ContDef:") _("add esi, 4") _("jmp _LoopDef") _("_ExitDef:") _("mov byte [edi], 0x21") ;CompCnt _("mov esi, [esp+4]");pComp _("mov edi, esi") _("mov edx, 1") _("_LoopCnt:") _("mov al, [esi]") _("add esi, 1") _("cmp al, [esi]");Byte = NextByte? _("je _CntPlus") _("mov [edi], al") _("add edi, 1") _("cmp edx, 2") _("jb _NoCnt") _("_WriteCnt:") _("mov ebx, edx") _("shr edx, 4");Next 4 _("and ebx, 0x0F") _("add ebx, 35");=Cnt _("mov [edi], bl");WriteCnt _("add edi, 1") _("cmp edx, 0") _("jnz _WriteCnt") _("_NoCnt:") _("mov edx, 0") _("_CntPlus:") _("add edx, 1") _("cmp al, 0x21") _("jb _ExitCompCnt") _("jmp _LoopCnt") _("_ExitCompCnt:") _("pxor xmm0, xmm0") _("movdqu [edi], xmm0");Terminate _("ret ") EndFunc Func _ASM_DeCompBufCalcSize() _("use32");32Bit! _("mov esi, dword[esp+4]");pComp _("mov eax, 0") _("_Loop:") _("mov bx, [esi]") _("add esi, 2") _("cmp bl, 0") _("jz _Exit") _("cmp bh, 0") _("jz _Exit") ;Buf1 = Buf-Buf ;Buf2 = Buf-Hex ;Buf3 = Hex-Buf _("cmp bl, 66") _("ja _Buf1") _("cmp bh, 66") _("ja _Buf3") _("add eax, 1") _("jmp _Loop") _("_Buf1:") _("cmp bh, 66") _("ja _Buf3") _("movzx edx, bh");= BufLen _("sub dl, 51") _("add eax, edx") _("jmp _Loop") _("_Buf3:") _("movzx edx, bh");= BufLen _("sub dl, 67") _("add eax, edx") _("jmp _Loop") _("_Exit:") _("ret ") EndFunc Func _ASM_DeCompBuf() _("use32");32Bit! _("mov esi, dword[esp+4]");pComp _("mov edi, dword[esp+8]");pDeComp _("mov edx, dword[esp+12]");pBuf ;xmm7 = Buffer 3 ;xmm6 = Buffer 2 ;xmm5 = Buffer 1 ;xmm4 = WriteByte ;xmm3 = 00000000000000000000000000000000 ;ecx = 0,0,ByteLen,BufPos ;Buf1 = Buf-Buf ;Buf2 = Buf-Hex ;Buf3 = Hex-Buf _("pxor xmm3, xmm3") _("_Loop:") _("mov ax, [esi]") _("add esi, 2") _("cmp al, 0") _("jz _Exit") _("cmp al, 0x42") _("ja _Buf1") _("cmp ah, 0x43") _("jb _Hex") ;Buf3: _("sub ax, 0x4313") _("mov cx, ax") _("jmp _BufferGet") _("_Buf1:");Buf1 / Buf2 _("cmp ah, 0x43") _("jb _Buf2") _("sub ax, 0x4343") _("mov cx, ax") _("jmp _BufferGet") _("_Buf2:") _("sub ax, 0x3333") _("mov cx, ax") _("jmp _BufferGet") _("_Hex:") _("sub ax, 0x3333") _("shl ah, 4") _("or al, ah") _("movzx eax, al") _("movd xmm4, eax") _("mov ch, 1") _("jmp _BufferAdd") _("_BufferGet:") _("movzx ebx, cl") _("movdqu xmm4, [edx+ebx+1]") _("_BufferAdd:") _("movdqu [edi], xmm4") _("movzx eax, ch") _("add edi, eax") _("mov al, [edx]");BufCnt _("add al, ch");+ByteLen _("cmp al, 48") _("jbe _NoBufSHR") _("sub al, 48") _("movzx eax, al");=BufSHR _("movdqu xmm7, [edx+eax+1]") _("movdqu xmm6, [edx+eax+17]") _("movdqu xmm5, [edx+eax+33]") _("movdqu [edx+1], xmm7") _("movdqu [edx+17], xmm6") _("movdqu [edx+33], xmm5") _("sub [edx], al") _("_NoBufSHR:") _("movzx eax, byte[edx]") _("movdqu [edx+eax+1], xmm4");Add Bytes to Buffer _("add al, ch") _("movdqu [edx+eax+1], xmm3");Trim to ByteLen _("add [edx], ch") _("jmp _Loop") _("_Exit:") _("ret ") EndFunc Func _ASM_DeCompPrepare() _("use32");32Bit! _("mov esi, dword[esp+4]");pComp _("mov edi, dword[esp+8]");pPMut _("_LoopDef:") _("mov ax, [esi]") _("cmp al, 0x21") _("jbe _CalcSize") _("cmp al, 67") _("jb _DoubleHex") ;Single Hex Chr _("sub al, 67") _("mov ah, al") _("shr ah, 4") _("and al, 0xF") _("add ax, 0x3333");=Hex Chr _("mov [edi], ax") _("add edi, 2") _("add esi, 1") _("jmp _LoopDef") _("_DoubleHex:") _("add ax, 0x1010");= Hex Chr _("mov [edi], ax") _("add edi, 2") _("add esi, 2") _("jmp _LoopDef") _("_CalcSize:") _("add esi, 1");Skip 0x21 _("mov eax, 0") _("_LoopSize:") _("mov ch, [esi]") _("cmp ch, 0") _("jz _Exit") _("mov edx, 0") _("mov cl, 0") _("_LoopCnt:") _("movzx ebx, byte[esi+1]") _("cmp bl, 50") _("ja _AddCnt") _("cmp bl, 35") _("jb _AddCnt") _("add esi, 1") _("sub bl, 35") _("shl ebx, cl") _("add cl, 4") _("or edx, ebx") _("jmp _LoopCnt") _("_AddCnt:") _("add esi, 1") _("cmp ch, 82") _("ja _LoopPMut") _("_LoopHex:") _("add eax, 1") _("sub edx, 1") _("jg _LoopHex") _("jmp _LoopSize") _("_LoopPMut:") _("add eax, 2") _("sub edx, 1") _("jg _LoopPMut") _("jmp _LoopSize") _("_Exit:") _("ret ") EndFunc Func _ASM_DeCompPMut() _("use32");32Bit! _("mov esi, dword[esp+4]");pComp _("mov edi, dword[esp+8]");pDeComp _("mov edx, dword[esp+12]");pPMut _("_LoopDef:") _("mov al, [esi]") _("add esi, 1") _("cmp al, 0x21") _("jbe _Expand") _("jmp _LoopDef") _("_Expand:") ;Expand ;eax = 0,0,0,0 ;ebx = Cnt ;ecx = 0,0,byte,shift ;edx = pPMut ;_("sub esi, 1") ;_("mov edx, dword[esp+12]");pPMut _("_LoopExp:") _("mov ch, [esi]") _("cmp ch, 0") _("jz _ExitExp") _("mov ebx, 0") _("mov cl, 0") _("_LoopCnt:") _("movzx eax, byte[esi+1]") _("cmp al, 50") _("ja _Write") _("cmp al, 35") _("jb _Write") _("add esi, 1") _("sub al, 35") _("shl eax, cl") _("add cl, 4") _("or ebx, eax") _("jmp _LoopCnt") _("_Write:") _("add esi, 1") _("cmp ch, 82") _("ja _PMut") _("_LoopHex:") _("mov [edi], ch") _("add edi, 1") _("sub ebx, 1") _("jg _LoopHex") _("jmp _LoopExp") _("_PMut:") _("sub ch, 83") _("movzx eax, ch") _("shl eax, 1");Word _("mov cx, [edx+eax]");get PMut _("_LoopPMut:") _("mov [edi], cx") _("add edi, 2") _("sub ebx, 1") _("jg _LoopPMut") _("jmp _LoopExp") _("_ExitExp:") _("ret ") EndFunc
-