self::$huffman_frq[$i], "asc"=>$i); } // PAIR LEAVES AND BRANCHES BASED ON FREQUENCY UNTIL THERE IS A SINGLE 'ROOT' for($i=0; $i<255; $i++) { $lowest_key1 = -1; $lowest_key2 = -1; $lowest_frq1 = 1E30; $lowest_frq2 = 1E30; // FIND THE LOWEST TWO FREQUENCIES for($j=0; $j<256; $j++) { if (self::$huffman_tree[$j] === FALSE) { continue; } if (self::$huffman_tree[$j]['frq'] < $lowest_frq1) { $lowest_key2 = $lowest_key1; $lowest_frq2 = $lowest_frq1; $lowest_key1 = $j; $lowest_frq1 = self::$huffman_tree[$j]['frq']; } elseif (self::$huffman_tree[$j]['frq'] < $lowest_frq2) { $lowest_key2 = $j; $lowest_frq2 = self::$huffman_tree[$j]['frq']; } } // JOIN THE TWO TOGETHER UNDER A NEW BRANCH self::$huffman_tree[$lowest_key1] = array("frq"=>($lowest_frq1 + $lowest_frq2), "branch0"=>self::$huffman_tree[$lowest_key2], "branch1"=>self::$huffman_tree[$lowest_key1]); self::$huffman_tree[$lowest_key2] = FALSE; } // MAKE THE ROOT THE ARRAY self::$huffman_tree = self::$huffman_tree[$lowest_key1]; } public static function binary_tree_to_lookup_table($branch, $binary_path = "") { // CHECK IF TABLE HAS ALREADY BEEN BUILT if ($binary_path == "" && self::$huffman_table) { return; } // GO THROUGH BRANCHES FINDING LEAVES WHILE TRACKING THE BINARY PATH TAKEN if (isset($branch['branch0'])) { self::binary_tree_to_lookup_table($branch['branch0'], $binary_path."0"); self::binary_tree_to_lookup_table($branch['branch1'], $binary_path."1"); return; } self::$huffman_table[$branch['asc']] = $binary_path; } public static function encode($data_string) { self::build_binary_tree(); self::binary_tree_to_lookup_table(self::$huffman_tree); // MATCH ASCII TO ENTRIES IN LOOKUP TABLE for($i=0; $i $binary_path) { $binary_length = strlen($binary_path); // NEEDS === OTHERWISE DOES NUMERIC COMPARISON ( 0011 == 11 ) if (substr($binary_string, 0, $binary_length) === $binary_path) { $decoded_string .= chr($ascii); $binary_string = substr($binary_string, $binary_length); continue 2; } } break; // NO MATCHES FOUND } return $decoded_string; } } //------------------------------------------------------------------------------------------------------------+ // EXAMPLE USAGE: define("SQF_NAME", 0x00000001); define("SQF_URL", 0x00000002); define("SQF_EMAIL", 0x00000004); define("SQF_MAPNAME", 0x00000008); define("SQF_MAXCLIENTS", 0x00000010); define("SQF_MAXPLAYERS", 0x00000020); define("SQF_PWADS", 0x00000040); define("SQF_GAMETYPE", 0x00000080); define("SQF_GAMENAME", 0x00000100); define("SQF_IWAD", 0x00000200); define("SQF_FORCEPASSWORD", 0x00000400); define("SQF_FORCEJOINPASSWORD", 0x00000800); define("SQF_GAMESKILL", 0x00001000); define("SQF_BOTSKILL", 0x00002000); define("SQF_DMFLAGS", 0x00004000); define("SQF_LIMITS", 0x00010000); define("SQF_TEAMDAMAGE", 0x00020000); define("SQF_TEAMSCORES", 0x00040000); // DEPRECIATED define("SQF_NUMPLAYERS", 0x00080000); define("SQF_PLAYERDATA", 0x00100000); define("SQF_TEAMINFO_NUMBER", 0x00200000); define("SQF_TEAMINFO_NAME", 0x00400000); define("SQF_TEAMINFO_COLOR", 0x00800000); define("SQF_TEAMINFO_SCORE", 0x01000000); define("SQF_TESTING_SERVER", 0x02000000); define("SQF_DATA_MD5SUM", 0x04000000); $request_flag = (SQF_NAME|SQF_URL|SQF_EMAIL|SQF_MAPNAME|SQF_MAXCLIENTS|SQF_MAXPLAYERS|SQF_PWADS|SQF_GAMETYPE|SQF_GAMENAME|SQF_IWAD|SQF_FORCEPASSWORD|SQF_FORCEJOINPASSWORD|SQF_GAMESKILL|SQF_BOTSKILL|SQF_DMFLAGS|SQF_LIMITS|SQF_TEAMDAMAGE|SQF_TEAMSCORES|SQF_NUMPLAYERS|SQF_PLAYERDATA|SQF_TEAMINFO_NUMBER|SQF_TEAMINFO_NAME|SQF_TEAMINFO_COLOR|SQF_TEAMINFO_SCORE|SQF_TESTING_SERVER|SQF_DATA_MD5SUM); $request_flag = (SQF_NAME|SQF_URL|SQF_EMAIL|SQF_MAPNAME|SQF_MAXCLIENTS|SQF_MAXPLAYERS|SQF_PWADS|SQF_GAMETYPE|SQF_GAMENAME|SQF_IWAD|SQF_FORCEPASSWORD|SQF_FORCEJOINPASSWORD|SQF_GAMESKILL|SQF_BOTSKILL|SQF_DMFLAGS|SQF_LIMITS|SQF_TEAMDAMAGE| SQF_NUMPLAYERS|SQF_PLAYERDATA|SQF_TEAMINFO_NUMBER|SQF_TEAMINFO_NAME|SQF_TEAMINFO_COLOR|SQF_TEAMINFO_SCORE ); $request = pack("l", 199); $request .= pack("l", $request_flag); $request .= "\x21\x21\x21\x21"; // pack("l", time()); $request = huffman::encode($request); $request = huffman::decode($request); //------------------------------------------------------------------------------------------------------------+ // EXAMPLE HOW TO SEPARATELY GENERATE AND OUTPUT THE TABLE: huffman::build_binary_tree(); huffman::binary_tree_to_lookup_table(huffman::$huffman_tree); $huffman_table = huffman::$huffman_table; ksort($huffman_table, SORT_NUMERIC); foreach($huffman_table as $ascii => $binary_path) { echo "{$ascii} -- ".htmlentities(chr($ascii), ENT_QUOTES)." -- {$binary_path}
\r\n"; } //------------------------------------------------------------------------------------------------------------+ ?>