LZW compression and decompression with Javascript and PHP

When trying to transfer large amounts of data between client and server it might be helpful to use an algorithm to compress the data before transmission. The compression technique of choice could be the LZW (Lempel-Ziv-Welch) compression. There is a huge variety of different LZW implementations for various languages out there, probably the largest collection of them can be found here. However, a PHP port of the implementation is missing. Working with the JS implementation from the above mentioned site I thought it might be useful to have a PHP implementation of that exact JS implementation on the server side, so I ported the function to PHP. Using the JS implementation and the following PHP implementation, you should be able to compress and decompress data transferred between client (JS) and server (PHP) without any need of customization. A nice side effect of compressing your data with LZW is that it obfuscates the transferred data as well.
PHP implementation of LZW compression:

class LZW {
    function compress($uncompressed) {
        $dictSize = 256;
        $dictionary = array();
        for ($i = 0; $i < 256; $i++) {
            $dictionary[chr($i)] = $i;
        }
        $w = "";
        $result = "";
        for ($i = 0; $i < strlen($uncompressed); $i++) {
            $c = $this->charAt($uncompressed, $i);
            $wc = $w.$c;
            if (isset($dictionary[$wc])) {
                $w = $wc;
            } else {
                if ($result != "") {
                    $result .= ",".$dictionary[$w];
                } else {
                    $result .= $dictionary[$w];
                }
                $dictionary[$wc] = $dictSize++;
                $w = "".$c;
            }
        }
        if ($w != "") {
            if ($result != "") {
                $result .= ",".$dictionary[$w];
            } else {
                $result .= $dictionary[$w];
            }
        }
        return $result;
    }
    function decompress($compressed) {
        $compressed = explode(",", $compressed);
        $dictSize = 256;
        $dictionary = array();
        for ($i = 1; $i < 256; $i++) {
            $dictionary[$i] = chr($i);
        }
        $w = chr($compressed[0]);
        $result = $w;
        for ($i = 1; $i < count($compressed); $i++) {
            $entry = "";
            $k = $compressed[$i];
            if (isset($dictionary[$k])) {
                $entry = $dictionary[$k];
            } else if ($k == $dictSize) {
                $entry = $w.$this->charAt($w, 0);
            } else {
                return null;
            }
            $result .= $entry;
            $dictionary[$dictSize++] = $w.$this->charAt($entry, 0);
            $w = $entry;
        }
        return $result;
    }
    function charAt($string, $index){
        if($index < mb_strlen($string)){
            return mb_substr($string, $index, 1);
        } else{
            return -1;
        }
    }
}

Usage example:

$lzw = new LZW();
$cmp = $lzw->compress("http://webdevwonders.com");
// 104,116,116,112,58,47,47,119,101,98,100,101,118,119,111,110,266,114,115,46,99,111,109
$dcmp = $lzw->decompress($cmp); // http://webdevwonders.com
Please vote: How useful was this post for you?
Current rating:
(4 out of 5)
This entry was posted in Javascript, PHP and tagged , , . Bookmark the permalink.

Comments are closed.