Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

Code Optimierung
Gehe zu Seite 1, 2  Weiter
 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC.
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
Type



Anmeldungsdatum: 24.02.2006
Beiträge: 187
Wohnort: Dresden

BeitragVerfasst am: 02.02.2012, 17:16    Titel: Code Optimierung Antworten mit Zitat

Hallo Leute,

ich habe mir ein kleines Backup-Programm gebaut, welches die gesicherten Dateien automatisch verschlüsseln soll.

Leider ist es nun doch recht langsam geworden (eine 500 MB Datei dauert bei mir etwa eine halbe Stunde...). Daher wollte ich mal fragen, ob ihr Verbesserungsvorschläge für den Code bzw. mein Vorgehen habt.

Meine Anforderungen waren:
    *Inkrementelles Backup
      *Nur Dateien sollen gesichert werden, die seit dem letzten Backup verändert wurden
      *Gesicherte Dateien und Verzeichnisse sollen gelöscht werden, wenn sie als Original nicht mehr vorhanden sind
    *"Sichere" Verschlüsselung (In meinem Fall mit einer XOR-Verküpfung des Dateiinhaltes mit einem 128 Bit AES Keystream)
    *Komplett in FreeBasic (also ohne Shell-Aufrufe usw.)
    *Auch unter Linux lauffähig
    *Möglichst schnell
Gerade mit dem letzten Punkt bin ich nicht 100%ig zufrieden.

Funktionsweise:

Datei aus Quellverzeichnis lesen -> MD5 Hash erstellen -> (falls die Zieldatei vorhanden) MD5 Hash aus der verschlüsselten Datei extrahieren -> (Im Fall die Hashs seien verschieden) Originaldatei (mit ihrem Hash zusammen) verschlüsseln und speichern

Nebenbei alle Dateien / Ordner aus dem Quellordner in Liste speichern.

Nachdem das durch ist Zielverzeichnis auslesen -> jede Datei / jeden Ordner mit dem Inhalt der Liste vergleichen -> wenn nicht in der Liste, Ordner (rekursiv) / Datei löschen

Danach rekursiv in alle Ordner des Quellverzeichnisses gehen und wieder von vorne anfangen.


Die Vorgehensweise erscheint mir etwas umständlich, könnte man da irgendwie effizienter herangehen?
Außerdem bin ich mir nicht hundertprozentig sicher, ob die Verschlüsselung ausreicht. - Laut Internet ja, wobei mir 256 Bit lieber wären...
Die Rekursionen sind auch ein Problem, wie ich finde (ich mag keine Rekursion...) - wie kann man die am besten rausbekommen, bzw. wie kann ich einen Überlauf verhindern?
Findet ihr irgendwelche anderen Probleme oder Fehler? - Was haltet ihr von dem Programm?

Den Code für die AES Verschlüsselung habe ich von http://www.freebasic-portal.de/code-beispiele/verschluesselung/aes-75.html. Wo ich den Code für den MD5-Hash her habe weiß ich leider nicht mehr (wenn es jemand von euch wissen sollte, wäre ich für eine Info dankbar!).

Danke für eure Hilfe.

MfG Type

P.S.: Ich war mir nicht sicher ob der Thread hier rein sollte oder zu den Projektvorstellungen... - zur Not bitte verschieben.


Hier ist nun der Quelltext (sechsDateien):

rek_dir_list.bas
Code:
'LinkedList
type liste

   as string content
   as liste ptr weiter
   
end type

'Neuen Listenteil vorne Anhängen
'list = Liste, die erweitert werden soll
'content = String der in der Liste gespeichert werden soll
sub add_to_list(byref list as liste ptr, content as string)

   'Neuen Listenteil erstellen
   dim as liste ptr neu = callocate(sizeof(liste))
   'Mit Inhalt füllen
   neu->content = content
   'Zusammensetzen
   neu->weiter = list
   list = neu

end sub

'Inhalt des ersten Listenelements als String zurückgeben. Das Listenelement wird dabei entfernt.
'list = Liste, die verarbeitet werden soll.
function get_from_list(byref list as liste ptr) as string

   'Wenn die Liste leer ist, gibt es nichts zurückzugeben
   if list = 0 then return ""
   
   'Inhalt des ersten Listenelements in result speichern
   dim as string result = list->content

   'Hilsvariable mit dem Rest der Liste erstellen
   dim as liste ptr helper = list->weiter
   'Alte Liste aus dem Speicher nehmen
   deallocate(list)
   'Hilfsvariable wird zu Liste
   list = helper
      
   'Ausgelesen Inhalt zurückgeben
   return result

end function

'Überprüft, ob der gesuchte String in der Liste enthalten ist. (1 bei gefunden, 0 bei nicht gefunden)
'list = Liste, die verarbeitet werden soll.
'content = Suchstring
function list_contents(byval list as liste ptr, content as string) as byte

   'Wenn die Liste leer ist, gibt es den geuschten String nicht
   if list = 0 then return 0
   
   'Durch gesammte Liste (Kopie, siehe byval) iterieren
   do until list = 0
      'Mit 1 beenden, wenn der Inhalt des Listenteils mit dem Suchstring übereinstimmt
      if list->content = content then return 1
      'Nächsten Listenteil auswählen
      list = list->weiter
   loop
   
   'Wenn die gesamte Schleife durchlaufen und die Funktion noch nicht beendet wurde ist Suchstring nicht in der Liste enthalten
   return 0

end function

'Liste löschen
'list = Zu leerende Liste
sub clear_list(byref list as liste ptr)

   dim as liste ptr helper
   
   'Alle Listenteile aus dem Speicher entfernen
   do until list = 0
      helper = list->weiter
      deallocate(list)
      list = helper
   loop

end sub

rmdir_rek.bas
Code:
#include once "rek_dir_list.bas"
#include once "dir.bi"

'Löscht ein Verzeichnis, inklusive Unterverzeichnisse und allen Dateien.
'path = pfad zum zu löschenden Ordner. Muss mit "/" abschließen.
'directory = name des zu löschenden Ordners. Muss mit "/" abschließen
sub rmdir_rek (path as string, directory as string)

   dim as string filename
   dim as liste ptr directory_liste
   'Dateiattribute: Entweder Ordner oder Datei
   dim as integer attrib = fbDirectory OR fbNormal, rattrib

   'Erste Datei im Verzeichnis auslesen
   filename = dir(path+directory+"*", attrib, rattrib)

   do
      if not(filename = ".." or filename = ".") then
         if rattrib = fbDirectory then
            'Wenn gelesenes Objekt Ordner, Name in LinkedList speichern
            add_to_list(directory_liste, filename)
         else
            'Wenn gelesenes Objekt kein Ordner (also Datei), löschen
            kill path+directory+filename
         end if
      end if
      'Nächstes Objekt einlesen
      filename = dir("", attrib, rattrib)
   loop until filename = ""
   

   do until directory_liste = 0
      'Rekursives Aufrufen der Löschfunktion mit allen Ordnern, die im aktuellen Verzeichnis enthalten sind
      rmdir_rek(path+directory, get_from_list(directory_liste)+"/")
   loop
   'Verzeichnis löschen
   rmdir path+directory

end sub

AES.bas
Code:
' AES Encryption Implementation by: Chris Brown(2007) aka Zamaster
'
' -Takes plain text and converts it to encrypted ASCII
' -Keys must be 128 bits in size, or 32 hex places/16 char places
' -Set ed in RIJNDAEL_Encrypt to 2 for decryption, 1 for encryption
'
declare function aes_encrypt (Text as string, Key as string) as string
declare function aes_decrypt (Text as string, Key as string) as string

Sub RIJNDAEL_ConvertEXPtoKey(index As Integer, ekey() As Ubyte, tkey() As Ubyte)
    Dim As Ubyte x,y,b
    b = (index-1)*4
    For y = 1 To 4
        For x = 1 To 4
            tkey(x,y) = ekey(b+x,y)
        Next x
    Next y
End Sub


Function RIJNDAEL_InverseS(v As Ubyte) As Ubyte
    Static As Ubyte RSBOX(0 To 255) = {_
    &H52, &H09, &H6A, &HD5, &H30, &H36, &HA5, &H38, &HBF, &H40, &HA3, &H9E, &H81, &HF3, &HD7, &HFB, _
    &H7C, &HE3, &H39, &H82, &H9B, &H2F, &HFF, &H87, &H34, &H8E, &H43, &H44, &HC4, &HDE, &HE9, &HCB, _
    &H54, &H7B, &H94, &H32, &HA6, &HC2, &H23, &H3D, &HEE, &H4C, &H95, &H0B, &H42, &HFA, &HC3, &H4E, _
    &H08, &H2E, &HA1, &H66, &H28, &HD9, &H24, &HB2, &H76, &H5B, &HA2, &H49, &H6D, &H8B, &HD1, &H25, _   
    &H72, &HF8, &HF6, &H64, &H86, &H68, &H98, &H16, &HD4, &HA4, &H5C, &HCC, &H5D, &H65, &HB6, &H92, _
    &H6C, &H70, &H48, &H50, &HFD, &HED, &HB9, &HDA, &H5E, &H15, &H46, &H57, &HA7, &H8D, &H9D, &H84, _
    &H90, &HD8, &HAB, &H00, &H8C, &HBC, &HD3, &H0A, &HF7, &HE4, &H58, &H05, &HB8, &HB3, &H45, &H06, _
    &HD0, &H2C, &H1E, &H8F, &HCA, &H3F, &H0F, &H02, &HC1, &HAF, &HBD, &H03, &H01, &H13, &H8A, &H6B, _
    &H3A, &H91, &H11, &H41, &H4F, &H67, &HDC, &HEA, &H97, &HF2, &HCF, &HCE, &HF0, &HB4, &HE6, &H73, _
    &H96, &HAC, &H74, &H22, &HE7, &HAD, &H35, &H85, &HE2, &HF9, &H37, &HE8, &H1C, &H75, &HDF, &H6E, _   
    &H47, &HF1, &H1A, &H71, &H1D, &H29, &HC5, &H89, &H6F, &HB7, &H62, &H0E, &HAA, &H18, &HBE, &H1B, _   
    &HFC, &H56, &H3E, &H4B, &HC6, &HD2, &H79, &H20, &H9A, &HDB, &HC0, &HFE, &H78, &HCD, &H5A, &HF4, _
    &H1F, &HDD, &HA8, &H33, &H88, &H07, &HC7, &H31, &HB1, &H12, &H10, &H59, &H27, &H80, &HEC, &H5F, _
    &H60, &H51, &H7F, &HA9, &H19, &HB5, &H4A, &H0D, &H2D, &HE5, &H7A, &H9F, &H93, &HC9, &H9C, &HEF, _
    &HA0, &HE0, &H3B, &H4D, &HAE, &H2A, &HF5, &HB0, &HC8, &HEB, &HBB, &H3C, &H83, &H53, &H99, &H61, _
    &H17, &H2B, &H04, &H7E, &HBA, &H77, &HD6, &H26, &HE1, &H69, &H14, &H63, &H55, &H21, &H0C, &H7D}
    Dim As Integer x
    x = RSBOX((v And &HF0) + (v And &HF))
    Return x
End Function





Function RIJNDAEL_S(v As Ubyte) As Ubyte
    Static As Ubyte RSBOX(0 To 255) = {_
    &H63, &H7C, &H77, &H7B, &HF2, &H6B, &H6F, &HC5, &H30, &H01, &H67, &H2B, &HFE, &HD7, &HAB, &H76, _
    &HCA, &H82, &HC9, &H7D, &HFA, &H59, &H47, &HF0, &HAD, &HD4, &HA2, &HAF, &H9C, &HA4, &H72, &HC0, _
    &HB7, &HFD, &H93, &H26, &H36, &H3F, &HF7, &HCC, &H34, &HA5, &HE5, &HF1, &H71, &HD8, &H31, &H15, _
    &H04, &HC7, &H23, &HC3, &H18, &H96, &H05, &H9A, &H07, &H12, &H80, &HE2, &HEB, &H27, &HB2, &H75, _
    &H09, &H83, &H2C, &H1A, &H1B, &H6E, &H5A, &HA0, &H52, &H3B, &HD6, &HB3, &H29, &HE3, &H2F, &H84, _
    &H53, &HD1, &H00, &HED, &H20, &HFC, &HB1, &H5B, &H6A, &HCB, &HBE, &H39, &H4A, &H4C, &H58, &HCF, _
    &HD0, &HEF, &HAA, &HFB, &H43, &H4D, &H33, &H85, &H45, &HF9, &H02, &H7F, &H50, &H3C, &H9F, &HA8, _
    &H51, &HA3, &H40, &H8F, &H92, &H9D, &H38, &HF5, &HBC, &HB6, &HDA, &H21, &H10, &HFF, &HF3, &HD2, _
    &HCD, &H0C, &H13, &HEC, &H5F, &H97, &H44, &H17, &HC4, &HA7, &H7E, &H3D, &H64, &H5D, &H19, &H73, _
    &H60, &H81, &H4F, &HDC, &H22, &H2A, &H90, &H88, &H46, &HEE, &HB8, &H14, &HDE, &H5E, &H0B, &HDB, _   
    &HE0, &H32, &H3A, &H0A, &H49, &H06, &H24, &H5C, &HC2, &HD3, &HAC, &H62, &H91, &H95, &HE4, &H79, _
    &HE7, &HC8, &H37, &H6D, &H8D, &HD5, &H4E, &HA9, &H6C, &H56, &HF4, &HEA, &H65, &H7A, &HAE, &H08, _
    &HBA, &H78, &H25, &H2E, &H1C, &HA6, &HB4, &HC6, &HE8, &HDD, &H74, &H1F, &H4B, &HBD, &H8B, &H8A, _
    &H70, &H3E, &HB5, &H66, &H48, &H03, &HF6, &H0E, &H61, &H35, &H57, &HB9, &H86, &HC1, &H1D, &H9E, _
    &HE1, &HF8, &H98, &H11, &H69, &HD9, &H8E, &H94, &H9B, &H1E, &H87, &HE9, &HCE, &H55, &H28, &HDF, _
    &H8C, &HA1, &H89, &H0D, &HBF, &HE6, &H42, &H68, &H41, &H99, &H2D, &H0F, &HB0, &H54, &HBB, &H16}
    Dim As Integer x
    x = RSBOX((v And &HF0) + (v And &HF))
    Return x
