From 677f9aedbf78cf4acc3f4f26d8b48afd11590584 Mon Sep 17 00:00:00 2001 From: David M <davidmj@users.sourceforge.net> Date: Thu, 9 Feb 2006 07:02:50 +0000 Subject: [PATCH] - It turns out that a very fast Adler-32 implementation exists, this removes the bulk of my runtime fears and allows me to make the script a little more readable. - Found a neat way to express the size of the image computationally instead of counting the length - Removed pointless iteration variables, they removed readability git-svn-id: file:///svn/phpbb/trunk@5538 89ea8834-ac86-4346-8a33-228a782c2dd0 --- phpBB/includes/ucp/ucp_confirm.php | 65 ++++++++++++++++++------------ 1 file changed, 40 insertions(+), 25 deletions(-) diff --git a/phpBB/includes/ucp/ucp_confirm.php b/phpBB/includes/ucp/ucp_confirm.php index 3bb1ff0a04..efbde293f0 100644 --- a/phpBB/includes/ucp/ucp_confirm.php +++ b/phpBB/includes/ucp/ucp_confirm.php @@ -40,18 +40,17 @@ class ucp_confirm WHERE session_id = '" . $db->sql_escape($user->session_id) . "' AND confirm_id = '" . $db->sql_escape($confirm_id) . "'"; $result = $db->sql_query($sql); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); // If we have a row then grab data else create a new id - if ($row = $db->sql_fetchrow($result)) - { - $db->sql_freeresult($result); - $code = $row['code']; - } - else + if (!$row) { exit; } + $code = $row['code']; + // If we can we will generate a single filtered png, we avoid nastiness via emulation of some Zlib stuff $_png = $this->define_filtered_pngs(); @@ -59,14 +58,13 @@ class ucp_confirm $total_height = 50; $img_height = 40; $img_width = 0; - $l = 0; list($usec, $sec) = explode(' ', microtime()); mt_srand($sec * $usec); $char_widths = array(); $code_len = strlen($code); - for ($i = 0; $i < $code_len; ++$i) + for ($i = 0; $i < $code_len; $i++) { $char = $code{$i}; @@ -80,20 +78,18 @@ class ucp_confirm $image = ''; $hold_chars = array(); - for ($i = 0; $i < $total_height; ++$i) + for ($i = 0; $i < $total_height; $i++) { $image .= chr(0); if ($i > $offset_y && $i < $offset_y + $img_height) { - $j = 0; - - for ($k = 0; $k < $offset_x; ++$k) + for ($k = 0; $k < $offset_x; $k++) { $image .= chr(mt_rand(140, 255)); } - for ($k = 0; $k < $code_len; ++$k) + for ($k = 0; $k < $code_len; $k++) { $char = $code{$k}; @@ -101,19 +97,17 @@ class ucp_confirm { $hold_chars[$char] = explode("\n", chunk_split(base64_decode($_png[$char]['data']), $_png[$char]['width'] + 1, "\n")); } - $image .= $this->randomise(substr($hold_chars[$char][$l], 1), $char_widths[$j++]); + $image .= $this->randomise(substr($hold_chars[$char][$i - $offset_y - 1], 1), $char_widths[$k]); } - for ($k = $offset_x + $img_width; $k < $total_width; ++$k) + for ($k = $offset_x + $img_width; $k < $total_width; $k++) { $image .= chr(mt_rand(140, 255)); } - - ++$l; } else { - for ($k = 0; $k < $total_width; ++$k) + for ($k = 0; $k < $total_width; $k++) { $image .= chr(mt_rand(140, 255)); } @@ -142,7 +136,7 @@ class ucp_confirm $new_line = ''; $end = strlen($scanline) - ceil($width/2); - for ($i = floor($width/2); $i < $end; ++$i) + for ($i = floor($width/2); $i < $end; $i++) { $pixel = ord($scanline{$i}); @@ -196,18 +190,39 @@ class ucp_confirm } else { - $len = strlen($raw_image); - // Adler-32 hash, lets go! + // The total length of this image, uncompressed, is just a calculation of pixels + $len = $temp_len = ($width + 1) * $height; + + // Optimized Adler-32 loop ported from the GNU Classpath project $s1 = 1; $s2 = 0; - for ($n = 0; $n < $len; ++$n) { - $s1 = ($s1 + ord($raw_image[$n])) % 65521; - $s2 = ($s2 + $s1) % 65521; + $i = 0; + while ($temp_len > 0) + { + // We can defer the modulo operation: + // s1 maximally grows from 65521 to 65521 + 255 * 3800 + // s2 maximally grows by 3800 * median(s1) = 2090079800 < 2^31 + $n = 3800; + if ($n > $temp_len) + { + $n = $temp_len; + } + $temp_len -= $n; + while (--$n >= 0) + { + $s1 += (ord($raw_image[$i++]) & 255); + $s2 += $s1; + } + $s1 %= 65521; + $s2 %= 65521; } $adler = ($s2 << 16) | $s1; + // This is the same thing as gzcompress($raw_image, 0) - $raw_image = pack('C7', 0x78, 0x01, 1, $len & 255, ($len >> 8) & 255, 255 - ($len & 255), 255 - (($len >> 8) & 255)) . $raw_image; + $raw_image = pack('C7', 0x78, 0x01, 0x01, $len, ($len >> 8) & 255, ~$len & 255, ~($len >> 8)) . $raw_image; $raw_image .= pack('C4', ($adler >> 24) & 255, ($adler >> 16) & 255, ($adler >> 8) & 255, $adler & 255); + + // The Zlib header + Adler hash make us add on 11 $len += 11; } $image .= $this->png_chunk($len, 'IDAT', $raw_image);