Dabei wird die 256er-Basis in eine 85er-Basis zerlegt.
Der ASM-Befehl DIV ist dafür natürlich optimal geeignet, weil er sowohl dividiert, als auch den Rest ausgibt.
Das heißt, eine LONG (4Bytes) in EAX werfen, fünf mal DIV 85 anwenden und die Reste jeweils auf die Zeichen im String addieren, der vorher aus "!" besteht.
Hier ist mal mein Code (x86 only):
Code: Alles auswählen
Procedure.s Base85Encoder(*Input, Length.i)
Protected Result.s = RSet("", Length*5/4, "!")
*Input + Length
!MOV ebx, 85 ; Divisor
!MOV ecx, [p.p_Input] ; Leseadresse
!MOV edi, [p.v_Result] ; Schreibadresse
!SUB ecx, [p.v_Length]
!base85_loop:
!MOV eax, [ecx] ; Tiefer Dividend-Teil
!BSWAP eax
!MOV edx, 0 ; Hoher Dividend-Teil = 0
!DIV ebx ; Erste Division
!ADD [edi+4], dl ; Rest (nur das tiefste Byte) kommt in den String, addiert auf das "!"
!MOV edx, 0
!DIV ebx ; Zweite Division
!ADD [edi+3], dl
!MOV edx, 0
!DIV ebx ; Dritte Division
!ADD [edi+2], dl
!MOV edx, 0
!DIV ebx ; Vierte Division
!ADD [edi+1], dl
!MOV edx, 0
!DIV ebx ; Fünfte Division
!ADD [edi+0], dl
!ADD ecx, 4 ; Leseadresse + 4
!ADD edi, 5 ; Schreibadresse + 5
!CMP ecx, [p.p_Input] ; Fertig?
!JNZ base85_loop
ProcedureReturn Result
EndProcedure
Define *Buffer1 = AllocateMemory(9)
PokeS(*Buffer1, "Man sure")
Debug Base85Encoder(*Buffer1, 8)
Define *Buffer2 = AllocateMemory(1024*1024*10)
RandomData(*Buffer2, MemorySize(*Buffer2))
Define String.s = Base85Encoder(*Buffer2, MemorySize(*Buffer2))
Debug String
Debug "Länge: "+Str(Len(String))
Hinweis: Der ASM-Code ist nicht ganz sauber, da ich die Register ebx und esi nicht sichere. Das müsste ggf. noch nachgetragen werden. Außerdem sind nur 4er-Längen erlaubt!