End Function


Sub RIJNDAEL_SubBytes(T() As Ubyte)   
    Dim As Ubyte x,y, temp
    For y = 1 To 4
        For x = 1 To 4
            temp = T(x,y)
            T(x,y) = RIJNDAEL_S(temp)
        Next x
    Next y
End Sub

Sub RIJNDAEL_InverseSubBytes(T() As Ubyte)   
    Dim As Ubyte x,y, temp
    For y = 1 To 4
        For x = 1 To 4
            temp = T(x,y)
            T(x,y) = RIJNDAEL_InverseS(temp)
        Next x
    Next y
End Sub


Sub RIJNDAEL_ShiftRows(T() As Ubyte)
    Swap T(1,2), T(4,2)
    Swap T(2,2), T(1,2)
    Swap T(3,2), T(2,2)
    Swap T(1,3), T(3,3)
    Swap T(2,3), T(4,3)
    Swap T(1,4), T(2,4)
    Swap T(3,4), T(4,4)
    Swap T(1,4), T(3,4)
End Sub

Sub RIJNDAEL_InverseShiftRows(T() As Ubyte)
    Swap T(1,2), T(2,2)
    Swap T(1,2), T(4,2)
    Swap T(3,2), T(4,2)
    Swap T(1,3), T(3,3)
    Swap T(2,3), T(4,3)
    Swap T(1,4), T(2,4)
    Swap T(2,4), T(3,4)
    Swap T(3,4), T(4,4)
End Sub



Function RIJNDAEL_Gmul(Byval a As Ubyte, Byval b As Ubyte) As Ubyte
    Dim As Ubyte p, i, hi
    For i = 1 To 8
        If (b And 1) = &H01 Then p = p Xor a
        hi = a And &H80
        a = a Shl 1
        If hi = &H80 Then a = a Xor &H1B
        b = b Shr 1
    Next i
    Return p
End Function


Sub RIJNDAEL_MixCollums(T() As Ubyte)
    Dim As Ubyte a(1 To 4), b(1 To 4), i, q, hb
    For q = 1 To 4
        For i = 1 To 4
            a(i) = T(q,i)
            hb = T(q,i) And &H80
            b(i) = a(i) Shl 1
            If hb = &h80 Then b(i) = b(i) Xor &H1B
        Next i
        T(q,1) = b(1) Xor a(4) Xor a(3) Xor b(2) Xor a(2)
        T(q,2) = b(2) Xor a(1) Xor a(4) Xor b(3) Xor a(3)
        T(q,3) = b(3) Xor a(2) Xor a(1) Xor b(4) Xor a(4)
        T(q,4) = b(4) Xor a(3) Xor a(2) Xor b(1) Xor a(1)
    Next q
End Sub

Sub RIJNDAEL_InverseMixCollums(T() As Ubyte)
    Dim As Ubyte a(1 To 4), q, i
    For q = 1 To 4
        For i = 1 To 4
            a(i) = T(q,i)
        Next
        T(q,1) = RIJNDAEL_Gmul(a(1),&HE) Xor RIJNDAEL_Gmul(a(2),&HB) Xor RIJNDAEL_Gmul(a(3),&HD) Xor RIJNDAEL_Gmul(a(4),&H9)
        T(q,2) = RIJNDAEL_Gmul(a(1),&H9) Xor RIJNDAEL_Gmul(a(2),&HE) Xor RIJNDAEL_Gmul(a(3),&HB) Xor RIJNDAEL_Gmul(a(4),&HD)
        T(q,3) = RIJNDAEL_Gmul(a(1),&HD) Xor RIJNDAEL_Gmul(a(2),&H9) Xor RIJNDAEL_Gmul(a(3),&HE) Xor RIJNDAEL_Gmul(a(4),&HB)
        T(q,4) = RIJNDAEL_Gmul(a(1),&HB) Xor RIJNDAEL_Gmul(a(2),&HD) Xor RIJNDAEL_Gmul(a(3),&H9) Xor RIJNDAEL_Gmul(a(4),&HE)
    Next q
End Sub


Sub RIJNDAEL_AddKey(T() As Ubyte, K() As Ubyte)
    Dim As Ubyte x,y
    For y = 1 To 4
        For x = 1 To 4
            T(x,y) = T(x,y) Xor K(x,y)
        Next x
    Next y
End Sub


Sub RIJNDAEL_ExpandKey(K1() As Ubyte, K2() As Ubyte)
    Static As Ubyte RCON(1 To 10) = {&H01, &H02, &H04, &H08, &H10, &H20, &H40, &H80, &H1B, &H36}
    Dim As Integer i, q, a, opt4, opt4m1, opt4m4, o4, om1, om4
    K2(1,1) = K1(1,1) Xor RIJNDAEL_S(K1(4,2)) Xor RCON(1)
    K2(1,2) = K1(1,2) Xor RIJNDAEL_S(K1(4,3))
    K2(1,3) = K1(1,3) Xor RIJNDAEL_S(K1(4,4))
    K2(1,4) = K1(1,4) Xor RIJNDAEL_S(K1(4,1))
    For i = 2 To 4
        For q = 1 To 4
            K2(i,q) = K2(i-1,q) Xor K1(i,q)
        Next q
    Next i
   
    For i = 2 To 10
        opt4 = ((i-1) Shl 2) + 1
        opt4m1 = opt4 - 1
        opt4m4 = opt4 - 4
        K2(opt4,1) = K2(opt4m4,1) Xor RIJNDAEL_S(K2(opt4m1,2)) Xor RCON(i)
        K2(opt4,2) = K2(opt4m4,2) Xor RIJNDAEL_S(K2(opt4m1,3))
        K2(opt4,3) = K2(opt4m4,3) Xor RIJNDAEL_S(K2(opt4m1,4))
        K2(opt4,4) = K2(opt4m4,4) Xor RIJNDAEL_S(K2(opt4m1,1))
        For q = 2 To 4
            o4 = opt4m1 + q
            om1 = o4-1
            om4 = o4-4
            For a = 1 To 4
                K2(o4,a) = K2(om1,a) Xor K2(om4,a)
            Next a
        Next q
    Next i
End Sub


Sub RIJNDAEL_TextToState(Byref texts As String, T() As Ubyte, dirc As Integer)
    Dim As String text
    text = texts
    Dim As Ubyte x,y
    If dirc = 1 Then
        For y = 1 To 4
            For x = 1 To 4
                T(x,y) = Asc(Mid$(text,(((y-1) Shl 2) + x),1))
            Next x
        Next y
    Else
        For y = 1 To 4
            For x = 1 To 4
                T(y,x) = Asc(Mid$(text,(((y-1) Shl 2) + x),1))
            Next x
        Next y
    Endif
End Sub

Sub RIJNDAEL_Rotate(K() As Ubyte)
    Swap K(1,2), K(2,1)
    Swap K(1,3), K(3,1)
    Swap K(1,4), K(4,1)
    Swap K(2,4), K(4,2)
    Swap K(3,4), K(4,3)
    Swap K(2,3), K(3,2)
End Sub

Function RIJNDAEL_StateToText(T() As Ubyte) As String
    Dim As String s
    Dim As Integer x,y
    For y = 1 To 4
        For x = 1 To 4
            s += Chr$(T(x,y))
        Next x
    Next y
    Return s
End Function

Function RIJNDAEL_StrToHex (Byref s As String) As String
    Dim As String convstr
    convstr = s
    Dim As Uinteger i
    Dim As String ftext
    For i = 1 To Len(convstr)
        ftext += Hex$(Asc(Mid$(convstr,i,1)),2)
    Next i
    Return ftext
End Function

Function RIJNDAEL_HexToStr (Byref s As String) As String
    Dim As String convstr
    convstr = s
    If Len(convstr) Mod 2 = 1 Then convstr += "0"
    Dim As Uinteger i
    Dim As String   f
    For i = 1 To Len(convstr) Step 2
        f += Chr$(Val("&H"+Mid$(convstr,i,2)))
    Next i
    Return f
End Function


Sub RIJNDAEL_BlockEncrypt(T() As Ubyte, K1() As Ubyte, K2() As Ubyte)
    Dim As Integer i
    Dim As Ubyte TempKey(1 To 4, 1 To 4)
    RIJNDAEL_AddKey T(), K1()
    RIJNDAEL_Rotate T()
    For i = 1 To 9
        RIJNDAEL_SubBytes T()
        RIJNDAEL_ShiftRows T()
        RIJNDAEL_MixCollums T()
        RIJNDAEL_ConvertEXPtoKey i, K2(), TempKey()
        RIJNDAEL_AddKey T(), TempKey()
    Next i
    RIJNDAEL_SubBytes T()
    RIJNDAEL_ShiftRows T()
    RIJNDAEL_ConvertEXPtoKey 10, K2(), TempKey()
    RIJNDAEL_AddKey T(), TempKey()
End Sub


Sub RIJNDAEL_BlockDecrypt(T() As Ubyte, K1() As Ubyte, K2() As Ubyte)
    Dim As Integer i
    Dim As Ubyte TempKey(1 To 4, 1 To 4)
    RIJNDAEL_ConvertEXPtoKey 10, K2(), TempKey()
    RIJNDAEL_AddKey T(), TempKey()
    For i = 9 To 1 Step -1
        RIJNDAEL_InverseShiftRows T()
        RIJNDAEL_InverseSubBytes T()
        RIJNDAEL_ConvertEXPtoKey i, K2(), TempKey()
        RIJNDAEL_AddKey T(), TempKey()
        RIJNDAEL_InverseMixCollums T()
    Next i
    RIJNDAEL_InverseShiftRows T()
    RIJNDAEL_InverseSubBytes T()
    RIJNDAEL_AddKey T(), K1()
End Sub


Function RIJNDAEL_Encrypt(Byref pptext As String, Byref Key As String, ed As Integer) As String
    If ed < 1 Or ed > 2 Then
        Beep
        Return "ERROR - NO SUCH ENCRYPTION MODE"
    Endif
    Dim As String ptext, ctext, mtext
    ptext = pptext
    Dim As Integer lt
    lt = Len(Key)
    If (lt Mod 16 <> 0) Or (lt Shr 4 <> 1) Then
        Return "ERROR - INVALID KEY"
    Endif
    Dim As Integer pmod, i
    lt = Len(ptext)
    pmod = lt Mod 16
    If pmod <> 0 Or lt < 1 Then
        pmod = 16 - pmod
        For i = 1 To pmod
            ptext += Chr$(0)
        Next i
    Endif
    lt = Len(ptext)
    lt = lt Shr 4
    Dim As Ubyte State(1 To 4, 1 To 4), KeyT(1 To 4, 1 To 4), EXPKey(1 To 40, 1 To 4)
    RIJNDAEL_TextToState Key, KeyT(), 2
    RIJNDAEL_ExpandKey KeyT(), EXPKey()
    Select Case ed
    Case 1
        For i = 1 To lt
            mtext = Mid$(ptext, ((i-1) Shl 4) + 1, 16)
            RIJNDAEL_TextToState mtext, State(), 1
            RIJNDAEL_BlockEncrypt State(), KeyT(), EXPKey()
            ctext += RIJNDAEL_StateToText(State())
        Next i
    Case 2
        RIJNDAEL_Rotate KeyT()
        For i = 1 To lt
            mtext = Mid$(ptext, ((i-1) Shl 4) + 1, 16)
            RIJNDAEL_TextToState mtext, State(), 1
            RIJNDAEL_BlockDecrypt State(), KeyT(), EXPKey()
            RIJNDAEL_Rotate State()
            ctext += RIJNDAEL_StateToText(State())
        Next i
    End Select
    Return ctext
End Function


function aes_encrypt(Text as string, Key as string) as string export
    if len(Key) <> 16 then
        exit function
    end if
    dim encrypted as string
    encrypted = RIJNDAEL_Encrypt(Text, Key, 1)
    return encrypted
end function

function aes_decrypt(Text as string, Key as string) as string export
    dim decrypted as string
    decrypted = RIJNDAEL_Encrypt(Text, Key, 2)
    return decrypted
