php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #1755 base64_decode uses inefficient algorithm
Submitted: 1999-07-20 12:34 UTC Modified: 1999-07-21 05:03 UTC
From: bfranklin at dct dot com Assigned:
Status: Closed Package: Performance problem
PHP Version: 4.0 Beta 1 OS: Sparc Solaris 2.7
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: bfranklin at dct dot com
New email:
PHP Version: OS:

 

 [1999-07-20 12:34 UTC] bfranklin at dct dot com
Base64_decode uses strchr to lookup the location of a character in base64_table[], causing a function call and (on average) 32 comparisons per encoded character.

It would be far more efficient to build a static array of reverse lookup values to use.

Here's a patch to fix this:
--- base64.c.orig       Tue Jul 20 10:29:42 1999
+++ base64.c    Tue Jul 20 10:51:54 1999
@@ -71,18 +71,34 @@
 unsigned char *_php3_base64_decode(const unsigned char *string, int length, int *ret_length) {
        const unsigned char *current = string;
        int ch, i = 0, j = 0, k;
+       static int reverse_table[256];
+       static int table_built = 0;
 
        unsigned char *result = (unsigned char *)emalloc((length / 4 * 3 + 1) * sizeof(char));
        if (result == NULL) {
                return NULL;
        }
 
+       /* build table of reverse mappings to speed things up */
+       if( ! table_built )
+       {
+               char *chp;
+               for(ch=0;ch<256;ch++)
+               {
+                       chp = strchr(base64_table, ch);
+                       if( chp != NULL )
+                               reverse_table[ch] = chp - base64_table;
+                       else
+                               reverse_table[ch] = -1;
+               }
+               table_built = 1;
+       }
+
        /* run through the whole string, converting as we go */
        while ((ch = *current++) != '\0') {
                if (ch == base64_pad) break;
-               ch = (int)strchr(base64_table, ch);
-               if (ch == 0) continue;
-               ch -= (int)base64_table;
+               ch = reverse_table[ch];
+               if (ch < 0) continue;
 
                switch(i % 4) {
                case 0:

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [1999-07-21 05:03 UTC] sas at cvs dot php dot net
Thanks, patch applieds
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Sun Jan 05 09:01:27 2025 UTC