2017-12-15

Navigation

Skip Navigation Links

Hash algorithms

Asymmetric Algorithms

Symmetric Cipher Algorithms

Encoding Algorithms

Compression Algorithms

Pseudo Random Number Algorithms

Steganography

Library Wrappers

String Comparison

Others

Syntax highlighting by Prism
PBCrypto.com Mirror

String Compress

Algorithm creator(s)

Timm Motl


PB author(s)

Timm Motl


Description

Custom string compressor/decompressor


Note

Very fast compression/decompression


Source

https://forum.powerbasic.com/forum/user-to-user-discussions/source-code/23567-string-compressor-decompressor?t=22954


See also

n/a


Source Code

Download source code file stringcompr.bas (Right-click -> "Save as ...")

#COMPILE EXE
#REGISTER ALL
#INCLUDE "WIN32API.INC"
FUNCTION Compress(Source AS STRING) AS STRING
   LOCAL CharCount   AS LONG
   LOCAL Loop1       AS LONG
   LOCAL Loop2       AS LONG
   LOCAL SourceLen   AS LONG
   LOCAL BlockChar   AS STRING
   LOCAL Compressed  AS STRING
   LOCAL CurrChar    AS STRING
   LOCAL DupChar     AS STRING
   LOCAL pBlockChar  AS BYTE PTR
   LOCAL pCurrChar   AS BYTE PTR
   LOCAL pCompressed AS BYTE PTR
   LOCAL pDupChar    AS BYTE PTR
   LOCAL pSource     AS BYTE PTR


   BlockChar   = CHR$(0)
   Compressed  = SPACE$(LEN(Source))
   CurrChar    = " "
   DupChar     = " "
   pBlockChar  = STRPTR(BlockChar)
   pCompressed = STRPTR(Compressed)
   pCurrChar   = STRPTR(CurrChar)
   pDupChar    = STRPTR(DupChar)
   pSource     = STRPTR(Source)


   IF INSTR(Source, BlockChar) THEN
      EXIT FUNCTION
   ELSE
      @pCurrChar = @pSource
      INCR pSource
      INCR CharCount
      SourceLen = LEN(Source) + 1
      FOR Loop1 = 2 TO SourceLen
         IF @pSource <> @pCurrChar OR CharCount = 255 OR Loop1 = SourceLen THEN
            IF CharCount > 1 THEN
               IF CharCount > 3 THEN
                  @pCompressed = @pBlockChar
                  INCR pCompressed
                  LSET DupChar = CHR$(CharCount)
                  @pCompressed = @pDupChar
                  INCR pCompressed
                  @pCompressed = @pCurrChar
                  INCR pCompressed
               ELSE
                  FOR Loop2 = 1 TO CharCount
                     @pCompressed = @pCurrChar
                     INCR pCompressed
                  NEXT
               END IF
               CharCount = 1
            ELSE
               @pCompressed = @pCurrChar
               INCR pCompressed
            END IF
            @pCurrChar = @pSource
         ELSE
            INCR CharCount
         END IF
         INCR pSource
      NEXT
   END IF
   FUNCTION = MKDWD$(LEN(Source)) + LEFT$(Compressed, pCompressed - STRPTR(Compressed))
END FUNCTION
FUNCTION Decompress(Source AS STRING) AS STRING
   LOCAL Loop1         AS LONG
   LOCAL Loop2         AS LONG
   LOCAL SourceLen     AS LONG
   LOCAL BlockChar     AS STRING
   LOCAL DupChar       AS STRING
   LOCAL Decompressed  AS STRING
   LOCAL pBlockChar    AS BYTE PTR
   LOCAL pDecompressed AS BYTE PTR
   LOCAL pDupChar      AS BYTE PTR
   LOCAL pSource       AS BYTE PTR
   SourceLen     = LEN(Source)
   BlockChar     = CHR$(0)
   Decompressed  = SPACE$(CVDWD(Source))
   pBlockChar    = STRPTR(BlockChar)
   pDecompressed = STRPTR(Decompressed)
   pDupChar      = STRPTR(DupChar)
   pSource       = STRPTR(Source) + 4
   DO
      IF @pSource = @pBlockChar THEN
         INCR pSource
         @pDupChar = @pSource
         INCR pSource
         FOR Loop2 = 1 TO @pDupChar
            @pDecompressed = @pSource
            INCR pDecompressed
         NEXT
      ELSE
         @pDecompressed = @pSource
         INCR pDecompressed
      END IF
      INCR pSource
   LOOP WHILE pSource - STRPTR(Source) < SourceLen
   FUNCTION = Decompressed
END FUNCTION
FUNCTION PBMAIN
   LOCAL A AS STRING
   LOCAL B AS STRING
   LOCAL C AS STRING
   LOCAL Start  AS DWORD
   LOCAL Finish AS DWORD
   ' 64K test string... highly compressible
   A = "Sample " + STRING$(21835, "X") + " Text " + STRING$(21835, "Z") + " Compressor " +
SPACE$(21835) + " ABCDE"


   ' 64K test string... not compressible
   'A = REPEAT$(2520, "ABCDEFGHIJKLMNOPQRSTUVWXYZ") + "ABCDEFGHIJKLMNOP"
   Start = GetTickCount
   B = Compress(A)
   IF LEN(B) THEN
      C = Decompress(B)
      Finish = GetTickCount
      IF A = C THEN
         MSGBOX "Compressed and decompressed in  " + _
                FORMAT$((Finish - Start) / 1000, "#.###") + "  seconds"
      ELSE
         MSGBOX "Oops!  Return string did NOT match source string!"
      END IF
   ELSE
      MSGBOX "Source string was binary (contained a NULL ASCII character)" + $CRLF + $CRLF + _
             "This routine is for text strings only!"
   END IF
END FUNCTION

Mirror provided by Knuth Konrad