end function

MD5Cheksum.bi
Code:
'MD5Checksum

'Initialisierungskonstanten
#Define MD5_INIT_STATE_0 &H67452301
#Define MD5_INIT_STATE_1 &Hefcdab89
#Define MD5_INIT_STATE_2 &H98badcfe
#Define MD5_INIT_STATE_3 &H10325476

'Konstanten für den Transformationsprozess
#Define MD5_S11 7
#Define MD5_S12 12
#Define MD5_S13 17
#Define MD5_S14 22
#Define MD5_S21 5
#Define MD5_S22 9
#Define MD5_S23 14
#Define MD5_S24 20
#Define MD5_S31 4
#Define MD5_S32 11
#Define MD5_S33 16
#Define MD5_S34 23
#Define MD5_S41 6
#Define MD5_S42 10
#Define MD5_S43 15
#Define MD5_S44 21

'Transformierungskonstanten - Runde 1
#Define MD5_T01  &Hd76aa478 'Transformationskonstante 1
#Define MD5_T02  &He8c7b756 'Transformationskonstante 2
#Define MD5_T03  &H242070db 'Transformationskonstante 3
#Define MD5_T04  &Hc1bdceee 'Transformationskonstante 4
#Define MD5_T05  &Hf57c0faf 'Transformationskonstante 5
#Define MD5_T06  &H4787c62a 'Transformationskonstante 6
#Define MD5_T07  &Ha8304613 'Transformationskonstante 7
#Define MD5_T08  &Hfd469501 'Transformationskonstante 8
#Define MD5_T09  &H698098d8 'Transformationskonstante 9
#Define MD5_T10  &H8b44f7af 'Transformationskonstante 10
#Define MD5_T11  &Hffff5bb1 'Transformationskonstante 11
#Define MD5_T12  &H895cd7be 'Transformationskonstante 12
#Define MD5_T13  &H6b901122 'Transformationskonstante 13
#Define MD5_T14  &Hfd987193 'Transformationskonstante 14
#Define MD5_T15  &Ha679438e 'Transformationskonstante 15
#Define MD5_T16  &H49b40821 'Transformationskonstante 16

'Transformierungskonstanten - Runde 2
#Define MD5_T17  &Hf61e2562 'Transformationskonstante 17
#Define MD5_T18  &Hc040b340 'Transformationskonstante 18
#Define MD5_T19  &H265e5a51 'Transformationskonstante 19
#Define MD5_T20  &He9b6c7aa 'Transformationskonstante 20
#Define MD5_T21  &Hd62f105d 'Transformationskonstante 21
#Define MD5_T22  &H02441453 'Transformationskonstante 22
#Define MD5_T23  &Hd8a1e681 'Transformationskonstante 23
#Define MD5_T24  &He7d3fbc8 'Transformationskonstante 24
#Define MD5_T25  &H21e1cde6 'Transformationskonstante 25
#Define MD5_T26  &Hc33707d6 'Transformationskonstante 26
#Define MD5_T27  &Hf4d50d87 'Transformationskonstante 27
#Define MD5_T28  &H455a14ed 'Transformationskonstante 28
#Define MD5_T29  &Ha9e3e905 'Transformationskonstante 29
#Define MD5_T30  &Hfcefa3f8 'Transformationskonstante 30
#Define MD5_T31  &H676f02d9 'Transformationskonstante 31
#Define MD5_T32  &H8d2a4c8a 'Transformationskonstante 32

'Transformierungskonstanten - Runde 3
#Define MD5_T33  &Hfffa3942 'Transformationskonstante 33
#Define MD5_T34  &H8771f681 'Transformationskonstante 34
#Define MD5_T35  &H6d9d6122 'Transformationskonstante 35
#Define MD5_T36  &Hfde5380c 'Transformationskonstante 36
#Define MD5_T37  &Ha4beea44 'Transformationskonstante 37
#Define MD5_T38  &H4bdecfa9 'Transformationskonstante 38
#Define MD5_T39  &Hf6bb4b60 'Transformationskonstante 39
#Define MD5_T40  &Hbebfbc70 'Transformationskonstante 40
#Define MD5_T41  &H289b7ec6 'Transformationskonstante 41
#Define MD5_T42  &Heaa127fa 'Transformationskonstante 42
#Define MD5_T43  &Hd4ef3085 'Transformationskonstante 43
#Define MD5_T44  &H04881d05 'Transformationskonstante 44
#Define MD5_T45  &Hd9d4d039 'Transformationskonstante 45
#Define MD5_T46  &He6db99e5 'Transformationskonstante 46
#Define MD5_T47  &H1fa27cf8 'Transformationskonstante 47
#Define MD5_T48  &Hc4ac5665 'Transformationskonstante 48

'Transformierungskonstanten - Runde 4
#Define MD5_T49  &Hf4292244 'Transformationskonstante 49
#Define MD5_T50  &H432aff97 'Transformationskonstante 50
#Define MD5_T51  &Hab9423a7 'Transformationskonstante 51
#Define MD5_T52  &Hfc93a039 'Transformationskonstante 52
#Define MD5_T53  &H655b59c3 'Transformationskonstante 53
#Define MD5_T54  &H8f0ccc92 'Transformationskonstante 54
#Define MD5_T55  &Hffeff47d 'Transformationskonstante 55
#Define MD5_T56  &H85845dd1 'Transformationskonstante 56
#Define MD5_T57  &H6fa87e4f 'Transformationskonstante 57
#Define MD5_T58  &Hfe2ce6e0 'Transformationskonstante 58
#Define MD5_T59  &Ha3014314 'Transformationskonstante 59
#Define MD5_T60  &H4e0811a1 'Transformationskonstante 60
#Define MD5_T61  &Hf7537e82 'Transformationskonstante 61
#Define MD5_T62  &Hbd3af235 'Transformationskonstante 62
#Define MD5_T63  &H2ad7d2bb 'Transformationskonstante 63
#Define MD5_T64  &Heb86d391 'Transformationskonstante 64

'Null Daten (außer des ersten BYTE) werden benutzt, um die Prüfsummenberechnung zu beenden
Dim Shared As UByte PADDING(64) => { _
   &H80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }

'*******************************************************

#Define RotateLeft(x, n) ((x Shl n) Or (x Shr (32 - n)))

#Macro FF(a, b, c, d, x, s, t)
   a += ((b And c) Or ((Not b) And d)) + x + t
   a = RotateLeft(a, s) + b
#EndMacro

#Macro GG(a, b, c, d, x, s, t)
   a += ((b And d) Or (c And (Not d))) + x + t
   a = RotateLeft(a, s) + b
#EndMacro

#Macro HH(a, b, c, d, x, s, t)
   a += (b Xor c Xor d) + x + t
   a = RotateLeft(a, s) + b
#EndMacro

#Macro II(a, b, c, d, x, s, t)
   a += (c Xor (b Or (Not d))) + x + t
   a = RotateLeft(a, s) + b
#EndMacro

'*******************************************************

Type MD5Checksum
   Public:
   'Konstruktor/Destruktor
   Declare Constructor()
   Declare Destructor()
   
   'RSA MD5 Implementierung
   Declare Sub Transform(block As UByte Ptr)
   Declare Sub Update(inpt As UByte Ptr, nInputLen As UInteger)
   Declare Function Final() As String
   
   Protected:
   'Nebenfunktionen
   Declare Sub UIntegerToUByte(outpt As UByte Ptr, inpt As UInteger Ptr, nLength As UInteger)
   Declare Sub UByteToUInteger(outpt As UInteger Ptr, inpt As UByte Ptr, nLength As UInteger)
   
   Private:
   As UByte m_lpszBuffer(64)   'Eingabepuffer
   As UInteger m_nCount(2)      'Anzahl der bits, modulo 2^64 (lsb zuerst)
   As UInteger m_lMD5(4)      'MD5 Prüfsumme
End Type

MD5Cheksum.bas
Code:
#Include "MD5Checksum.bi"

#Ifndef memcpy
   Function memcpy(destination As UByte Ptr, source As UByte Ptr, num As UInteger) As UByte Ptr
      'Ersatz für "crt/string.bi"
      'Prüft nicht nach der Größe von Destination
      For i As Integer = 0 To num - 1
         destination[i]  = source[i]
      Next
      Return destination
   End Function
#EndIf

Sub MD5Checksum.UByteToUInteger(outpt As UInteger Ptr, inpt As UByte Ptr, nLength As UInteger)
   'Initialisierung
   Dim As UInteger i = 0
   Dim As UInteger j = 0
   
   'transferiere die Daten durch shifting und kopieren
   While j < nLength
      outpt[i] = (Cast(UInteger, inpt[j])) Or (Cast(UInteger, inpt[j+1]) Shl 8) Or (Cast(UInteger, inpt[j+2]) Shl 16) Or (Cast(UInteger, inpt[j+3]) Shl 24)
      i += 1
      j += 4
   Wend
End Sub

Sub MD5Checksum.Transform(block As UByte Ptr)
   'initialisiere die lokalen Daten mit der aktuellen checksum
   Dim As UInteger a = m_lMD5(0)
   Dim As UInteger b = m_lMD5(1)
   Dim As UInteger c = m_lMD5(2)
   Dim As UInteger d = m_lMD5(3)
   
   'Kopiert Bytes aus input 'Block' in ein Array von UIntegers 'X'
   Dim As UInteger X(16)
   UByteToUInteger(@X(0), block, 64)
   
   'Runde 1 Transformation
   FF(a, b, c, d, X( 0), MD5_S11, MD5_T01)
   FF(d, a, b, c, X( 1), MD5_S12, MD5_T02)
   FF(c, d, a, b, X( 2), MD5_S13, MD5_T03)
   FF(b, c, d, a, X( 3), MD5_S14, MD5_T04)
   FF(a, b, c, d, X( 4), MD5_S11, MD5_T05)
   FF(d, a, b, c, X( 5), MD5_S12, MD5_T06)
   FF(c, d, a, b, X( 6), MD5_S13, MD5_T07)
   FF(b, c, d, a, X( 7), MD5_S14, MD5_T08)
   FF(a, b, c, d, X( 8), MD5_S11, MD5_T09)
   FF(d, a, b, c, X( 9), MD5_S12, MD5_T10)
   FF(c, d, a, b, X(10), MD5_S13, MD5_T11)
   FF(b, c, d, a, X(11), MD5_S14, MD5_T12)
   FF(a, b, c, d, X(12), MD5_S11, MD5_T13)
   FF(d, a, b, c, X(13), MD5_S12, MD5_T14)
   FF(c, d, a, b, X(14), MD5_S13, MD5_T15)
   FF(b, c, d, a, X(15), MD5_S14, MD5_T16)
   
   'Runde 2 Transformation
   GG(a, b, c, d, X( 1), MD5_S21, MD5_T17)
   GG(d, a, b, c, X( 6), MD5_S22, MD5_T18)
   GG(c, d, a, b, X(11), MD5_S23, MD5_T19)
   GG(b, c, d, a, X( 0), MD5_S24, MD5_T20)
   GG(a, b, c, d, X( 5), MD5_S21, MD5_T21)
   GG(d, a, b, c, X(10), MD5_S22, MD5_T22)
   GG(c, d, a, b, X(15), MD5_S23, MD5_T23)
   GG(b, c, d, a, X( 4), MD5_S24, MD5_T24)
   GG(a, b, c, d, X( 9), MD5_S21, MD5_T25)
   GG(d, a, b, c, X(14), MD5_S22, MD5_T26)
   GG(c, d, a, b, X( 3), MD5_S23, MD5_T27)
   GG(b, c, d, a, X( 8), MD5_S24, MD5_T28)
   GG(a, b, c, d, X(13), MD5_S21, MD5_T29)
   GG(d, a, b, c, X( 2), MD5_S22, MD5_T30)
   GG(c, d, a, b, X( 7), MD5_S23, MD5_T31)
   GG(b, c, d, a, X(12), MD5_S24, MD5_T32)
   
   'Runde 3 Transformation
   HH(a, b, c, d, X( 5), MD5_S31, MD5_T33)
   HH(d, a, b, c, X( 8), MD5_S32, MD5_T34)
   HH(c, d, a, b, X(11), MD5_S33, MD5_T35)
   HH(b, c, d, a, X(14), MD5_S34, MD5_T36)
   HH(a, b, c, d, X( 1), MD5_S31, MD5_T37)
   HH(d, a, b, c, X( 4), MD5_S32, MD5_T38)
   HH(c, d, a, b, X( 7), MD5_S33, MD5_T39)
   HH(b, c, d, a, X(10), MD5_S34, MD5_T40)
   HH(a, b, c, d, X(13), MD5_S31, MD5_T41)
   HH(d, a, b, c, X( 0), MD5_S32, MD5_T42)
   HH(c, d, a, b, X( 3), MD5_S33, MD5_T43)
   HH(b, c, d, a, X( 6), MD5_S34, MD5_T44)
   HH(a, b, c, d, X( 9), MD5_S31, MD5_T45)
   HH(d, a, b, c, X(12), MD5_S32, MD5_T46)
   HH(c, d, a, b, X(15), MD5_S33, MD5_T47)
   HH(b, c, d, a, X( 2), MD5_S34, MD5_T48)
   
   'Runde 4 Transformation
   II(a, b, c, d, X( 0), MD5_S41, MD5_T49)
   II(d, a, b, c, X( 7), MD5_S42, MD5_T50)
   II(c, d, a, b, X(14), MD5_S43, MD5_T51)
   II(b, c, d, a, X( 5), MD5_S44, MD5_T52)
   II(a, b, c, d, X(12), MD5_S41, MD5_T53)
   II(d, a, b, c, X( 3), MD5_S42, MD5_T54)
   II(c, d, a, b, X(10), MD5_S43, MD5_T55)
   II(b, c, d, a, X( 1), MD5_S44, MD5_T56)
   II(a, b, c, d, X( 8), MD5_S41, MD5_T57)
   II(d, a, b, c, X(15), MD5_S42, MD5_T58)
   II(c, d, a, b, X( 6), MD5_S43, MD5_T59)
   II(b, c, d, a, X(13), MD5_S44, MD5_T60)
   II(a, b, c, d, X( 4), MD5_S41, MD5_T61)
   II(d, a, b, c, X(11), MD5_S42, MD5_T62)
   II(c, d, a, b, X( 2), MD5_S43, MD5_T63)
   II(b, c, d, a, X( 9), MD5_S44, MD5_T64)
   
   'Füge die veränderten Werte zur aktuellen Checksum hinzu
   m_lMD5(0) += a
   m_lMD5(1) += b
   m_lMD5(2) += c
   m_lMD5(3) += d
