PHP Doku:: DekodiertMIME base64-kodierte Daten - function.base64-decode.html

Verlauf / Chronik / History: (50) anzeigen

Sie sind hier:
Doku-StartseitePHP-HandbuchFunktionsreferenzSonstige GrunderweiterungenURLsURL Funktionenbase64_decode

Ein Service von Reinhard Neidl - Webprogrammierung.

URL Funktionen

<<URL Funktionen

base64_encode>>

base64_decode

(PHP 4, PHP 5)

base64_decodeDekodiertMIME base64-kodierte Daten

Beschreibung

string base64_decode ( string $data [, bool $strict = false ] )

Dekodiert base64-kodierte Daten, die in data übergeben wurden.

Parameter-Liste

data

Die zu dekodierenden Daten.

strict

Gibt FALSE zurück, wenn der Input Zeichen enthält, die nicht im "base64-Alphabet" enthalten sind.

Rückgabewerte

Gibt die Originaldaten zurück. Im Fehlerfall wird FALSE zurückgegeben. Die zurückgegebenen Daten können in Binärform vorliegen.

Changelog

Version Beschreibung
5.2.0 strict-Parameter hinzugefügt

Beispiele

Beispiel #1 base64_decode()-Beispiel

<?php
$str 
'RGllcyBpc3QgZWluIHp1IGtvZGllcmVuZGVyIFN0cmluZw==';
echo 
base64_decode($str);
?>

Das oben gezeigte Beispiel erzeugt folgende Ausgabe:

Dies ist ein zu kodierender String

Siehe auch


15 BenutzerBeiträge:
- Beiträge aktualisieren...
martinstaemmler at gmx dot net
18.08.2009 6:05
I had some trouble trying to let base64_decode decode base64-strings longer than ~5k chars.

The base64-decoding function is a homomorphism between modulo 4 and modulo 3-length segmented strings. That motivates a divide and conquer approach: Split the encoded string into substrings counting modulo 4 chars, then decode each substring and concatenate all of them.

Then instead of

<?php $decoded = base64_decode($encoded); ?>

for big $encoded strings, it's saver to use

<?php
$decoded
= "";
for (
$i=0; $i < ceil(strlen($encoded)/256); $i++)
  
$decoded = $decoded . base64_decode(substr($encoded,$i*256,256));
?>

