Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Working on Base-85 Encoder/Decoder Functions
#11
Try this version @Dav :

Code: (Select All)
_CONTROLCHR OFF



test$ = "abc"
a$ = B256to128$(test$)
b$ = B128to256$(a$)
PRINT test$, a$, b$
PRINT LEN(test$), LEN(a$), LEN(b$)

SLEEP

FOR i = 0 TO 255
    t$ = CHR$(i)
    PRINT i, t$,
    a$ = B256to128(t$)
    PRINT a$,
    b$ = B128to256(a$)
    PRINT b$
    IF t$ <> b$ THEN
        PRINT "DON'T MATCH!!"
        END
    END IF
NEXT

PRINT
PRINT "All characters match before and after encoding and decoding."



FUNCTION B256to128$ (text$)
    FOR i = 1 TO LEN(text$)
        a = ASC(text$, i) '                      get the ASCII value of our character
        b$ = RIGHT$("00000000" + _BIN$(a), 8) '  convert it to binary
        temp$ = temp$ + b$ '                      add the binary to a single long string
    NEXT
    padding$ = STRING$(7 - LEN(temp$) MOD 7, "0")
    temp$ = temp$ + padding$ '                    add necessay padding to make it suitable for base-128 encoding
    FOR i = 1 TO LEN(temp$) STEP 7
        c$ = MID$(temp$, i, 7) '                  get 7 characters from our 8 byte represention
        c = VAL("&B" + c$) '                      that's the character value of our base 128-character
        temp1$ = temp1$ + CHR$(c + 65) '              add that to our new string
    NEXT
    B256to128$ = temp1$
END FUNCTION

FUNCTION B128to256$ (text$)
    FOR i = 1 TO LEN(text$)
        a = ASC(text$, i) - 65
        b$ = RIGHT$("0000000" + _BIN$(a), 7)
        temp$ = temp$ + b$
    NEXT
    temp$ = LEFT$(temp$, 8 * INT(LEN(temp$) / 8)) 'remove padding
    FOR i = 1 TO LEN(temp$) STEP 8
        b$ = "&B" + MID$(temp$, i, 8)
        temp1$ = temp1$ + CHR$(VAL(b$))
    NEXT
    B128to256$ = temp1$
END FUNCTION

I tried to change and simplify the process as much as possible here.  From the initial testing, all seems to be working now as it should, without that stray "0" popping up from time to time and biting you in the hiney.  

Try it out and let me know if it works as advertised, or not, for you.  Smile
Reply
#12
Works perfectly so far!  I gave it one of my testing methods and let it run on loop for a couple minutes.  No problems at all!  Thanks for the fix Steve. Smile

I'll post my test program for those interested.  It just generates random data strings and check the original size and content with the decoded size and content.  If there's a change then say so and stop.  Hasn't stopped yet.

On a side note, I have updated my Base85 functions on the first post to use CVL/MKL$ to do some dirty work, removing some calculations and code bloat.  A little faster, a little smaller.

- Dav

Edit: Fixed a typo in code.  Try'er again.

Code: (Select All)


'Testing Steve's functions.  Passed with flying colors.

_ControlChr Off

Do
    Cls
    Color 15: Print "Checking bytes loop -- Hit any key to stop checking ..."
    a$ = ""
    Print
    Color 7, 0: Print "Original:"
    For i = 0 To 200
        a$ = a$ + Chr$(Int(Rnd * 255))
    Next
    Print a$
    Print Len(a$); "bytes"

    Print
    Print "Encoded:"
    a2$ = B256to128$(a$): Print a2$
    Print Len(a2$); "bytes"
    Print
    Print "Decoded:"
    a3$ = B128to256$(a2$): Print a3$
    Print Len(a3$); "bytes"
    Print

    If Len(a$) <> Len(a3$) Then Print "Size don't match!"; t: End
    If a$ <> a3$ Then Print "Bytes don't match!"; t: End

    _Limit 25

    If _KeyHit Then Exit Do

Loop

Color 15: Print "No Problems detected!  Original and Decoded data are the same!"

Function B256to128$ (text$)
    For i = 1 To Len(text$)
        a = Asc(text$, i) '                      get the ASCII value of our character
        b$ = Right$("00000000" + _Bin$(a), 8) '  convert it to binary
        temp$ = temp$ + b$ '                      add the binary to a single long string
    Next
    padding$ = String$(7 - Len(temp$) Mod 7, "0")
    temp$ = temp$ + padding$ '                    add necessay padding to make it suitable for base-128 encoding
    For i = 1 To Len(temp$) Step 7
        c$ = Mid$(temp$, i, 7) '                  get 7 characters from our 8 byte represention
        c = Val("&B" + c$) '                      that's the character value of our base 128-character
        temp1$ = temp1$ + Chr$(c + 65) '              add that to our new string
    Next
    B256to128$ = temp1$
End Function

Function B128to256$ (text$)
    For i = 1 To Len(text$)
        a = Asc(text$, i) - 65
        b$ = Right$("0000000" + _Bin$(a), 7)
        temp$ = temp$ + b$
    Next
    temp$ = Left$(temp$, 8 * Int(Len(temp$) / 8)) 'remove padding
    For i = 1 To Len(temp$) Step 8
        b$ = "&B" + Mid$(temp$, i, 8)
        temp1$ = temp1$ + Chr$(Val(b$))
    Next
    B128to256$ = temp1$
End Function

Find my programs here in Dav's QB64 Corner
Reply
#13
Did some bench marking using the Base64, Base85, Base128 encoders using a 50,371 byte file for testing.  Seeing which would be the best to use for resource packing in BAS code.  All 3 have their advantages.  Here are the results...

The Base128 is best on making smallest output size, slower decoding.
The Base64 encodes fast, but makes largest output size.
The Base85 decodes fast, output size in between others.

- Dav

Find my programs here in Dav's QB64 Corner
Reply
#14
Fastest would probably just be hex.  Use _HEX$ and "&H" to convert back and forth.

Since decoding is something I tend to do only once to unpack resources at startup, speed isn't usually my primary concern.  The fewer lines I have to scroll past and the less lag in the IDE from excessively long programs, the happier I am!  Wink
Reply
#15
Hexified data that would be called Base 16?  I use to use that in Qbasic programs a lot, saving and restoring palette data.

I sure hope I didn't come across complaining about those routines you posted in any way.  They aren't too slow.  They are great! 

I think i will finish the Base91, then put the Base64/85/91 encoders in one collection.  After that take a break on encoded things - it's making me to start seeing everything si-goggly... Tongue

- Dav

Find my programs here in Dav's QB64 Corner
Reply
#16
I've been studying how you did your encoder, @SMcNeill. Really smart combining the binary data strings and the grouping those into smaller chunks.  I'm going to play around doing that.

- Dav

Find my programs here in Dav's QB64 Corner
Reply
#17
With some advice from @RhoSigma I was able to get these function to encode and decode so much faster.  A 1MB string takes only .25 seconds on my slow laptop to encode.  The first post has been edited with the updated functions.  Thanks Rho!

- Dav

Find my programs here in Dav's QB64 Corner
Reply




Users browsing this thread: 1 Guest(s)