End Sub

Constructor MD5Checksum
   'Initialisierung
   m_nCount(0) = 0
   m_nCount(1) = 0
   
   'Lade magic state Initialisierungskonstanten
   m_lMD5(0) = MD5_INIT_STATE_0
   m_lMD5(1) = MD5_INIT_STATE_1
   m_lMD5(2) = MD5_INIT_STATE_2
   m_lMD5(3) = MD5_INIT_STATE_3
End Constructor

Destructor MD5Checksum
   
End Destructor

Sub MD5Checksum.UIntegerToUByte(outpt As UByte Ptr, inpt As UInteger Ptr, nLength As UInteger)
   'Initialisierung
   Dim As UInteger i      'Index des Zeilarrays
   Dim As UInteger j      'Index des Quellarrays
   
   'transferiere die Daten durch shifting und kopieren
   While j < nLength
      outpt[ j ] = Cast(UByte, (inpt[i]       ))
      outpt[j+1] = Cast(UByte, (inpt[i] Shr  8))
      outpt[j+2] = Cast(UByte, (inpt[i] Shr 16))
      outpt[j+3] = Cast(UByte, (inpt[i] Shr 24))
      i += 1
      j += 4
   Wend
End Sub

Function MD5Checksum.Final() As String
   'Sichere Anzahl der Bits
   Dim As UByte bits(8)
   UIntegerToUByte(@bits(0), @m_nCount(0), 8)
   
   'Auffüllen bis 56 mod 64
   Dim As UInteger nIndex = Cast(UInteger, (m_nCount(0) Shr 3) And &H3f)
   Dim As UInteger nPadLen = IIf((nIndex < 56), (56 - nIndex), (120 - nIndex))
   Update(@PADDING(0), nPadLen)
   
   'Füge die Länge hinzu (vor dem Auffüllen)
   Update(@bits(0), 8)
   
   'Sichere final state in 'lpszMD5'
   Dim As UByte lpszMD5(16)
   UIntegerToUByte(@lpszMD5(0), @m_lMD5(0), 16)
   
   'Konvertiere die hexadezimale Checksum in einen String
   Dim As String strMD5
   For i As Integer = 0 To 15
      Dim As String Strn
      If lpszMD5(i) = 0 Then
         Strn = "00"
      ElseIf lpszMD5(i) <= 15 Then
         Strn = "0" + Str(Hex(lpszMD5(i)))
      Else
         Strn = Str(Hex(lpszMD5(i)))
      EndIf
      
      strMD5 += Strn
   Next
   
   Return strMD5
End Function

Sub MD5Checksum.Update(inpt As UByte Ptr, nInputLen As UInteger)
   'Anzahl der Bytes mod 64 berechnen
   Dim As UInteger nIndex = Cast(UInteger, ((m_nCount(0) Shr 3) And &H3f))
   
   'Anzahl der Bits aktualisieren
   m_nCount(0) += (nInputLen Shl 3)
   If (m_nCount(0) < (nInputLen Shl 3)) Then
      m_nCount(1) += 1
   EndIf
   m_nCount(1) += (nInputLen Shr 29)
   
   'Transformiere so oft wie möglich
   Dim As UInteger i = 0
   Dim As UInteger nPartLen = 64 - nIndex
   If (nInputLen >= nPartLen) Then
      memcpy(@m_lpszBuffer(nIndex), inpt, nPartLen)
      
      Transform(@m_lpszBuffer(0))
      
      i = nPartLen
      While i + 63 < nInputLen
         Transform(@inpt[i])
         i += 64
      Wend
      
      nIndex = 0
   Else
      i = 0
   EndIf
   
   'Übrig gebliebenen Input in Buffer
   memcpy(@m_lpszBuffer(nIndex), @inpt[i], nInputLen - i)
End Sub

Function createHash(text As String) As String
   Dim As UInteger nLength = Len(text)
   If nLength = 0 Then
      Return "Kein Text enthalten"
   EndIf
   
   Dim As UByte buffer(16384)
   For i As Integer = 1 To nLength
      buffer(i - 1) = Asc(Mid(text, i ,1))
   Next
   
   Dim As MD5Checksum MD5
   MD5.Update(@buffer(0), nLength)
   
   Return MD5.Final()
End Function

