{You won't get that sort of compression from my routines, but here they are anyway. When testing, you'll get best compression if you use English and longish Strings. } Unit Compress; Interface Const CompressedStringArraySize = 500; { err on the side of generosity } Type tCompressedStringArray = Array[1..CompressedStringArraySize] of Byte; Function GetCompressedString(Arr : tCompressedStringArray) : String; Procedure CompressString(st : String; Var Arr : tCompressedStringArray; Var len : Integer); { converts st into a tCompressedStringArray of length len } Implementation Const FreqChar : Array[4..14] of Char = 'etaonirshdl'; { can't be in [0..3] because two empty bits signify a space } Function GetCompressedString(Arr : tCompressedStringArray) : String; Var Shift : Byte; i : Integer; ch : Char; st : String; b : Byte; Function GetHalfNibble : Byte; begin GetHalfNibble := (Arr[i] shr Shift) and 3; if Shift = 0 then begin Shift := 6; inc(i); end else dec(Shift,2); end; begin st := ''; i := 1; Shift := 6; Repeat b := GetHalfNibble; if b = 0 then ch := ' ' else begin b := (b shl 2) or GetHalfNibble; if b = $F then begin b := GetHalfNibble shl 6; b := b or GetHalfNibble shl 4; b := b or GetHalfNibble shl 2; b := b or GetHalfNibble; ch := Char(b); end else ch := FreqChar[b]; end; if ch <> #0 then st := st + ch; Until ch = #0; GetCompressedString := st; end; Procedure CompressString(st : String; Var Arr : tCompressedStringArray; Var len : Integer); { converts st into a tCompressedStringArray of length len } Var i : Integer; Shift : Byte; Procedure OutHalfNibble(b : Byte); begin Arr[len] := Arr[len] or (b shl Shift); if Shift = 0 then begin Shift := 6; inc(len); end else dec(Shift,2); end; Procedure OutChar(ch : Char); Var i : Byte; bych : Byte Absolute ch; begin if ch = ' ' then OutHalfNibble(0) else begin i := 4; While (i<15) and (FreqChar[i]<>ch) do inc(i); OutHalfNibble(i shr 2); OutHalfNibble(i and 3); if i = $F then begin OutHalfNibble(bych shr 6); OutHalfNibble((bych shr 4) and 3); OutHalfNibble((bych shr 2) and 3); OutHalfNibble(bych and 3); end; end; end; begin len := 1; Shift := 6; fillChar(Arr,sizeof(Arr),0); For i := 1 to length(st) do OutChar(st[i]); OutChar(#0); { end of compressed String signaled by #0 } if Shift = 6 then dec(len); end; end.