' Base85/Ascii85 encoding (RFC 1924 style) for binary data with delimiter markers
#COMPILE EXE
#DIM ALL

FUNCTION PBMAIN() AS LONG
    LOCAL i  AS LONG
    LOCAL j  AS LONG
    LOCAL srcLen  AS LONG
    LOCAL encodedLen  AS LONG
    LOCAL word  AS LONG
    LOCAL v0  AS LONG
    LOCAL v1  AS LONG
    LOCAL v2  AS LONG
    LOCAL v3  AS LONG
    LOCAL val  AS LONG
    LOCAL c0  AS LONG
    LOCAL c1  AS LONG
    LOCAL c2  AS LONG
    LOCAL c3  AS LONG
    LOCAL c4  AS LONG
    LOCAL padding  AS LONG
    LOCAL written  AS LONG
    LOCAL src(80) AS LONG
    LOCAL result AS STRING
    LOCAL testIdx  AS LONG
    LOCAL byteVal  AS LONG
    PRINT "=== Base85 / Ascii85 Encoding ==="
    PRINT

    srcLen = 8
    src(0) = 77
    src(1) = 97
    src(2) = 110
    src(3) = 32
    src(4) = 115
    src(5) = 117
    src(6) = 114
    src(7) = 101

    PRINT "Test 1: 'Man sure' (8 bytes)"
    PRINT "Input bytes:"
    FOR i = 0 TO srcLen - 1
        PRINT FORMAT$(src(i))
        IF i < srcLen - 1 THEN PRINT " ";
    NEXT i
    PRINT

    result = "<~"
    i = 0

    WHILE i < srcLen
        IF i + 3 < srcLen THEN
            v0 = src(i)
            v1 = src(i + 1)
            v2 = src(i + 2)
            v3 = src(i + 3)
            word = v0 * 16777216 + v1 * 65536 + v2 * 256 + v3

            IF word = 0 THEN
                result = result + "z"
            ELSE
                c0 = word / 52200625
                word = word MOD 52200625
                c1 = word / 614125
                word = word MOD 614125
                c2 = word / 7225
                word = word MOD 7225
                c3 = word / 85
                c4 = word MOD 85
                result = result + CHR$(c0 + 33) + CHR$(c1 + 33) + CHR$(c2 + 33) + CHR$(c3 + 33) + CHR$(c4 + 33)
            END IF
            i = i + 4
        ELSE
            padding = 4 - (srcLen - i)
            v0 = 0
            v1 = 0
            v2 = 0
            v3 = 0
            IF i < srcLen THEN v0 = src(i)
            IF i + 1 < srcLen THEN v1 = src(i + 1)
            IF i + 2 < srcLen THEN v2 = src(i + 2)
            IF i + 3 < srcLen THEN v3 = src(i + 3)
            word = v0 * 16777216 + v1 * 65536 + v2 * 256 + v3
            c0 = word / 52200625
            word = word MOD 52200625
            c1 = word / 614125
            word = word MOD 614125
            c2 = word / 7225
            word = word MOD 7225
            c3 = word / 85
            c4 = word MOD 85
            result = result + CHR$(c0 + 33) + CHR$(c1 + 33) + CHR$(c2 + 33) + CHR$(c3 + 33) + CHR$(c4 + 33)
            i = i + 4
        END IF
    WEND

    result = result + "~>"
    PRINT "Base85 string: " & result
    PRINT

    PRINT "Test 2: Empty input"
    result = "<~~>"
    PRINT "Base85: " & result
    PRINT

    PRINT "Test 3: Various lengths"
    FOR testIdx = 1 TO 10
        srcLen = testIdx
        FOR j = 0 TO srcLen - 1
            src(j) = (j * 37 + 13) AND 255
        NEXT j

        result = "<~"
        i = 0
        WHILE i < srcLen
            IF i + 3 < srcLen THEN
                v0 = src(i)
                v1 = src(i + 1)
                v2 = src(i + 2)
                v3 = src(i + 3)
                word = v0 * 16777216 + v1 * 65536 + v2 * 256 + v3
                IF word = 0 THEN
                    result = result + "z"
                ELSE
                    c0 = word / 52200625
                    word = word MOD 52200625
                    c1 = word / 614125
                    word = word MOD 614125
                    c2 = word / 7225
                    word = word MOD 7225
                    c3 = word / 85
                    c4 = word MOD 85
                    result = result + CHR$(c0 + 33) + CHR$(c1 + 33) + CHR$(c2 + 33) + CHR$(c3 + 33) + CHR$(c4 + 33)
                END IF
                i = i + 4
            ELSE
                padding = 4 - (srcLen - i)
                v0 = 0
                v1 = 0
                v2 = 0
                v3 = 0
                IF i < srcLen THEN v0 = src(i)
                IF i + 1 < srcLen THEN v1 = src(i + 1)
                IF i + 2 < srcLen THEN v2 = src(i + 2)
                IF i + 3 < srcLen THEN v3 = src(i + 3)
                word = v0 * 16777216 + v1 * 65536 + v2 * 256 + v3
                c0 = word / 52200625
                word = word MOD 52200625
                c1 = word / 614125
                word = word MOD 614125
                c2 = word / 7225
                word = word MOD 7225
                c3 = word / 85
                c4 = word MOD 85
                written = 5 - padding
                IF written > 5 THEN written = 5
                result = result + LEFT$(CHR$(c0 + 33) + CHR$(c1 + 33) + CHR$(c2 + 33) + CHR$(c3 + 33) + CHR$(c4 + 33), written)
                i = i + 4
            END IF
        WEND
        result = result + "~>"

        PRINT "Length" & STR$(testIdx) & ": " & result
    NEXT testIdx

    PRINT
    PRINT "--- Character set range ---"
    PRINT "Base85 uses chars 33 ('!') to 117 ('u')"
    PRINT "Lowest char: '!' (ASCII " & STR$(33) & ")"
    PRINT "Highest char: 'u' (ASCII " & STR$(117) & ")"
    PRINT "Special: 'z' represents 4 zero bytes"
    PRINT "Delimiters: '<~' and '~>'"

    PRINT
    PRINT "Base85 encoding complete."

    FUNCTION = 0
END FUNCTION