Function createFileHash(file As String) As String
   Dim As UInteger nLength = Len(file)
   If nLength = 0 Then
      Return "Keine Datei angegeben"
   EndIf
   
   Dim As Integer FFF = FreeFile
   If Open(file For Binary Access Read As #FFF) <> 0 Then
      Return "Datei konnte nicht gefunden/geöffnet werden"
   EndIf
   
   Dim As UInteger fileLength = Lof(FFF)
   If fileLength = 0 Then
      Close #FFF
      Return "Leere Datei"
   EndIf
   
   Dim As UByte buffer(16384)
   Dim As UInteger toBuffer
   Dim As MD5Checksum MD5
   Do Until fileLength = 0
      If fileLength >= 16384 Then
         fileLength -= 16384
         toBuffer = 16384
      Else
         toBuffer = fileLength
         fileLength = 0
      EndIf
      Get #FFF, , buffer(0), toBuffer
      MD5.Update(@buffer(0), toBuffer)
   Loop
   Close #FFF
   
   Return MD5.Final()
End Function

crypt.bas
Code:
#include once "AES.bas"
#Include once "MD5Checksum.bas"

#define decrypt 0
#define encrypt not(decrypt)   '-1

'128 Bit Eingabestring mit 128 Bit Schlüssel AES-Verschlüsseln
'iv = String der verschlüsselt werden soll
'key = Passwort
function set_initial_vector (iv as string, key as string) as string

   'Prüfen ob die Länge der Strings in Ordnung ist (genau 16 Zeichen = 16 * 8 = 128 Bit
   if len(key) <> 16 then print "ERROR1"
   if len(iv) <> 16 then print "ERROR2"

   'String verschlüsseln und zurückgeben
   return aes_encrypt(iv, key)

end function

'Ein ByteArray wird Byteweise im einem Eingabestring geXORt.
'Dabei kann der Eingabestring größer sein, als das Array
'iv = Eingabestring
'value() = ByteArray
function encrypt_value (iv as string, value() as byte) as string
   
   dim as string result
   
   'ASC-Code eines einzelnen String-Zeichens wird mit Byte aus dem Array XOR genommen
   for a as integer = 0 to ubound(value)
      result += chr(value(a) xor iv[a])
   next a
   
   return result
   
end function

'Holt den MD5-Hash aus einer verschlüsselten Datei
'datei = Dateiname
'key = Passwort, mit dem die Datei verschlüsselt wurde
function readFilehash(datei as string, key as string) as string

   dim as ubyte file = freefile
   dim as ubyte head(31)
   dim as string hash
   dim as string vektor = key
   dim as string keystream
   
   'Die ersten 32 Byte der Datei werden in hash gespeichert
   'Ist die Datei zu klein, ist sie in jedem Fall ungültig. => Rückgabe ist leer
   open datei for binary lock write as #file
      if lof(file) < 32 then return ""      
      get #file, ,head()
   close #file
   
   'Keystream von 32 Byte Länge erzeugen
   'Passwort wird AES-Verschlüsselt.
   '-> 16 Byte String wird in keystream gespeichert, 16 Byte String nochmal AES verschlüsselt
   '-> Neuer 16 Byte String wird in keystream angehängt.
   for a as byte= 0 to 1
      vektor = set_initial_vector(vektor, key)
      keystream += vektor
   next a
   'hash dekodieren
   hash = encrypt_value(keystream, head())
   
   return hash

end function


'Alte Kopierfunktion (langsam)
sub crypt_copyfile (original as string, kopie as string, key as string, encrypt_state as byte)

   redim as ubyte block(15)
   dim as string vektor
   dim as string hash
   
   select case encrypt_state
      case decrypt
         vektor = set_initial_vector(set_initial_vector(key, key), key)
         hash = createFileHash(kopie)
         if hash = readFileHash(original, key) then exit sub
      case else
         vektor = key
         hash = createFileHash(original)
         if hash = readFileHash(kopie, key) then exit sub
   end select

   '~ print "Lösche ";encrypt_state
   kill kopie

   dim as ubyte file1 = freefile
   open original for binary lock write as #file1
      
      dim as ubyte file2 = freefile
      open kopie for binary lock write as #file2
         
         select case encrypt_state
            case decrypt
               seek #file1, 33
            case else
               for b as byte = 0 to 16 step 16
                  vektor = set_initial_vector(vektor, key)
                  for a as byte = 0 to 15
                     block(a) = hash[a+b]
                  next a
                  put #file2, , encrypt_value(vektor, block())   
               next b
         end select
         
         do until loc(file1) + 16 >= lof(file1)      
            get #file1, , block()
            vektor = set_initial_vector(vektor, key)
            put #file2, , encrypt_value(vektor, block())   
         loop

         if lof(file1) - loc(file1) > 0 then
            redim block(lof(file1)-loc(file1) - 1)
            get #file1, , block()
            vektor = set_initial_vector(vektor, key)
            put #file2, , encrypt_value(vektor, block())            
         end if
         
      close #file2
   close #file1

end sub

'Ver- / Entschlüsselt die Kopie einer Quelldatei.
'Dabei werden nur Dateien ver- / entschlüsselt, die noch nicht ver- / entschlüsselt wurden, um Zeit zu sparen.
'Indikator ist hierbei Der Hash-Wert der (entschlüsselten) Originaldatei, der mit dem gespeicherten Hash-Wert der
'verschlüsselten Datei verglichen wird.
'original = Originale Datei (mit Pfad)
'backup = Ver- / Entschlüsselte Datei (mit Pfad)
'key = Passwort
'encrypt_state = decrypt (0)  -> Datei wird entschlüsselt
'             encrypt (-1) -> Datei wird verschlüsselt
sub crypt_copyfile_fast (original as string, kopie as string, key as string, encrypt_state as byte)

   'soviel wird pro Block kopiert
   dim as integer blocksize = 8192'= 8 KiloByte
   redim as ubyte block()
   dim as string keystream
   dim as string vektor
   dim as string hash
   
   select case encrypt_state
      case decrypt
         'Soll die Datei entschlüsselt werden, so sind die ersten 32 Byte der Datei der MD5 Hash der Originaldatei.
         'Diese 32 Byte werden nicht benötigt. Daher können die ersten 32 Byte des Keystreams Übersprungen werden.
         vektor = set_initial_vector(set_initial_vector(key, key), key)
         'Hash der (entschüsselten) Datei holen (falls vorhanden)
         hash = createFileHash(kopie)
         'Hash der entschlüsselten Datei (falls vorhanden) mit dem Hash der verschlüsselten Datei vergleichen.
         'Stimmen die Hash-Werte überein, so ist die verschlüsselte Datei bereits entschlüsselt. -> Hier wird dann die SUB beendet.
         if hash = readFileHash(original, key) then exit sub
      case else
         'Wenn die Datei verschlüsselt werden soll, wird der Anfang des Keystreams mit Hilfe des Passworts erstellt.
         vektor = key
         'Hash der (verschüsselten) Datei holen
         hash = createFileHash(original)
         'Hash der verschlüsselten Datei mit dem Hash der entschlüsselten Datei vergleichen.
         'Stimmen die Hash-Werte überein, so ist die entschlüsselte Datei bereits verschlüsselt. -> Hier wird dann die SUB beendet.
         if hash = readFileHash(kopie, key) then exit sub
   end select

   '~ print "Lösche ";encrypt_state
   'Zu ver- / entschüsselnde Datei löschen (sie ist ja veraltet)
   kill kopie

   'Beide Dateien öffnen, andere Schreibzugriffe verbieten
   dim as ubyte file1 = freefile
   open original for binary lock write as #file1
      
      dim as ubyte file2 = freefile
      open kopie for binary lock write as #file2
         
         
         select case encrypt_state
            case decrypt
               'Soll die Datei entswchlüsselt werden, so sind die ersten 32 Byte nutzlos (darin steht der HAsh-Wert der entschlüsselten Datei).
               'Daher werden diese 23 Byte übersprungen
               seek #file1, 33
            case else
               'Soll die Datei verschlüsselt werden, so wird zunächst der Hash verschlüsselt
               'Puffergröße (zum Schreiben in die Datei) auf 32 Byte setzen
               redim block(31)
               'Keystream von 32 Byte Länge erzeugen
               'Passwort wird AES-Verschlüsselt.
               '-> 16 Byte String wird in keystream gespeichert, 16 Byte String nochmal AES verschlüsselt
               '-> Neuer 16 Byte String wird in keystream angehängt.
               for a as byte = 0 to 1
                  vektor = set_initial_vector(vektor, key)
                  keystream += vektor
               next a
               'Puffer füllen (mit den ASC-Werten des Hashs)
               for a as byte = 0 to 31
                     block(a) = hash[a]
               next a
               'Block mit Keystream verschlüsseln und in die Zieldatei schreiben
               put #file2, , encrypt_value(keystream, block())   
               keystream = ""
         end select
         
         'Lese- / Schreibpuffergröße auf Blockgröße setzen
         redim block(blocksize - 1)
         'So lange der ungelesene Teil der Quelldatei größer als die Blockgröße ist...
         do until loc(file1) + blocksize >= lof(file1)   
            'Keystream-Puffer in der Größe der Blockgröße erstellen
            for a as integer = 1 to blocksize \ 16
               vektor = set_initial_vector(vektor, key)
               keystream += vektor
            next a
            'Inhalt aus der Quelldatei lesen, ver- / entschlüsseln (mit Keystream) und in die Zieldatei schreiben
            get #file1, , block()
            put #file2, , encrypt_value(keystream, block())
            'Keystream-Puffer leeren. Wird ein neuer Keystream-Puffer erstellt, bleibt der Strom allerdings erhalten.
            keystream = ""
         loop

         'Wenn der ungelesene Teil kleiner als die Blöckgröße ist...
         if lof(file1) - loc(file1) > 0 then
            'Keystream-Puffer in der Größe der "Rest-Datei" erstellen
            for a as integer = 1 to (lof(file1) - loc(file1)) \ 16 + 1
               vektor = set_initial_vector(vektor, key)
               keystream += vektor
            next a

            'Lese- / Schreib-Puffer neu dimensionieren (ebenfalls auf den "Rest der Datei")
            redim block(lof(file1)-loc(file1) - 1)

            'Inhalt aus der Quelldatei lesen, ver- / entschlüsseln (mit Keystream) und in die Zieldatei schreiben
            get #file1, , block()
            put #file2, , encrypt_value(keystream, block())   
                     
         end if
         
      close #file2
   close #file1

end sub

'~ print "TXT FAST"
'~ crypt_copyfile_fast ("testumgebung/original/readme/easy.txt", "testumgebung/backup/easy_copy_fast.txt","abcdefghijklmnop", encrypt)
'~ crypt_copyfile_fast ("testumgebung/backup/easy_copy_fast.txt", "testumgebung/backup/easy_decode_fast.txt","abcdefghijklmnop", decrypt)
'~ print "PIC FAST"
'~ crypt_copyfile_fast ("testumgebung/original/foto0299.jpg", "testumgebung/backup/foto0299_fast.jpg","abcdefghijklmnop", encrypt)
'~ crypt_copyfile_fast ("testumgebung/backup/foto0299_fast.jpg", "testumgebung/backup/foto0299_dec_fast.jpg","abcdefghijklmnop", decrypt)


'~ print "TXT SLOW"
'~ crypt_copyfile ("testumgebung/original/readme/easy.txt", "testumgebung/backup/easy_copy.txt","abcdefghijklmnop", encrypt)
'~ crypt_copyfile ("testumgebung/backup/easy_copy.txt", "testumgebung/backup/easy_decode.txt","abcdefghijklmnop", decrypt)
'~ print "PIC SLOW"
'~ crypt_copyfile ("testumgebung/original/foto0299.jpg", "testumgebung/backup/foto0299.jpg","abcdefghijklmnop", encrypt)
'~ crypt_copyfile ("testumgebung/backup/foto0299.jpg", "testumgebung/backup/foto0299_dec.jpg","abcdefghijklmnop", decrypt)


'~ end

rek_dir.bas(Hauptdatei)
Code:
#include once "rmdir_rek.bas"
#include once "rek_dir_list.bas"
#include once "dir.bi"
#include once "crypt.bas"

'Rekursives Ver- / Entschlüsseln eines Verzeichnisses (mit Unterordnern und -dateien),
'vorausgesetzt, diese haben jeweils eine Änderung erfahren. (Vergleich per MD5-Hash)
'Außerdem werden Ordner und Dateien, die nicht (mehr) im Quellverzeichnis vorhanden sind entfernt
'original_pfad = Quellpfad
'backup_pfad = Pfad in dem die Kopie der Ordnerstruktur erstellt werden soll
'key = Passwort mit dem die Dateien verschlüsselt werden
'encrypt_state = decrypt (0)  -> Ordner wird entschlüsselt
'             encrypt (-1) -> Ordner wird verschlüsselt
sub crypt_directories (original_pfad as string, backup_pfad as string, key as string, encrypt_state as byte)

   dim as liste ptr original_liste
   dim as liste ptr directory_liste
   dim as liste ptr remove_directory_liste

   dim as string filename
   dim as string new_pfad
   'Ordner und normale Dateien lesen
   dim as integer attrib = fbDirectory OR fbNormal, rattrib

   'falls nicht vorhanden, wird der Zielordner erstellt
   mkdir backup_pfad

   'Quellverzeichnis auslesen
   filename = dir(original_pfad+"*", attrib, rattrib)
   do
      '.. und . am Anfang eines jeden Verzeichnisses ignorieren
      if not(filename = ".." or filename = ".") then
         'Datei- /Ordnername des Quellverzeichnisses in einer Liste speichern
         add_to_list(original_liste, filename)
         'Wenn es sich bei dem gelesenen Objekt um einen Ordner handelt, den Ordnernamen in einer Ordnerliste speichern.
         'Ansonsten handelt es sich bei dem Objekt um eine Datei und und sie wird verschlüsselt ins Zielverzeichnis kopiert
         '(Aber nur wenn sie noch nicht vorhanden ist oder geändert wurde, siehe CRYPT_COPYFILE_FAST).
         if rattrib = fbDirectory then
            add_to_list(directory_liste, filename)
         else
            crypt_copyfile_fast(original_pfad+filename, backup_pfad+filename, key, encrypt_state)
         end if
         
      end if
      'Nächstes Objekt im Quellverzeichnis lesen, bis alles eingelesen wurde.
      filename = dir("", attrib, rattrib)
   loop until filename = ""

   'Zielverzeichnis auslesen
   filename = dir(backup_pfad+"*", attrib, rattrib)
   do
      '.. und . am Anfang eines jeden Verzeichnisses ignorieren
      'Außerdem wird der IF-Block nur betreten, wenn die gelesene Datei / der gelesene Ordner NICHT im Quellverzeichnis vorhanden ist)
      if not(filename = ".." or filename = ".") and list_contents(original_liste, filename) = 0 then
            'Handelt es sich bei dem gelesenen Objekt um einen Ordner, wird er ein einer _weiteren_ Ordnerliste gespeichert.
            'Handelt es sich um eine Datei wird sie gelöscht.
            if rattrib = fbdirectory then
               add_to_list(remove_directory_liste, filename)
            else
               kill backup_pfad+filename
            end if
      end if
      'Nächstes Objekt im Quellverzeichnis lesen, bis alles eingelesen wurde.      
      filename = dir("", attrib, rattrib)
   loop until filename = ""
   'Datei- / Ordnerliste des Originalverzeichnisses entfernen
   clear_list(original_liste)

   'Alle Ordner in der "_weiteren_" Ordnerliste rekursiv entfernen.
   '(Es sind ja nur Ornder in der Liste enthalten, die nicht im Quellverzeichnis vorhanden waren)
   do until remove_directory_liste = 0
      rmdir_rek(backup_pfad, get_from_list(remove_directory_liste)+"/")
   loop
   
   'Rekursiv alle Ordner ver- / entschlüsseln, die in der ersten Ordnerliste (des Quellverzeichnises) gespeichert wurden.
   '(Im besten Fall alle, die im Quellverzeichnis enthalten sind ;-) )
   do until directory_liste = 0
      'Neuer Pfad = Alter Pfad + Ordnername aus der Liste
      new_pfad = get_from_list(directory_liste)+"/"
      crypt_directories (original_pfad+new_pfad, backup_pfad+new_pfad, key, encrypt_state)
   loop

end sub

dim as string original_pfad
dim as string backup_pfad
dim as string decode_pfad
original_pfad = "testumgebung/original/"
backup_pfad = "testumgebung/backup/"
decode_pfad = "testumgebung/decode/"

crypt_directories(original_pfad,backup_pfad,"abcdefghijklmnop", encrypt)
crypt_directories(backup_pfad,decode_pfad,"abcdefghijklmnop", decrypt)
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
MOD
Fleißiger Referenzredakteur


Anmeldungsdatum: 10.09.2007
Beiträge: 1003

BeitragVerfasst am: 02.02.2012, 17:39    Titel: Antworten mit Zitat

Den MD5 Code hast du aus dem Portal. Er steht unter der WTFPL, Credits sind also nicht nötig, werden aber immer begrüßt. happy
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
28398



Anmeldungsdatum: 25.04.2008
Beiträge: 1917

BeitragVerfasst am: 02.02.2012, 22:32    Titel: Antworten mit Zitat

Nutz rsync/git/whatever und pack es in ein Truecryptcontainer.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Flo
aka kleiner_hacker


Anmeldungsdatum: 23.06.2006
Beiträge: 1210

BeitragVerfasst am: 03.02.2012, 03:06    Titel: Antworten mit Zitat

das ist aber langweilig, wenn mans selber machen will zwinkern

meine Empfehlung: wenn es dir primär um ein verlässliches, sicheres Backup geht, dann nutze rsync plus Verschlüsselungscontainer

wenn du inkrementell willst: rsync hat eine option, in einem Referenzverzeichnis zu gucken, ob $datei schon existiert und identisch ist. wenn nein -> ins neue Verzeichnis kopieren, ansonsten einen Hardlink (der keinen Speicherplatz verbraucht und wie eine normale Datei aussieht) setzen. Damit kannst du unter backups/$datum/ jeweils für sich genommen komplette Schnappschüsse erzeugen (zurückspielen geht mit einer einfachen Kopieroperation), die trotzdem platzsparend sind.


wenn dus allerdings primär des Lerneffekt willens machst, kann ich dir leider nicht helfen. Aber viel Erfolg noch happy
_________________
MFG
Flo

Satoru Iwata: Wer Spaß am Spielen hat, fragt nicht nach Grafik.

zum korrekten Verstaendnis meiner Beitraege ist die regelmaessige Wartung des Ironiedetektors unerlaesslich.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Type



Anmeldungsdatum: 24.02.2006
Beiträge: 187
Wohnort: Dresden

BeitragVerfasst am: 03.02.2012, 11:57    Titel: Antworten mit Zitat

Danke für eure Antworten. lächeln

Es geht mir darum, die Daten mit einem eigenen Programm zu sichern.
Aber die Anmerkung mit dem Referenzverzeichnis ist eine gute Idee. Vielleicht kann man daraus ja was machen.

Ich denke mal die Knackpunkte an diesem Programm sind die Erstellung des Hash's und die Kopierfunktion.
Ich meine bei QuickBasic gab es mal eine Möglichkeit Dateien noch schneller zu kopieren (Stand irgendwo in der QBMonFaq, aber ich finde den Eintrag nicht mehr...).
Eine schnellere Hash Funktion kenn ich auch nicht (bzw. eine andere).

Mich würde erstmal auch interessieren ob es eine schnellere Vorgehensweise geben könnte.

- Auf die Gefahr hin, dass ich jetzt gleich dafür geköpft werde: Denkt ihr nicht das es mit FreeBasic möglich ist ein schnelleres Backup-Programm zu erstellen, als rsync+container?

MfG Type
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
MisterD



Anmeldungsdatum: 10.09.2004
Beiträge: 3071
Wohnort: bei Darmstadt

BeitragVerfasst am: 03.02.2012, 13:07    Titel: Antworten mit Zitat

auf jeden fall nicht in einer woche
_________________
"It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Sebastian
Administrator


Anmeldungsdatum: 10.09.2004
Beiträge: 5969
Wohnort: Deutschland

BeitragVerfasst am: 03.02.2012, 13:41    Titel: Antworten mit Zitat

Hallo!
Type hat Folgendes geschrieben:
Ich meine bei QuickBasic gab es mal eine Möglichkeit Dateien noch schneller zu kopieren (Stand irgendwo in der QBMonFaq, aber ich finde den Eintrag nicht mehr...).

Im Allgemeinen kann man davon ausgehen, dass ein Algorithmus (der gleichartig in FreeBASIC und QuickBASIC implementiert wird), auf einem modernen PC (mit Windows >= NT oder Linux) viel viel schneller abläuft, wenn er als FreeBASIC-Binary ausgeführt wird. Der 16-Bit-Maschinencode, den QB erzeugt, wird ja auf allen aktuellen Plattformen (wenn überhaupt!) nur noch als "Kompatibilitäts-Notlösung" in einer Art Emulator ausgeführt - sei es durch ntvdm unter Windows oder DOSBox unter Windows/Linux. Andererseits kann QB-Code ja sowieso von Haus aus gar nichts von dem nutzen, was die CPU-Entwicklung der letzten ~20 Jahre so hervorgebracht hat.

Das schnelle Kopierverfahren in QB war, die Datei nicht Integer- oder Double-weise zu lesen und zu schreiben (= einstellige Puffergröße in Bytes), sondern blockweise mit einem Puffer von mehreren Kilobytes. Dazu steht auch etwas in der Monster-FAQ. Ich könnte mir vorstellen, dass du das meinst.
Das Verfahren wendest du ja aber in deinem Code bereits an. Auch wenn mir der Puffer mit 8 kB etwas klein erscheint. Du könntest hier mal mit verschiedenen Puffergrößen experimentieren. Vom RAM her kannst du ja problemlos in den Megabyte-Bereich gehen und normale Dateien wie Quelltexte, Word-Dokumente etc. "in einem Rutsch" einlesen. In QB musste man damals halt im Kilobyte-Bereich bleiben, weil dort Strings, über die man die langen Puffer realisiert hat, eben nicht länger sein konnten.

Bei der Verschlüsselung könnte man vielleicht durch Assembler-Optimierung, idealerweise mit kryptographischen Spezial-Instruktionen moderner CPUs, mehr Performance herausholen. Siehe zum Beispiel:
- http://en.wikipedia.org/wiki/AES_instruction_set
- http://software.intel.com/en-us/articles/intel-advanced-encryption-standard-instructions-aes-ni/
- http://www.intel.com/content/dam/doc/white-paper/advanced-encryption-standard-new-instructions-set-paper.pdf

Viele Grüße!
Sebastian
_________________

Die gefährlichsten Familienclans | Opas Leistung muss sich wieder lohnen - für 6 bis 10 Generationen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
28398



Anmeldungsdatum: 25.04.2008
Beiträge: 1917

BeitragVerfasst am: 04.02.2012, 01:23    Titel: Antworten mit Zitat

Flo hat Folgendes geschrieben:
das ist aber langweilig, wenn mans selber machen will zwinkern

Backupprogramme sind nichts zum Selbermachen. Das gibt am Ende nur Ärger°.

° Gut, man kann auch mit Fehlbedienung vorhandener Programme viel Mist bauen. Aber gerade wenns um Verschlüsselung geht, sollte man sowas nicht selbst machen. IdR. werden die Algorithmen nicht verstanden und schnell a) falsch benutzt (ECB z.B.) oder b) falsch implementiert oder c) im Prinzip richtig implementiert, aber viel zu langsam und/oder inkompatibel zu validierenden Implementierungen.

