static public function PrintHex($chars, $return=false, $width=0, $with_ascii=false)
    {
        $output = '';

        $hex_str   = '';
        $ascii_str = '';

        $width = (int) $width;
        if (!$width) {
            for ($i=0; isset($chars[$i]); $i++) {
                $hex_str   .= sprintf('%02x ', ord($chars[$i]));
                $ascii_str .= sprintf('%s  ', self::ASCII2Visible($chars[$i], '.'));
            }

            $output .= "HEX DUMP:\t" . $hex_str . "\n";
            if ($with_ascii) {
                $output .= "ASCII CHR: \t" . $ascii_str . "\n";
            }

        } else {

            for ($i=0; isset($chars[$i]); $i++) {
                $hex_str   .= sprintf('%02x ', ord($chars[$i]));
                $ascii_str .= sprintf('%s', self::ASCII2Visible($chars[$i], '.'));
            }

            $ph = $pa = 0;
            $wh = 3;
            $wa = 1;
            $lwh = $wh * $width;
            $lwa = $wa * $width;

            do {
                $output .= "DUMP\t";
                $output .= str_pad(substr($hex_str, $ph, $lwh), $lwh, ' ');
                $output .= "\t";
                $output .= str_pad(substr($ascii_str, $pa, $lwa), $lwa, ' ');
                $output .= "\n";
                $ph += $lwh;
                $pa += $lwa;

                if (!isset($hex_str[$ph]) || !isset($ascii_str[$pa])) {
                    break;
                }
            } while (true);
        }

        if ($return) {
            return $output;
        } else {
            echo $output;
            return true;
        }
    }