profifrage: datei encodieren / decodieren - methode zu langsam :(

  • hi leute, ich brauch mal wieder guten rat ....
    ich hab ein problem mit dem ver/entschlüsseln von dateien auf hex-basis.
    und zwar habe ich eine tabelle für jedes der 256 hex-zeichen die ich durch ein anderes
    hex-zeichen ersetzen muss... leider sind die dateinen verdammt groß und so wie ich das mache, gehts
    schon mit kleineren dateinen sau-lahm :( ...

    Spoiler anzeigen
    [autoit]


    ;Verschlüsseln :
    Func _Encodefile($string)
    If $string = "" Then Return ""
    Local $sfa
    $len = StringLen($string)
    $a = StringToASCIIArray($string)
    for $c = 0 to $len -1
    if hex($a[$c]) = 00 Then $a[$c] = 55
    if hex($a[$c]) = 01 Then $a[$c] = 54
    if hex($a[$c]) = 02 Then $a[$c] = 57
    ;...usw bis 255
    Next
    Return _ArrayToString($a)
    EndFunc

    [/autoit]


    ;das ganze wollte ich auch wieder umgekehrt machen ....

    hier die tablelle...
    evtl. checkt ihr ja den algo... ich leider nur im ansatz, deswegen mach ichs halt so.

    Spoiler anzeigen


    danke im voraus :)

    Einmal editiert, zuletzt von WhiteLion (10. November 2011 um 18:07)

  • Wenn ich es richtig verstanden habe ist :

    Spoiler anzeigen

    0 = 5
    1=4
    2=7
    3=6
    4=1
    5=0
    6=3
    7=2
    8=D
    9=C
    A=F
    B=E
    C=9
    D=8
    E=B
    F=A

  • Moin,

    versuch mal

    [autoit]

    Func _Encodefile($string)
    If $string = "" Then Return ""
    Local $sfa
    $len = StringLen($string)
    $a = StringToASCIIArray($string)
    for $c = 0 to $len -1
    Switch hex($a[$c])
    Case 00
    $a[$c] = 55
    Case 01
    $a[$c] = 54
    Case 02
    $a[$c] = 57
    ;...usw bis 255
    Next
    Return _ArrayToString($a)
    EndFunc

    [/autoit]

    Switch ist sehr viel schneller als If Then - und du wandelst nur 1x Hex()

    BLinz

  • danke, das sind schon zwei wichtige informationen .... wenn ich das schema anwende was TheLuBu vorschlägt, dann müsste ich die datei am besten ein mal als hex-string öffnen. und könnte dann mit stringreplace nach dem schema ersetzten, dann wieder den hex-string als datei speichern .... hmmmm

  • Also ich würde keine cäsar chiffre verwenden.
    Erstens is sie wenn du sie rein in autoit machst doch ziemlich langsam (auch wenn man mit ein paar gut verschachtelten ifs noch einiges an performance rausholen könnte)
    Zweitens bekommst du bei größeren Dateien Probleme wegen Maximaler Stringlänge/Arraygröße (außer du baust es anders auf)
    Drittens is sie sowieso ziemlich unsicher (so wie alles wenn man die Autoit exe hat)
    Viertens gibts schon bessere fertige Funktionen ;)

    Sie dir doch mal die Crypt.au3 an. Besonders _Crypt_EncryptFile()

  • also mir geht es gar nciht darum, dass ich etwas selber schützen möchte, sondern um eine bestehende chiffrierung von spieledateinen.... leider sind die dinger auch bis zu 500MB groß :( .... trotzdem würde ich es gerne hinbekommen .... leider weiss ich wirklich nicht wie ich das einigermaßen performant tun kann.... :(

  • Wirklich performant ist AutoIt dabei nicht aber vielleicht kannst du damit wenigstens ein bisschen besser leben:

    Spoiler anzeigen
    [autoit]

    Global Const $a_Chiff[256] = [84,87,86,81,80,83,82,93,92,95,94,89,88,91,90,69,68,71,70,65,64,67,66,77,76,79,78,73,72,75,74,117,116,119,118,113,112,115,114,125,124,127,126,121,120,123,122,101,100,103,102,97,96,99,98,109,108,111,110,105,104,107,106,21,20,23,22,17,16,19,18,29,28,31,30,25,24,27,26,5,4,7,6,1,0,3,2,13,12,15,14,9,8,11,10,53,52,55,54,49,48,51,50,61,60,63,62,57,56,59,58,37,36,39,38,33,32,35,34,45,44,47,46,41,40,43,42,213,212,215,214,209,208,211,210,221,220,223,222,217,216,219,218,197,196,199,198,193,192,195,194,205,204,207,206,201,200,203,202,245,244,247,246,241,240,243,242,253,252,255,254,249,248,251,250,229,228,231,230,225,224,227,226,237,236,239,238,233,232,235,234,149,148,151,150,145,144,147,146,157,156,159,158,153,152,155,154,133,132,135,134,129,128,131,130,141,140,143,142,137,136,139,138,181,180,183,182,177,176,179,178,189,188,191,190,185,184,187,186,165,164,167,166,161,160,163,162,173,172,175,174,169,168,171,170,85]

    [/autoit] [autoit][/autoit] [autoit]

    Func _Encodefile(Const $s_FileName)
    Local $a_AArr = StringToASCIIArray(FileRead($s_FileName))
    For $i = 0 To UBound($a_AArr) -1
    $a_AArr[$i] = $a_Chiff[$a_AArr[$i]]
    Next
    Return StringFromASCIIArray($a_AArr)
    EndFunc

    [/autoit]
  • AspirinJunkie

    danke für die antwort ... leider funktionierte das script aus einigen gründen nicht...
    ich habs so weit geändert, bis auf eine entscheidene kleinigkeit bei der ich nicht weiter komme.
    und zwar encodiere ich KEINE text-dateien, sondern binärdateien.
    das haut natürlich mit "StringFromASCIIArray" nicht hin .... ich weiss aber auch nicht wies gehen soll.


    [autoit]

    Func _Encodefile($s_FileName)
    $s_FileName = FileOpen($s_FileName, 16)
    $s_FileName = FileRead($s_FileName)
    MsgBox(0,"1", $s_FileName)
    Local $a_AArr = StringToASCIIArray($s_FileName)
    _ArrayDisplay($a_AArr)
    For $i = 0 To UBound($a_AArr) -1
    $a_AArr[$i] = $a_Chiff[$a_AArr[$i]]
    Next
    _ArrayDisplay($a_AArr)
    Return StringFromASCIIArray($a_AArr,"")
    EndFunc

    [/autoit]

    Einmal editiert, zuletzt von WhiteLion (10. November 2011 um 22:19)

  • Ich hab jetzt folgends, was auch mit kleineren dateinen funktioniert ... leider stürzt es mit der fehlermeldung: "...funktioniert nicht mehr "ab, sobald ich eine größere datei konvertieren möchte :( evtl kann ja mal jemand einen blick drauf werfen .....
    PS: ich habe die .dlls und alles was zum testen benötigt wird, angehängt.

    Spoiler anzeigen
    [autoit]


    ;~ #include <AVIConstants.au3>
    ;~ #include <ButtonConstants.au3>
    ;~ #include <EditConstants.au3>
    ;~ #include <GUIConstantsEx.au3>
    ;~ #include <StaticConstants.au3>
    #include <WindowsConstants.au3>
    #include <Array.au3>
    #include <File.au3>
    ;~ #include <GUIConstants.au3>
    ;~ #include <GuiListView.au3>
    ;~ #include <GuiImageList.au3>
    ;~ #include <Constants.au3>
    ;~ #include <inet.au3>
    ;~ #include <GuiEdit.au3>
    ;~ #include <GuiStatusBar.au3>
    ;~ #include <ScrollBarConstants.au3>
    #include <sendmessage.au3>
    #include <string.au3>
    #include <Zip32.au3>

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    FileInstall("zip32.dll", @ScriptDir & "\zip32.dll")
    FileInstall("unzip32.dll", @ScriptDir & "\unzip32.dll")
    Global $destdirectory, $sourcefile, $sourcedirtozip, $destzipname, $timestring

    _StatsSaver()

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _StatsSaver() ; StatsSaver GUI
    $h10Gui = GUICreate("Stats Unpacker V0.01", 200, 200, -1, -1, $WS_MINIMIZEBOX)
    ;$Label61 = GUICtrlCreateLabel("Thanx for idea to ", 40, 70)
    ;GUICtrlCreatePic(@TempDir & "\logo.jpg", 10, 10, 425, 55)
    $QuitStats = GUICtrlCreateButton("X", 179, 0, 15, 15, 0)
    $RestoringStats = GUICtrlCreateButton("Restore Stats", 10, 120, 100, 15, 0)
    $SaveStats = GUICtrlCreateButton("Save Stats", 10, 140, 100, 15, 0)
    GUISetState(@SW_SHOW)

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    $nMsg = GUIGetMsg()
    Sleep(20)
    Switch $nMsg
    Case $QuitStats
    GUIDelete($h10Gui)
    ExitLoop
    Case $RestoringStats
    $sourcefile = FileOpenDialog("Select a vfile (.v archive)", @ScriptDir, "vfiles (*.v)")
    if $sourcefile <> "" Then
    $splitted = StringSplit($sourcefile,"\")
    _ArrayDisplay($splitted)
    _checkifstatsbackupexists2()
    $createdir = StringTrimRight($splitted[$splitted[0]], 2)
    MsgBox(0,"",$createdir)
    DirCreate(@ScriptDir & "\extracted-vfiles\" & $createdir)
    $decoded = _Decodefile($sourcefile)
    FileWrite(@ScriptDir & "\extracted-vfiles\"&$createdir&"-decoded.v", $decoded)
    _unpack(@ScriptDir & "\extracted-vfiles\"&$createdir&"-decoded.v", @ScriptDir & "\extracted-vfiles\"&$createdir)
    EndIf
    Case $SaveStats
    $sourcefile = FileSelectFolder("Select a directroy where vfiles where extracted", @ScriptDir)
    if $sourcefile <> "" Then
    $splitted = StringSplit($sourcefile,"\")
    $savedir = $splitted[$splitted[0]]
    _checkifstatsbackupexists()
    _pack($sourcefile, @ScriptDir & "\vfiles\"&$savedir&"-packed.v")
    $s_FileName = @ScriptDir & "\vfiles\"&$savedir&"-packed.v"
    $encoded = _Encodefile($s_FileName)
    FileWrite(@ScriptDir & "\vfiles\"&$savedir&".v", $encoded)
    EndIf
    EndSwitch
    WEnd
    EndFunc ;==>_tatsSaver

    [/autoit] [autoit][/autoit] [autoit]

    Func _unpack($sourcefile, $destdirectory)
    _UnZip_Init("_UnZIP_PrintFunc", "UnZIP_ReplaceFunc", "_UnZIP_PasswordFunc", "_UnZIP_SendAppMsgFunc", "_UnZIP_ServiceFunc")
    _UnZIP_SetOptions()
    _UnZIP_Unzip($sourcefile, $destdirectory)
    If @error Then
    MsgBox(16, "Error", "Restorings stats and Archive unpacking error")
    Else
    MsgBox(64, "Success", "Restoring stats and archive unpacking successful")
    EndIf
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _pack($sourcedirtozip, $destzipname)
    _Zip_Init("_ZIPPrint", "_ZIPPassword", "_ZIPComment", "_ZIPProgress")
    If @error Then
    MsgBox(16, "Error", "Zip32.dll did not initialize")
    Exit
    EndIf
    ; Global $sDate = 0, $sEncrypt = 0, $sSys = 1, $sEmptyFolder = 0, $sExcludeDate = 0, $sIncludeDate = 0, $sJunkDir = 0, $sMove = 0, $sUpdate = 0,
    ; $sFresh = 0, $sLatestTime = 0, $sComment = 0, $sPrivilege = 1, $sRecurse = 1, $sLevel = 9

    [/autoit] [autoit][/autoit] [autoit]

    _ZIP_SetOptions(0,0,1,0,0,0,1)
    If @error Then
    MsgBox(16, "Error", "Options sets error")
    Exit
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    _ZIP_Archive($destzipname, $sourcedirtozip)
    If @error Then
    MsgBox(16, "Error", "Saving stats and archive creating error")
    Else
    MsgBox(64, "Success", "Saving stats and archive creating successful")
    EndIf
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _checkifstatsbackupexists()
    if DirGetSize(@ScriptDir & "\vfiles") = -1 then DirCreate(@ScriptDir & "\vfiles")
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _checkifstatsbackupexists2()
    if DirGetSize(@ScriptDir & "\extracted-vfiles") = -1 then DirCreate(@ScriptDir & "\extracted-vfiles")
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _createtimestring()
    Global $timestring = ("__date_"&@MON&"_"&@MDAY&"_"&@YEAR&"__time_"&@HOUR&"_"&@MIN&"_"&@SEC)
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    ;==========================# ZIP Dll-callback functions #======================================
    Func _ZIPPrint($sFile, $sPos)
    ConsoleWrite("!> _ZIPPrint: " & $sFile & @LF)
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _ZIPPassword($sPWD, $sX, $sS2, $sName)
    Local $iPass = InputBox("Archive encrypting set", "Enter the password", "", "", 300, 120)

    If $iPass = "" Then Return 1

    Local $PassBuff = DllStructCreate("char[256]", $sPWD)
    DllStructSetData($PassBuff, 1, $iPass)
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _ZIPComment($sComment)
    Local $iComment = InputBox("Archive comment set", "Enter the comment", "", "", 300, 120)
    If $iComment = "" Then Return 1

    Local $CommentBuff = DllStructCreate("char[256]", $sComment)
    DllStructSetData($CommentBuff, 1, $iComment)
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    ;~ Func _ZIPProgress($sName, $sSize)
    ;~ ;Return 1 for abort the zip!
    ;~ $CurZipSize += Number($sSize)
    ;~ Local $iPercent = Round(($CurZipSize / $UnCompSize * 100))
    ;~ GUICtrlSetData($progress, $iPercent)
    ;~ GUICtrlSetData($edit, $sName & @CRLF, 1)
    ;~
    ;~ ConsoleWrite("!> Name: " & $sName & @LF)
    ;~ EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    ;==========================# UnZIP Dll-callback functions #========================================
    Func _UnZIP_PrintFunc($sName, $sPos)
    ConsoleWrite("---> _UnZIP_PrintFunc: " & $sName & @LF)
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func UnZIP_ReplaceFunc($sReplace)
    If MsgBox(4 + 32, "Overwrite", "File " & $sReplace & " is exists." & @LF & "Do you want to overwrite all file?") = 6 Then
    Return $IDM_REPLACE_ALL
    Else
    Return $IDM_REPLACE_NONE
    EndIf
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _UnZIP_PasswordFunc($sPWD, $sX, $sS2, $sName)
    ConsoleWrite("!> UnZIP_PasswordFunc: " & $sPWD & @LF)

    Local $iPass = InputBox("Password require", "Enter the password for decrypt", "", "", 300, 120)
    If $iPass = "" Then Return 1

    Local $PassBuff = DllStructCreate("char[256]", $sPWD)
    DllStructSetData($PassBuff, 1, $iPass)
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _UnZIP_SendAppMsgFunc($sUcsize, $sCsize, $sCfactor, $sMo, $Dy, $sYr, $sHh, $sMm, $sC, $sFname, $sMeth, $sCRC, $fCrypt)
    ;ConsoleWrite("!> _UnZIP_SendAppMsgFunc: " & $sUcsize & @LF)
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _Encodefile($s_FileName)
    $s_FileName = FileOpen($s_FileName, 16)
    $s_FileName = FileRead($s_FileName)
    Local $a_AArr = StringSplit($s_FileName,"")
    For $i = 2 To UBound($a_AArr) -1
    Switch $a_AArr[$i]
    Case "0"
    $a_AArr[$i] = "5"
    Case "1"
    $a_AArr[$i] = "4"
    Case "2"
    $a_AArr[$i] = "7"
    Case "3"
    $a_AArr[$i] = "6"
    Case "4"
    $a_AArr[$i] = "1"
    Case "5"
    $a_AArr[$i] = "0"
    Case "6"
    $a_AArr[$i] = "3"
    Case "7"
    $a_AArr[$i] = "2"
    Case "8"
    $a_AArr[$i] = "D"
    Case "9"
    $a_AArr[$i] = "C"
    Case "A"
    $a_AArr[$i] = "F"
    Case "B"
    $a_AArr[$i] = "E"
    Case "C"
    $a_AArr[$i] = "9"
    Case "D"
    $a_AArr[$i] = "8"
    Case "E"
    $a_AArr[$i] = "B"
    Case "F"
    $a_AArr[$i] = "A"
    EndSwitch
    Next
    Return Binary(_ArrayToString($a_AArr,"",1))
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _Decodefile($s_FileName)
    $s_FileName = FileOpen($s_FileName, 16)
    $s_FileName = FileRead($s_FileName)
    Local $a_AArr = StringSplit($s_FileName,"")
    For $i = 2 To UBound($a_AArr) -1
    Switch $a_AArr[$i]
    Case "5"
    $a_AArr[$i] = "0"
    Case "4"
    $a_AArr[$i] = "1"
    Case "7"
    $a_AArr[$i] = "2"
    Case "6"
    $a_AArr[$i] = "3"
    Case "1"
    $a_AArr[$i] = "4"
    Case "0"
    $a_AArr[$i] = "5"
    Case "3"
    $a_AArr[$i] = "6"
    Case "2"
    $a_AArr[$i] = "7"
    Case "D"
    $a_AArr[$i] = "8"
    Case "C"
    $a_AArr[$i] = "9"
    Case "F"
    $a_AArr[$i] = "A"
    Case "E"
    $a_AArr[$i] = "B"
    Case "9"
    $a_AArr[$i] = "C"
    Case "8"
    $a_AArr[$i] = "D"
    Case "B"
    $a_AArr[$i] = "E"
    Case "A"
    $a_AArr[$i] = "F"
    EndSwitch
    Next
    Return Binary(_ArrayToString($a_AArr,"",1))
    EndFunc

    [/autoit]
  • so "Fehler" gefunden, der String der Beispieldatei ist 171668668 Zeichen lang.
    Für Strings kein Problem, aber du lädst es in ein Array und das ist auf 16777216 Elemente begrenzt.

    Ich überlege mir kurz was

  • Spoiler anzeigen
    [autoit]

    Func _Decodefile($s_FileName)
    Local $a_AArr, $s_Mid,$read,$s_ret = "", $i_done = 1, $len,$count
    $hFile = FileOpen($s_FileName, 16)
    $read = FileRead($hFile)
    $len = StringLen($read)
    $count = Ceiling($len / 16777215)
    For $k = 1 To $count
    $s_Mid = StringMid($read, $i_done, 16777215)
    $a_AArr = StringSplit($s_Mid, "")
    For $i = 1 To $a_AArr[0]
    If $a_AArr[$i] = "0" And $a_AArr[$i+1] = "x" Then ContinueLoop
    If $a_AArr[$i] = "x" And $a_AArr[$i-1] = "0" Then ContinueLoop
    Switch $a_AArr[$i]
    Case "5"
    $s_ret &= "0"
    Case "4"
    $s_ret &= "1"
    Case "7"
    $s_ret &= "2"
    Case "6"
    $s_ret &= "3"
    Case "1"
    $s_ret &= "4"
    Case "0"
    $s_ret &= "5"
    Case "3"
    $s_ret &= "6"
    Case "2"
    $s_ret &= "7"
    Case "D"
    $s_ret &= "8"
    Case "C"
    $s_ret &= "9"
    Case "F"
    $s_ret &= "A"
    Case "E"
    $s_ret &= "B"
    Case "9"
    $s_ret &= "C"
    Case "8"
    $s_ret &= "D"
    Case "B"
    $s_ret &= "E"
    Case "A"
    $s_ret &= "F"
    EndSwitch
    Next
    $i_done += 16777215
    Next
    FileClose($hFile)
    Return Binary($s_ret)
    EndFunc ;==>_Decodefile

    [/autoit]

    So hab das Decoden mal gemacht, sollte funktionieren.
    bei mir gibts aber nen Fehler mit der zip32.dll, liegt aber wahrscheinlich dran, das ich nen 64Bit Rechner hab

  • mit welcher Datei hast du es getestet? Mit einer größeren Datei?

    Die maximale Stringlänge ist 2147483647, wenn eine Datei größer ist könntest du mit

    [autoit]

    FileRead ($hFile , 2147483646 )

    [/autoit]


    Den ersten Teil einlesen,
    dann

    [autoit]

    FileSetPos(hFile ,2147483646, 0)

    [/autoit]


    und das ganze nochmal (evtl in ner Schleife)
    Dann kannst du auch diese Einschränkung umgehen

  • Ich hab das mal geändert, für den Fall, das du auch größere Dateien einlesen willst, das hier sollte dann auch klappen.
    Der Rückgabetyp ist jetzt aber ein Array, kannst du aber nacheinander in eine Datei schreiben.

    Spoiler anzeigen
    [autoit]

    Func _Decodefile($s_FileName)
    Local $a_AArr, $s_Mid, $read, $s_ret, $i_done, $len, $count, $exitdo = 0, $ret_array[1], $maxstringlenght = 2147483646, $pos = 0
    $hFile = FileOpen($s_FileName, 16)
    Do
    $read = FileRead($hFile, $maxstringlenght)
    $len = StringLen($read)
    If $len < 2147483646 Then
    $exitdo = 1
    Else
    If $pos = 0 Then
    FileSetPos($hFile, $pos + 1, 0)
    Else
    FileSetPos($hFile, $pos, 0)
    EndIf
    $pos += 2147483646
    EndIf
    $i_done = 1
    $s_ret = ""
    $count = Ceiling($len / 16777215)
    For $k = 1 To $count
    $s_Mid = StringMid($read, $i_done, 16777215)
    $a_AArr = StringSplit($s_Mid, "")
    For $i = 1 To $a_AArr[0]
    If $a_AArr[$i] = "0" And $a_AArr[$i + 1] = "x" Then ContinueLoop
    If $a_AArr[$i] = "x" And $a_AArr[$i - 1] = "0" Then ContinueLoop
    Switch $a_AArr[$i]
    Case "5"
    $s_ret &= "0"
    Case "4"
    $s_ret &= "1"
    Case "7"
    $s_ret &= "2"
    Case "6"
    $s_ret &= "3"
    Case "1"
    $s_ret &= "4"
    Case "0"
    $s_ret &= "5"
    Case "3"
    $s_ret &= "6"
    Case "2"
    $s_ret &= "7"
    Case "D"
    $s_ret &= "8"
    Case "C"
    $s_ret &= "9"
    Case "F"
    $s_ret &= "A"
    Case "E"
    $s_ret &= "B"
    Case "9"
    $s_ret &= "C"
    Case "8"
    $s_ret &= "D"
    Case "B"
    $s_ret &= "E"
    Case "A"
    $s_ret &= "F"
    EndSwitch
    Next
    $i_done += 16777215
    Next
    _ArrayAdd($ret_array, Binary($s_ret))
    Until $exitdo = 1
    FileClose($hFile)
    Return $ret_array
    EndFunc ;==>_Decodefile

    [/autoit]

    Schreib mal bitte den genauen Fehler auf, also auch Scriptzeile und so