@Sebastian: AES-NI haben bisher allerdings die wenigsten CPUs; Parallelisierung ist auch viel perfomanceträchtiger als die Instruktionen zu nutzen. Aber da machen noch sehr viel mehr Leute noch sehr viel schneller noch sehr viel mehr falsch. Algorithmen parallelisieren => diffizil, Kryptographie => äußerst diffizil; krypotgraphische Algorithmen parallelisieren ... grinsen

-- edit --
Ich nehm das mal zurück, kann wohl kein FB mehr lesen. Zuviel C++/Python happy
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Type



Anmeldungsdatum: 24.02.2006
Beiträge: 187
Wohnort: Dresden

BeitragVerfasst am: 04.02.2012, 11:38    Titel: Antworten mit Zitat

28398 hat Folgendes geschrieben:
Backupprogramme sind nichts zum Selbermachen. Das gibt am Ende nur Ärger.

Das verstehe ich nicht ganz. Irgendjemand muss die ja programmieren und diese Leute stehen vor den gleichen Problemen. zwinkern
Und wenn man gewissenhaft arbeitet und eine lange Testphase hat sollte das schon funktionieren (zumal ich das ja für mich mache, da ist es außer bei mir selbst ja egal, wenn was "kaputtgeht").

An Parallelisierung trau ich mich nicht so recht ran, damit habe ich noch nie gearbeitet (wäre mal was neues), aber momentan hab ich wenig Zeit (Prüfungen und so...) daher werde ich mich wohl später erst damit befassen.

Die Assembler-Methode klingt nicht schlecht, damit ließe sich sicher Zeit sparen, dann kann ich vermutlich 1/3 des Codes in ASM auslagern. zwinkern

Danke auf jeden Fall für eure Anregungen!

MfG Type
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
28398



Anmeldungsdatum: 25.04.2008
Beiträge: 1917

BeitragVerfasst am: 04.02.2012, 13:05    Titel: Antworten mit Zitat

Type hat Folgendes geschrieben:
Die Assembler-Methode klingt nicht schlecht, damit ließe sich sicher Zeit sparen, dann kann ich vermutlich 1/3 des Codes in ASM auslagern. zwinkern

Zitat:
Don't optimize (yet)

Schnapp dir erstmal nen Profiler und schau wo es überhaupt hängt, bevor du anfängst unportablen und unwartbaren Assemblercode zu schreiben.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Type



Anmeldungsdatum: 24.02.2006
Beiträge: 187
Wohnort: Dresden

BeitragVerfasst am: 04.02.2012, 18:33    Titel: Antworten mit Zitat

Gute, Idee, hab ich gar nicht dran gedacht.

Ich habe mal gprof über das Programm laufen lassen.
Dabei ist herausgekommen, dass die AES-Verschlüsselung der Engpass ist.
    (1) Insbesondere RIJNDAEL_MIXCOLLUMS und RIJNDAEL_ADDKEY - also die AES-Verschlüsselung - benöti fast 20% der Laufzeit.
    (2) Interessanterweise benötigt fb_StrConcat (ich nehme mal an, dass ist die FB-Interne Funktion, um Strings aneinanderzuhängen) weitere 24% der Programmlaufzeit.

zu (1) Ich habe mir meinen Code nochmal angeschaut und gehe davon aus, dass es an diesem Konstrukt liegt:
Code:
do until loc(file1) + blocksize >= lof(file1)
   for a as integer = 1 to blocksize \ 16
      vektor = set_initial_vector(vektor, key)
      keystream += vektor
   next a
   [...]
   keystream = ""
loop
Der Teil erzeugt in 128 Bit Schritten den Keystream mit dem die Datei verschlüsselt wird. Dabei wird der alte vektor-String mit dem Passwort mit Hilfe von AES verschlüsselt und an den Keystream angehängt und zwar solange, bis der Keystream die Größe von blocksize erreicht hat.

Danach wird keystream geleert (aber vektor nicht zurückgesetzt) und der nächste Block wird gelesen. Dadurch ergibt sich insgesamt ein Keystream, der beliebig lang werden kann. Das mache ich, damit Dateien, die größer als 2GB sind keinen Überlauf im String erzeugen.

Das dies ein Nadelöhr ist hab ich mir schon gedacht, nur wie ich es wegkriegen könnte weiß ich nicht genau. Hat da evt. jemand eine Idee?


zu (2) Wäre es schneller wenn man sich eine eigene Funktion zum vergrößern eines Strings basteln könnte? Ich stelle mir da etwas mit Listen und Pointern vor:
Idee hat Folgendes geschrieben:
[BUCHSTABE 1]->[BUCHSTABE 2]->...->[BUCHSTABE n]
Code:
type own_string
   as byte char
   as own_string ptr weiter
end type


Hoffentlich habt ihr noch Ideen, ich weiß nicht so recht wie ich weitermachen soll zwinkern

MfG Type
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
28398



Anmeldungsdatum: 25.04.2008
Beiträge: 1917

BeitragVerfasst am: 04.02.2012, 18:46    Titel: Antworten mit Zitat

Für BLOBS keine Strings, sondern flachen Speicher (~char*) nutzen
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
MisterD



Anmeldungsdatum: 10.09.2004
Beiträge: 3071
Wohnort: bei Darmstadt

BeitragVerfasst am: 04.02.2012, 19:01    Titel: Antworten mit Zitat

28398 hat Folgendes geschrieben:
Für BLOBS keine Strings, sondern flachen Speicher (~char*) nutzen


ich bin nich mehr so bewandert mit FB datentypen, aber Blob sind eigentilch bytes, nicht chars. Damit du chars bekommst brauchst du eigentlich erst ein charset, was eigentlich unnötig ist wenn du nur platt dateien liest und 1:1 wieder rausschreibst.
_________________
"It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 04.02.2012, 19:23    Titel: Antworten mit Zitat

Type hat Folgendes geschrieben:
(2) Interessanterweise benötigt fb_StrConcat (ich nehme mal an, dass ist die FB-Interne Funktion, um Strings aneinanderzuhängen) weitere 24% der Programmlaufzeit.

"Interessanterweise"? Stringoperationen sind langsam, da kann man nichts gegen tun. Es wäre sinnvoller, auf einem Byte-Array zu arbeiten, das man bei Bedarf in der länge einfach verdoppelt. Somit muss das Array nur in den Fällen, in denen es bereits 2^n existierende Einträge hat, kopiert werden, anstatt in jedem Durchlauf.
_________________
» Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
28398



Anmeldungsdatum: 25.04.2008
Beiträge: 1917

BeitragVerfasst am: 04.02.2012, 19:28    Titel: Antworten mit Zitat

MisterD hat Folgendes geschrieben:
28398 hat Folgendes geschrieben:
Für BLOBS keine Strings, sondern flachen Speicher (~char*) nutzen


ich bin nich mehr so bewandert mit FB datentypen, aber Blob sind eigentilch bytes, nicht chars. Damit du chars bekommst brauchst du eigentlich erst ein charset, was eigentlich unnötig ist wenn du nur platt dateien liest und 1:1 wieder rausschreibst.
chars sind bytes...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
MisterD



Anmeldungsdatum: 10.09.2004
Beiträge: 3071
Wohnort: bei Darmstadt

BeitragVerfasst am: 04.02.2012, 20:24    Titel: Antworten mit Zitat

28398 hat Folgendes geschrieben:
MisterD hat Folgendes geschrieben:
28398 hat Folgendes geschrieben:
Für BLOBS keine Strings, sondern flachen Speicher (~char*) nutzen


ich bin nich mehr so bewandert mit FB datentypen, aber Blob sind eigentilch bytes, nicht chars. Damit du chars bekommst brauchst du eigentlich erst ein charset, was eigentlich unnötig ist wenn du nur platt dateien liest und 1:1 wieder rausschreibst.
chars sind bytes...


Nein eben nicht lächeln ein ä zB ist ein eindeutiger char, aber kein eindeutiges byte. Welches byte - oder sogar welche kombination aus bytes (zB bei UTF8 ) - zu benutzen ist um den char irgendwo hinzuschreiben hängt vom benutzten charset ab. Wenn du ne binäre datei einliest liest du erstmal nur bytes. Erst wenn dir jemand sagt "die datei hat charset X" kannst du die bytes wirklich in korrekte chars übersetzen. Vorher kannst du natürlich auch die bytes einfach zu chars casten, aber da kommt idR mist raus, insbesondere wenn du nen leser benutzt, der das System-Standardcharset verwendet. Dann sind chars auf dem windows-system nämlich plötzlich andere chars auf dem osx-system, obwohl du beide male einfach nur "char" geschrieben hast. Rohe Bytes aber sind überall gleich.

Wie gesagt, bei FB weiß ich grad nich obs da byte und char getrennt überhaupt gibt, viel zu lang nicht mehr benutzt. Aber wenns beides gibt haben die unterschiedliche bedeutungen, auch wenns letztendlich beides einfach 8 bit sind.
_________________
"It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
28398



Anmeldungsdatum: 25.04.2008
Beiträge: 1917

BeitragVerfasst am: 04.02.2012, 22:03    Titel: Antworten mit Zitat

Hast du schonmal jemanden in C den Typ "byte" oder uint8_t nutzen sehen?
-
In FB gibts nur byte und ubyte...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 04.02.2012, 23:19    Titel: Antworten mit Zitat

28398 hat Folgendes geschrieben:
Hast du schonmal jemanden in C den Typ "byte" oder uint8_t nutzen sehen?

du etwa nicht?
_________________
» Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Flo
aka kleiner_hacker


Anmeldungsdatum: 23.06.2006
Beiträge: 1210

BeitragVerfasst am: 04.02.2012, 23:32    Titel: Antworten mit Zitat

28398 hat Folgendes geschrieben:
Hast du schonmal jemanden in C den Typ "byte" oder uint8_t nutzen sehen?
-
In FB gibts nur byte und ubyte...



ooooh ja (ich zum beispiel). allein schon, weil du dir nicht sicher sein kannst, ob ein char wirklich ein 8-bit-wert ist.

in java sind das komplett verschiedene typen.