where 256 can be replaced by a sufficiently small modulo 4 natural.
dimagolov at yahoo dot com
10.07.2009 20:44
Here is function to decode Base 62 (see http://en.wikipedia.org/wiki/Base_62) string to number. It is used by MTA in message id, e.g. by Exim
<?php
function base62_decode($str) {
   
$ret= 0;
    for (
$i= 0, $l= strlen($str); $i < $l; $i++) {
       
$val= ord($str[$i]);
        if (
ctype_digit($str[$i]))
           
$val-= ord('0');
        else if (
ctype_upper($str[$i]))
           
$val-= ord('A') - 10;
        else if (
ctype_lower($str[$i]))
           
$val-= ord('a') - 36;
        else
           
$val= 0;
       
$ret= $ret * 62 + $val;
    }
    return
$ret;
}
?>
mcalwell
9.04.2009 18:20
I had a problem testing whether an imap message body was base64 encoded on a pre 5.2.* server.  I had been using this function on a post 5.2 server.

I found that the function imap_base64() returns FALSE on failing to decode a string, and that I could use that to check instead.

<?php
if(imap_base64($body)) $body = imap_base64($body);
?>
alvaro at demogracia dot com
5.12.2008 10:11
You can do partial decoding (e.g. from buffered input streams) if you choose a chunk length that is multiple of 4:

<?php

$encoded
= base64_encode('The quick brown fox jumps over the lazy dog');
for(
$i=0, $len=strlen($encoded); $i<$len; $i+=4){
    echo
base64_decode( substr($encoded, $i, 4) );
}

?>

4 encoded chars represent 3 original chars. The "=" character is used as padding.
twm at twmacinta dot com
10.07.2008 5:38
To follow up on Starson's post, PHP was changed to no longer treat a space as if it were a plus sign in CVS revision 1.43.2.1, which corresponds to PHP 5.1.0.  You can see what happened with a diff to branch point 1.43 at:

http://cvs.php.net/viewvc.cgi/php-src/ext/standard/base64.c

The CVS log indicates that this change was made to fix bug #34214 (base64_decode() does not properly ignore whitespace).

It would seem from the comment preceding the code which was removed that the treatment of the space as if it were the plus sign was actually intentional at one time:

    When Base64 gets POSTed, all pluses are interpreted as spaces.
    This line changes them back.  It's not exactly the Base64 spec,
    but it is completely compatible with it (the spec says that spaces
    are invalid).  This will also save many people considerable
    headache.

    if (ch == ' ') ch = '+';

However, RFC 3548 states that characters not in the Base64 alphabet should either be ignored or cause the implementation to reject the encoding and RFC 2045 says they should be ignored.  So the original code was unfortunately not fully compatible with the spec or other implementations.  It may have also masked problems with code not properly escaping POST variables.
debug
27.02.2008 21:39
@morgangalpin att gmail dotty com

A better implementation would be the following regular expression:

^[a-zA-Z0-9/+]*={0,2}$

Which will also detect the usage of = or == at the end of the string (and only end).

If this regex isn't following proper RFC guidelines, please comment on it.

A function geared specifically toward this:

<?php

function is_base64_encoded()
    {
        if (
preg_match('%^[a-zA-Z0-9/+]*={0,2}$%', $data)) {
            return
TRUE;
        } else {
            return
FALSE;
        }
    };

is_base64_encoded("iash21iawhdj98UH3"); // true
is_base64_encoded("#iu3498r"); // false
is_base64_encoded("asiudfh9w=8uihf"); // false
is_base64_encoded("a398UIhnj43f/1!+sadfh3w84hduihhjw=="); // true

?>
zmorris at zsculpt dot com
10.11.2007 23:22
Here is a drop-in replacement for base64_decode(), based on a faster version of morgangalpin's code:

<?php
// workaround for bug in php 4.3.11 through 4.4.7, 5.1.2 through 5.2.4 and perhaps others (http://bugs.php.net/bug.php?id=37244)
function    base64_decode_fix( $data, $strict = false )
{
    if(
$strict )
        if(
preg_match( '![^a-zA-Z0-9/+=]!', $data ) )
            return(
false );
   
    return(
base64_decode( $data ) );
}
?>
morgangalpin att gmail dotty com
14.08.2007 2:25
I was having trouble with base64_decode returning false if the data to be decoded wasn't actually encoded. It turns out that it is a bug that exists in PHP version 5.1.2, which I'm using, but it has been fixed in CVS. The relevant bug is: http://bugs.php.net/bug.php?id=37244 "base64_decode violates RFC 3548". The fix may become available in 5.2.4 or 6 or whatever is coming next.

Since I'm not able to upgrade PHP to the latest version, I needed a way to check if some data had actually been encoded before trying to decode it. Here is the function I've used; I hope it helps someone.

<?php
 
/**
   * Check a string of base64 encoded data to make sure it has actually
   * been encoded.
   *
   * @param $encodedString string Base64 encoded string to validate.
   * @return Boolean Returns true when the given string only contains
   * base64 characters; returns false if there is even one non-base64 character.
   */
 
function checkBase64Encoded($encodedString) {
   
$length = strlen($encodedString);
   
   
// Check every character.
   
for ($i = 0; $i < $length; ++$i) {
     
$c = $encodedString[$i];
      if (
        (
$c < '0' || $c > '9')
        && (
$c < 'a' || $c > 'z')
        && (
$c < 'A' || $c > 'Z')
        && (
$c != '+')
        && (
$c != '/')
        && (
$c != '=')
      ) {
       
// Bad character found.
       
return false;
      }
    }
   
// Only good characters found.
   
return true;
  }
?>
Tom
6.12.2006 19:23
This function supports "base64url" as described in Section 5 of RFC 4648, "Base 64 Encoding with URL and Filename Safe Alphabet"

    <?php
   
function base64url_decode($base64url)
    {
       
$base64 = strtr($base64url, '-_', '+/');
       
$plainText = base64_decode($base64);
        return (
$plainText);
    }
   
?>
Starson
19.09.2006 15:23
To expand on Jes' post:

The change took place between 5.0.5 and 5.1.0.  Exactly where I don't know or care.

In short php <= 5.0.5's base64_decode( $string ) will assume that a space is meant to be a + sign where php >= 5.1.0's base64_decode( $string ) will no longer make that assumption.  I did not see this noted in the change log.

Please note that, as of this writing, mb_convert_encoding( $string, "UTF-8", "BASE64" ) still behaves as base64_decode( $string ) did in php <= 5.0.5 regardless of the version of php you are running.
Jes
30.08.2006 17:31
I've come across an interesting issue with an external program that submits a gzcompressed base64_encoded string to PHP via POST. The external program encodes the string using the occasional " " (space) character, however if I encode the same original string within PHP (using base64_encode), it uses a "+" (plus) character wherever the external program would use a space. On my deployed machine, running PHP 4.3.9, base64_decode is fine with the " " (space) characters, but my test server running 5.1.4 is not. It took me a while to figure out that was the issue, but I ended up fixing it with a simple:

<?php

$post_data
= str_replace(" ","+",$_POST['string'])

?>

This fix works on both the 4.3.9 and 5.1.4 machines. I am sure that the external program is probably not conforming to the standard, and it isn't a PHP problem per-se; but incase anybody else ever runs into that.
paul at ijsfontein dot nl
10.06.2004 15:04
The user notes posted here helped me a lot in writing the PHP code to upload uuencoded files to a server using $_POST. Hardest thing to figure out was why the files came out scrambled and corrupted. After comparing the original file with the file reconstructed by the uudecode script, I found out that a simple "stripcslashes" on the posted data will do the trick.

So, to upload any kind of uuencoded file using a POST:
1. send the raw file data to the PHP script
2. $uuencoded_data = stripcslashes($_POST['filedata']);
3. strip the marker lines from $uuencoded_data (first line, last line and second last line of the data. Each line is seperated by a LF (chr(10)) character.)
4. $decoded_data = uudecode($stripped_uuencoded_data); (this function can be found in the user notes here).
5. Use the script provided in one of the user notes on this page to write the decoded data to a binary file.

That should do the trick!
tobias at silverxnet dot de
23.12.2003 21:16
I was wondering how to decode attached images within mails. Basically they are mostly JPEG files, so it was obviously to write a function that decodes JPEG images.
I guess the plainest way to do so was the following:

<?php
function base64_to_jpeg( $inputfile, $outputfile ) {
 
/* read data (binary) */
 
$ifp = fopen( $inputfile, "rb" );
 
$imageData = fread( $ifp, filesize( $inputfile ) );
 
fclose( $ifp );
 
/* encode & write data (binary) */
 
$ifp = fopen( $outputfile, "wb" );
 
fwrite( $ifp, base64_decode( $imageData ) );
 
fclose( $ifp );
 
/* return output filename */
 
return( $outputfile );
}
?>

This function decodes the given inputfile (a filename!) and saves it to the given outputfile (a filename as well) and then returns the output filename for further usage (e.g. redirect, imagejpeg() and so on).
I thought that might be helpful.
Klaus Fehrenbacher
17.04.2003 13:05
this script can correct the bug

<?php
$enc
= chunk_split(preg_replace('!\015\012|\015|\012!','',$enc));
$enc = base64_decode($enc);
?>
nsayer at kfu dot com
21.03.2002 22:15
I used to do uudecode as a C module, but I've discovered a really fast way to do it in PHP. Here it is:

<?php
function uudecode($encode) {
 
$b64chars="ABCDEFGHIJKLMNOPQRSTUVWXYZ\
abcdefghijklmnopqrstuvwxyz0123456789+/"
;

 
$encode = preg_replace("/^./m","",$encode);
 
$encode = preg_replace("/\n/m","",$encode);
  for(
$i=0; $i<strlen($encode); $i++) {
    if (
$encode[$i] == '`')
     
$encode[$i] = ' ';
   
$encode[$i] = $b64chars[ord($encode[$i])-32];
  }

  while(
strlen($encode) % 4)
   
$encode .= "=";

  return
base64_decode($encode);
}
?>

This is the PHP equivalent to perl's unpack("u",___). That is, you need to strip the 'begin' and 'end' lines from the typical uuencoded file.



PHP Powered Diese Seite bei php.net
The PHP manual text and comments are covered by the Creative Commons Attribution 3.0 License © the PHP Documentation Group - Impressum - mail("TO:Reinhard Neidl",...)