und, so sehr ich C auch mag, C sollte man nicht als vorbild sehen. in C sind sehr viele Fehler gemacht worden, die neuere Sprachen (wie z.B. Java) behoben haben (und naturgemäß durch neue Fehler ersetzt haben zwinkern )
_________________
MFG
Flo

Satoru Iwata: Wer Spaß am Spielen hat, fragt nicht nach Grafik.

zum korrekten Verstaendnis meiner Beitraege ist die regelmaessige Wartung des Ironiedetektors unerlaesslich.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Type



Anmeldungsdatum: 24.02.2006
Beiträge: 187
Wohnort: Dresden

BeitragVerfasst am: 05.02.2012, 13:09    Titel: Antworten mit Zitat

So, ich habe jetzt versucht die Stringoperationen auf ein Minimum zu reduzieren. Die AES-Verschlüsselung, sowie die Keystream-Operationen und das Schreiben in die Datei läuft nun über UByte-Arrays.
Das Programm ist auch merklich schneller! lächeln

Außerdem habe ich die Puffergröße auf 8MB erhöht.

Dafür schonmal danke!

Wie sieht es mit (1) aus? - Das Problem ist, dass die Key-Generierung nur bei großen Dateien zu lange dauert...
Ich glaube fast daran lässt sich nicht rütteln, außer man optimiert die AES-Verschlüsselung noch weiter...

Hier die beiden aktualisierten Dateien (AES.bas -> aes_fast.bas; crypt.bas -> crypt_aes_fast.bas)
aes_fast.bas
Code:

' AES Encryption Implementation by: Chris Brown(2007) aka Zamaster
'
' -Takes plain text and converts it to encrypted ASCII
' -Keys must be 128 bits in size, or 32 hex places/16 char places
' -Set ed in RIJNDAEL_Encrypt to 2 for decryption, 1 for encryption
'
Sub RIJNDAEL_ConvertEXPtoKey(index As Integer, ekey() As Ubyte, tkey() As Ubyte)
    Dim As Ubyte x,y,b
    b = (index-1)*4
    For y = 1 To 4
        For x = 1 To 4
            tkey(x,y) = ekey(b+x,y)
        Next x
    Next y
End Sub


Function RIJNDAEL_InverseS(v As Ubyte) As Ubyte
    Static As Ubyte RSBOX(0 To 255) = {_
    &H52, &H09, &H6A, &HD5, &H30, &H36, &HA5, &H38, &HBF, &H40, &HA3, &H9E, &H81, &HF3, &HD7, &HFB, _
    &H7C, &HE3, &H39, &H82, &H9B, &H2F, &HFF, &H87, &H34, &H8E, &H43, &H44, &HC4, &HDE, &HE9, &HCB, _
    &H54, &H7B, &H94, &H32, &HA6, &HC2, &H23, &H3D, &HEE, &H4C, &H95, &H0B, &H42, &HFA, &HC3, &H4E, _
    &H08, &H2E, &HA1, &H66, &H28, &HD9, &H24, &HB2, &H76, &H5B, &HA2, &H49, &H6D, &H8B, &HD1, &H25, _   
    &H72, &HF8, &HF6, &H64, &H86, &H68, &H98, &H16, &HD4, &HA4, &H5C, &HCC, &H5D, &H65, &HB6, &H92, _
    &H6C, &H70, &H48, &H50, &HFD, &HED, &HB9, &HDA, &H5E, &H15, &H46, &H57, &HA7, &H8D, &H9D, &H84, _
    &H90, &HD8, &HAB, &H00, &H8C, &HBC, &HD3, &H0A, &HF7, &HE4, &H58, &H05, &HB8, &HB3, &H45, &H06, _
    &HD0, &H2C, &H1E, &H8F, &HCA, &H3F, &H0F, &H02, &HC1, &HAF, &HBD, &H03, &H01, &H13, &H8A, &H6B, _
    &H3A, &H91, &H11, &H41, &H4F, &H67, &HDC, &HEA, &H97, &HF2, &HCF, &HCE, &HF0, &HB4, &HE6, &H73, _
    &H96, &HAC, &H74, &H22, &HE7, &HAD, &H35, &H85, &HE2, &HF9, &H37, &HE8, &H1C, &H75, &HDF, &H6E, _   
    &H47, &HF1, &H1A, &H71, &H1D, &H29, &HC5, &H89, &H6F, &HB7, &H62, &H0E, &HAA, &H18, &HBE, &H1B, _   
    &HFC, &H56, &H3E, &H4B, &HC6, &HD2, &H79, &H20, &H9A, &HDB, &HC0, &HFE, &H78, &HCD, &H5A, &HF4, _
    &H1F, &HDD, &HA8, &H33, &H88, &H07, &HC7, &H31, &HB1, &H12, &H10, &H59, &H27, &H80, &HEC, &H5F, _
    &H60, &H51, &H7F, &HA9, &H19, &HB5, &H4A, &H0D, &H2D, &HE5, &H7A, &H9F, &H93, &HC9, &H9C, &HEF, _
    &HA0, &HE0, &H3B, &H4D, &HAE, &H2A, &HF5, &HB0, &HC8, &HEB, &HBB, &H3C, &H83, &H53, &H99, &H61, _
    &H17, &H2B, &H04, &H7E, &HBA, &H77, &HD6, &H26, &HE1, &H69, &H14, &H63, &H55, &H21, &H0C, &H7D}
    Dim As Integer x
    x = RSBOX((v And &HF0) + (v And &HF))
    Return x
End Function


Function RIJNDAEL_S(v As Ubyte) As Ubyte
    Static As Ubyte RSBOX(0 To 255) = {_
    &H63, &H7C, &H77, &H7B, &HF2, &H6B, &H6F, &HC5, &H30, &H01, &H67, &H2B, &HFE, &HD7, &HAB, &H76, _
    &HCA, &H82, &HC9, &H7D, &HFA, &H59, &H47, &HF0, &HAD, &HD4, &HA2, &HAF, &H9C, &HA4, &H72, &HC0, _
    &HB7, &HFD, &H93, &H26, &H36, &H3F, &HF7, &HCC, &H34, &HA5, &HE5, &HF1, &H71, &HD8, &H31, &H15, _
    &H04, &HC7, &H23, &HC3, &H18, &H96, &H05, &H9A, &H07, &H12, &H80, &HE2, &HEB, &H27, &HB2, &H75, _
    &H09, &H83, &H2C, &H1A, &H1B, &H6E, &H5A, &HA0, &H52, &H3B, &HD6, &HB3, &H29, &HE3, &H2F, &H84, _
    &H53, &HD1, &H00, &HED, &H20, &HFC, &HB1, &H5B, &H6A, &HCB, &HBE, &H39, &H4A, &H4C, &H58, &HCF, _
    &HD0, &HEF, &HAA, &HFB, &H43, &H4D, &H33, &H85, &H45, &HF9, &H02, &H7F, &H50, &H3C, &H9F, &HA8, _
    &H51, &HA3, &H40, &H8F, &H92, &H9D, &H38, &HF5, &HBC, &HB6, &HDA, &H21, &H10, &HFF, &HF3, &HD2, _
    &HCD, &H0C, &H13, &HEC, &H5F, &H97, &H44, &H17, &HC4, &HA7, &H7E, &H3D, &H64, &H5D, &H19, &H73, _
    &H60, &H81, &H4F, &HDC, &H22, &H2A, &H90, &H88, &H46, &HEE, &HB8, &H14, &HDE, &H5E, &H0B, &HDB, _   
    &HE0, &H32, &H3A, &H0A, &H49, &H06, &H24, &H5C, &HC2, &HD3, &HAC, &H62, &H91, &H95, &HE4, &H79, _
    &HE7, &HC8, &H37, &H6D, &H8D, &HD5, &H4E, &HA9, &H6C, &H56, &HF4, &HEA, &H65, &H7A, &HAE, &H08, _
    &HBA, &H78, &H25, &H2E, &H1C, &HA6, &HB4, &HC6, &HE8, &HDD, &H74, &H1F, &H4B, &HBD, &H8B, &H8A, _
    &H70, &H3E, &HB5, &H66, &H48, &H03, &HF6, &H0E, &H61, &H35, &H57, &HB9, &H86, &HC1, &H1D, &H9E, _
    &HE1, &HF8, &H98, &H11, &H69, &HD9, &H8E, &H94, &H9B, &H1E, &H87, &HE9, &HCE, &H55, &H28, &HDF, _
    &H8C, &HA1, &H89, &H0D, &HBF, &HE6, &H42, &H68, &H41, &H99, &H2D, &H0F, &HB0, &H54, &HBB, &H16}
    Dim As Integer x
    x = RSBOX((v And &HF0) + (v And &HF))
    Return x
End Function


Sub RIJNDAEL_SubBytes(T() As Ubyte)   
    Dim As Ubyte x,y, temp
    For y = 1 To 4
        For x = 1 To 4
            temp = T(x,y)
            T(x,y) = RIJNDAEL_S(temp)
        Next x
    Next y
End Sub

Sub RIJNDAEL_InverseSubBytes(T() As Ubyte)   
    Dim As Ubyte x,y, temp
    For y = 1 To 4
        For x = 1 To 4
            temp = T(x,y)
            T(x,y) = RIJNDAEL_InverseS(temp)
        Next x
    Next y
End Sub


Sub RIJNDAEL_ShiftRows(T() As Ubyte)
    Swap T(1,2), T(4,2)
    Swap T(2,2), T(1,2)
    Swap T(3,2), T(2,2)
    Swap T(1,3), T(3,3)
    Swap T(2,3), T(4,3)
    Swap T(1,4), T(2,4)
    Swap T(3,4), T(4,4)
    Swap T(1,4), T(3,4)
End Sub

Sub RIJNDAEL_InverseShiftRows(T() As Ubyte)
    Swap T(1,2), T(2,2)
    Swap T(1,2), T(4,2)
    Swap T(3,2), T(4,2)
    Swap T(1,3), T(3,3)
    Swap T(2,3), T(4,3)
    Swap T(1,4), T(2,4)
    Swap T(2,4), T(3,4)
    Swap T(3,4), T(4,4)
End Sub

Sub RIJNDAEL_MixCollums(T() As Ubyte)
    Dim As Ubyte a(1 To 4), b(1 To 4), i, q, hb
    For q = 1 To 4
        For i = 1 To 4
            a(i) = T(q,i)
            hb = T(q,i) And &H80
            b(i) = a(i) Shl 1
            If hb = &h80 Then b(i) = b(i) Xor &H1B
        Next i
        T(q,1) = b(1) Xor a(4) Xor a(3) Xor b(2) Xor a(2)
        T(q,2) = b(2) Xor a(1) Xor a(4) Xor b(3) Xor a(3)
        T(q,3) = b(3) Xor a(2) Xor a(1) Xor b(4) Xor a(4)
        T(q,4) = b(4) Xor a(3) Xor a(2) Xor b(1) Xor a(1)
    Next q
End Sub

Sub RIJNDAEL_AddKey(T() As Ubyte, K() As Ubyte)
    Dim As Ubyte x,y
    For y = 1 To 4
        For x = 1 To 4
            T(x,y) = T(x,y) Xor K(x,y)
        Next x
    Next y
End Sub


Sub RIJNDAEL_ExpandKey(K1() As Ubyte, K2() As Ubyte)
    Static As Ubyte RCON(1 To 10) = {&H01, &H02, &H04, &H08, &H10, &H20, &H40, &H80, &H1B, &H36}
    Dim As Integer i, q, a, opt4, opt4m1, opt4m4, o4, om1, om4
    K2(1,1) = K1(1,1) Xor RIJNDAEL_S(K1(4,2)) Xor RCON(1)
    K2(1,2) = K1(1,2) Xor RIJNDAEL_S(K1(4,3))
    K2(1,3) = K1(1,3) Xor RIJNDAEL_S(K1(4,4))
    K2(1,4) = K1(1,4) Xor RIJNDAEL_S(K1(4,1))
    For i = 2 To 4
        For q = 1 To 4
            K2(i,q) = K2(i-1,q) Xor K1(i,q)
        Next q
    Next i
   
    For i = 2 To 10
        opt4 = ((i-1) Shl 2) + 1
        opt4m1 = opt4 - 1
        opt4m4 = opt4 - 4
        K2(opt4,1) = K2(opt4m4,1) Xor RIJNDAEL_S(K2(opt4m1,2)) Xor RCON(i)
        K2(opt4,2) = K2(opt4m4,2) Xor RIJNDAEL_S(K2(opt4m1,3))
        K2(opt4,3) = K2(opt4m4,3) Xor RIJNDAEL_S(K2(opt4m1,4))
        K2(opt4,4) = K2(opt4m4,4) Xor RIJNDAEL_S(K2(opt4m1,1))
        For q = 2 To 4
            o4 = opt4m1 + q
            om1 = o4-1
            om4 = o4-4
            For a = 1 To 4
                K2(o4,a) = K2(om1,a) Xor K2(om4,a)
            Next a
        Next q
    Next i
End Sub


Sub RIJNDAEL_FillTable(text() as ubyte, T() As Ubyte, dirc As Integer)

   select case dirc
      case 1
         for y as ubyte = 1 to 4
            for x as ubyte = 1 to 4
               T(x,y) = text((((y-1) Shl 2) + x-1))
            next x
         next y
      case else
         For y as ubyte = 1 To 4
            For x as ubyte = 1 To 4
               T(y,x) = text((((y-1) Shl 2) + x-1))
            Next x
         Next y
   end select      

end sub


Sub RIJNDAEL_Rotate(K() As Ubyte)
    Swap K(1,2), K(2,1)
    Swap K(1,3), K(3,1)
    Swap K(1,4), K(4,1)
    Swap K(2,4), K(4,2)
    Swap K(3,4), K(4,3)
    Swap K(2,3), K(3,2)
End Sub

Sub RIJNDAEL_BlockEncrypt(T() As Ubyte, K1() As Ubyte, K2() As Ubyte)
    Dim As Integer i
    Dim As Ubyte TempKey(1 To 4, 1 To 4)
    RIJNDAEL_AddKey T(), K1()
    RIJNDAEL_Rotate T()
    For i = 1 To 9
        RIJNDAEL_SubBytes T()
        RIJNDAEL_ShiftRows T()
        RIJNDAEL_MixCollums T()
        RIJNDAEL_ConvertEXPtoKey i, K2(), TempKey()
        RIJNDAEL_AddKey T(), TempKey()
    Next i
    RIJNDAEL_SubBytes T()
    RIJNDAEL_ShiftRows T()
    RIJNDAEL_ConvertEXPtoKey 10, K2(), TempKey()
    RIJNDAEL_AddKey T(), TempKey()
End Sub

sub RIJNDAEL_Encrypt(ptext() As ubyte, Key() As ubyte)

    Dim As String ctext
   
    Dim As Ubyte State(1 To 4, 1 To 4)
    dim as ubyte KeyT(1 To 4, 1 To 4)
    dim as ubyte EXPKey(1 To 40, 1 To 4)

    RIJNDAEL_FillTable Key(), KeyT(), 2
    RIJNDAEL_ExpandKey KeyT(), EXPKey()
    RIJNDAEL_FillTable ptext(), State(), 1
    RIJNDAEL_BlockEncrypt State(), KeyT(), EXPKey()
           
    For y as byte = 0 To 3
        For x as byte = 0 To 3
            ptext(x+(4*y)) = State(x+1,y+1)
        Next x
    Next y
   
End sub
 
 '~ dim as string key = "abcdefghijklmnop"
 '~ dim as string wort = "1234567890KLMNOP"
 '~ dim as ubyte bwort(15), bkey(15)
 '~ for a as integer = 0 to 15
   '~ bwort(a) = wort[a]
   '~ locate 1, a+1 : print chr(bwort(a))
   '~ bkey(a) = key[a]
   '~ locate 2, a+1:print chr(bkey(a))
'~ next a

'~ RIJNDAEL_Encrypt(bwort(),bkey())

 '~ for a as integer = 0 to 15
   '~ locate 1, a+1 : print chr(bwort(a))
   '~ locate 2, a+1:print chr(bkey(a))
'~ next a

crypt_aes_fast.bas
Code:
#include once "aes_fast.bas"
'~ #include once "aes_fast/aes_fast.bas"
#Include once "../MD5Checksum.bas"

#define decrypt 0
#define encrypt not(decrypt)   '-1

'Ein ByteArray wird Byteweise im einem Eingabestring geXORt.
'Dabei kann der Eingabestring größer sein, als das Array
'iv = Eingabestring
'value() = ByteArray
sub encrypt_value (iv() as ubyte, value() as ubyte)
   
   'ASC-Code eines einzelnen String-Zeichens wird mit Byte aus dem Array XOR genommen
   for a as integer = 0 to ubound(value)
      value(a) = value(a) xor iv(a)
   next a
   
end sub

'Holt den MD5-Hash aus einer verschlüsselten Datei
'datei = Dateiname
'key = Passwort, mit dem die Datei verschlüsselt wurde
function readFilehash(datei as string, key() as ubyte) as string

   dim as ubyte file = freefile
   dim as ubyte head(31)
   dim as string hash
   dim as ubyte keystream(31)
   dim as ubyte vektor(15)
   for a as byte = 0 to 15
      vektor(a) = key(a)
   next a
   
   'Die ersten 32 Byte der Datei werden in hash gespeichert
   'Ist die Datei zu klein, ist sie in jedem Fall ungültig. => Rückgabe ist leer
   open datei for binary lock write as #file
      if lof(file) < 32 then return ""      
      get #file, ,head()
   close #file
   
   'Keystream von 32 Byte Länge erzeugen
   'Passwort wird AES-Verschlüsselt.
   '-> 16 Byte String wird in keystream gespeichert, 16 Byte String nochmal AES verschlüsselt
   '-> Neuer 16 Byte String wird in keystream angehängt.
   for a as byte= 0 to 1
      RIJNDAEL_Encrypt vektor(), key()
      for b as byte = 0 to 15
         keystream(b+(a*16)) = vektor(b)
      next b
   next a
   'hash dekodieren
   encrypt_value(keystream(), head())
   
   for a as byte = 0 to 31
      hash += chr(head(a))
   next a
   
   return hash

end function

'Ver- / Entschlüsselt die Kopie einer Quelldatei.
'Dabei werden nur Dateien ver- / entschlüsselt, die noch nicht ver- / entschlüsselt wurden, um Zeit zu sparen.
'Indikator ist hierbei Der Hash-Wert der (entschlüsselten) Originaldatei, der mit dem gespeicherten Hash-Wert der
'verschlüsselten Datei verglichen wird.
'original = Originale Datei (mit Pfad)
'backup = Ver- / Entschlüsselte Datei (mit Pfad)
'key = Passwort
'encrypt_state = decrypt (0)  -> Datei wird entschlüsselt
'             encrypt (-1) -> Datei wird verschlüsselt
sub crypt_copyfile_fast (original as string, kopie as string, key as string, encrypt_state as byte)

   'soviel wird pro Block kopiert
   '~ dim as integer blocksize = 8192'= 8 KiloByte
   dim as integer blocksize = 8388608'= 8 MegaByte
   dim as integer restgroesse
   redim as ubyte block()
   redim as ubyte keystream()
   
   dim as ubyte byte_key(15)
   dim as ubyte byte_key_for_hash(15)
   dim as ubyte vektor(15)
         
   for a as byte = 0 to 15
      byte_key(a) = key[a]
      byte_key_for_hash(a) = key[a]
      vektor(a) = key[a]
   next a

   '~ dim as string keystream
   '~ dim as string vektor
   dim as string hash
   
   select case encrypt_state
      case decrypt
print "Entschlüssele: ";original;" [";time;"]"
         'Hash der (entschüsselten) Datei holen (falls vorhanden)
         hash = createFileHash(kopie)
         'Hash der entschlüsselten Datei (falls vorhanden) mit dem Hash der verschlüsselten Datei vergleichen.
         'Stimmen die Hash-Werte überein, so ist die verschlüsselte Datei bereits entschlüsselt. -> Hier wird dann die SUB beendet.
         if hash = readFileHash(original, byte_key_for_hash()) then print "nicht nötig": exit sub
      case else
print "Verschlüssele: ";original;" [";time;"]"
         'Hash der (verschüsselten) Datei holen
         hash = createFileHash(original)
         'Hash der verschlüsselten Datei mit dem Hash der entschlüsselten Datei vergleichen.
         'Stimmen die Hash-Werte überein, so ist die entschlüsselte Datei bereits verschlüsselt. -> Hier wird dann die SUB beendet.
         if hash = readFileHash(kopie, byte_key_for_hash()) then print "nicht nötig": exit sub
   end select

   '~ print "Lösche ";encrypt_state
   'Zu ver- / entschüsselnde Datei löschen (sie ist ja veraltet)
   kill kopie

   'Beide Dateien öffnen, andere Schreibzugriffe verbieten
   dim as ubyte file1 = freefile
   open original for binary lock write as #file1
      
      dim as ubyte file2 = freefile
      open kopie for binary lock write as #file2
         
      
         select case encrypt_state
            case decrypt
               'Soll die Datei entswchlüsselt werden, so sind die ersten 32 Byte nutzlos (darin steht der HAsh-Wert der entschlüsselten Datei).
               'Daher werden diese 32 Byte übersprungen
               RIJNDAEL_Encrypt vektor(), byte_key()
               RIJNDAEL_Encrypt vektor(), byte_key()
               seek #file1, 33
               
            case else
               'Soll die Datei verschlüsselt werden, so wird zunächst der Hash verschlüsselt
               'Puffergröße (zum Schreiben in die Datei) auf 32 Byte setzen
               redim block(31)
               redim keystream(31)
               'Keystream von 32 Byte Länge erzeugen
               'Passwort wird AES-Verschlüsselt.
               '-> 16 Byte String wird in keystream gespeichert, 16 Byte String nochmal AES verschlüsselt
               '-> Neuer 16 Byte String wird in keystream angehängt.
               for a as byte= 0 to 1
                  RIJNDAEL_Encrypt vektor(), byte_key()
                  for b as byte = 0 to 15
                     keystream(b+(a*16)) = vektor(b)
                  next b
               next a

               'Puffer füllen (mit den ASC-Werten des Hashs)
               for a as byte = 0 to 31
                     block(a) = hash[a]
               next a
               'Block mit Keystream verschlüsseln und in die Zieldatei schreiben
               encrypt_value(keystream(), block())
               put #file2, , block()   
               redim keystream(0)
         end select
         
         'Lese- / Schreibpuffergröße auf Blockgröße setzen
         redim block(blocksize - 1)
         redim keystream(blocksize-1)
         'So lange der ungelesene Teil der Quelldatei größer als die Blockgröße ist...
dim as integer zeile = csrlin
         do until loc(file1) + blocksize >= lof(file1)   
         'Keystream-Puffer in der Größe der Blockgröße erstellen
            for a as integer = 0 to (blocksize \ 16) -1
               RIJNDAEL_Encrypt vektor(), byte_key()
               for b as byte = 0 to 15
                  keystream(b+(a*16)) = vektor(b)
               next b
            next a
            'Inhalt aus der Quelldatei lesen, ver- / entschlüsseln (mit Keystream) und in die Zieldatei schreiben
            get #file1, , block()
            encrypt_value(keystream(), block())
            put #file2, , block()
locate zeile, 1:print loc(file1); " / ";lof(file1)
         loop

         'Wenn der ungelesene Teil kleiner als die Blöckgröße ist...
         restgroesse = lof(file1) - loc(file1)
         if restgroesse > 0 then
            'Keystream-Puffer in der Größe der "Rest-Datei" erstellen
            dim as integer new_size = restgroesse
            if restgroesse mod 16 > 0 then
               new_size = restgroesse + (16 - (restgroesse mod 16))
            end if
            
            redim keystream(new_size)
            
            for a as integer = 0 to (new_size / 16) - 1
               RIJNDAEL_Encrypt vektor(), byte_key()
               for b as byte = 0 to 15
                  keystream(b+(a*16)) = vektor(b)
               next b
            next a

            'Lese- / Schreib-Puffer neu dimensionieren (ebenfalls auf den "Rest der Datei")
            redim block(restgroesse - 1)

            'Inhalt aus der Quelldatei lesen, ver- / entschlüsseln (mit Keystream) und in die Zieldatei schreiben
            get #file1, , block()
            encrypt_value(keystream(), block())
            put #file2, , block()
                     
locate zeile, 1:print loc(file1); " / ";lof(file1)
         end if
         
      close #file2
   close #file1
   
print "FERTIG!";" [";time;"]"

end sub

'~ print "TXT FAST"
'~ crypt_copyfile_fast ("../testumgebung/original/readme/COPYING.txt", "../testumgebung/backup/easy_copy_fast.txt","abcdefghijklmnop", encrypt)
'~ crypt_copyfile_fast ("../testumgebung/backup/easy_copy_fast.txt", "../testumgebung/backup/easy_decode_fast.txt","abcdefghijklmnop", decrypt)
'~ print "PIC FAST"
'~ crypt_copyfile_fast ("testumgebung/original/foto0299.jpg", "testumgebung/backup/foto0299_fast.jpg","abcdefghijklmnop", encrypt)
'~ crypt_copyfile_fast ("testumgebung/backup/foto0299_fast.jpg", "testumgebung/backup/foto0299_dec_fast.jpg","abcdefghijklmnop", decrypt)


'~ print "TXT SLOW"
'~ crypt_copyfile ("testumgebung/original/readme/easy.txt", "testumgebung/backup/easy_copy.txt","abcdefghijklmnop", encrypt)
'~ crypt_copyfile ("testumgebung/backup/easy_copy.txt", "testumgebung/backup/easy_decode.txt","abcdefghijklmnop", decrypt)
'~ print "PIC SLOW"
'~ crypt_copyfile ("testumgebung/original/foto0299.jpg", "testumgebung/backup/foto0299.jpg","abcdefghijklmnop", encrypt)
'~ crypt_copyfile ("testumgebung/backup/foto0299.jpg", "testumgebung/backup/foto0299_dec.jpg","abcdefghijklmnop", decrypt)


'~ end
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC. Alle Zeiten sind GMT + 1 Stunde
Gehe zu Seite 1, 2  Weiter
Seite 1 von 2

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.

 Impressum :: Datenschutz