/* License This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License (http://www.gnu.org/copyleft/gpl.html) for more details. Original JavaScript Encoding/Decoding Written by Stephen Ostermiller Copyright (C) 2003-2005 Stephen Ostermiller (http://ostermiller.org/contact.pl?regarding=JavaScript+Encoding) Actionscript 2.0 Port: Jason Nussbaum, September 2005 Copyright (C) 2005 Jason Nussbaum (http://www.jasonnussbaum.com) */ class Base64 extends Object { ///#region Properties ///#endregion ///#region Constructor // all access to this class is through the // static Encode and Decode methods. private function Base64() {} ///#endregion ///#region Public Methods ///#region Static Methods public static function Encode( str:String ) : String { var encoder:Base64 = new Base64(); return encoder.encodeBase64( str ); } public static function Decode( str:String ) : String { var decoder:Base64 = new Base64(); return decoder.decodeBase64( str ); } public static function StringReplaceAll( source:String, find:String, replacement:String ) : String { return source.split( find ).join( replacement ); } ///#endregion ///#endregion ///#region Private vars ///#region Static Vars private static var _EndOfInput = -1; private static var _Chars:Array = new Array( 'A','B','C','D','E','F','G','H', 'I','J','K','L','M','N','O','P', 'Q','R','S','T','U','V','W','X', 'Y','Z','a','b','c','d','e','f', 'g','h','i','j','k','l','m','n', 'o','p','q','r','s','t','u','v', 'w','x','y','z','0','1','2','3', '4','5','6','7','8','9','+','/' ); private static var _CharsReverseLookup:Array; // = new Array(); private static var _CharsReverseLookupInited:Boolean = InitReverseChars(); private static var _Digits = new Array( '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' ); ///#endregion private var _base64Str:String; private var _base64Count:Number; ///#endregion ///#region Private Mtehods ///#region Static Methods private static function InitReverseChars() : Boolean { _CharsReverseLookup = new Array(); for ( var i=0; i < _Chars.length; i++ ) { _CharsReverseLookup[ _Chars[i] ] = i; } return true; } private static function UrlDecode( str:String ) : String { str = StringReplaceAll( str, "\+", " " ); str = unescape( str ); return str; } private static function UrlEncode( str:String ) : String { str = escape( str ); str = StringReplaceAll( str, "\+", "%2B" ); str = StringReplaceAll( str, "%20", "+" ); return str; } ///#endregion private function setBase64Str( str:String ) { _base64Str = str; _base64Count = 0; } private function readBase64() : Number { if( !_base64Str ) { return _EndOfInput; } if( _base64Count >= _base64Str.length ) { return _EndOfInput; } var c:Number = _base64Str.charCodeAt( _base64Count ) & 0xff; _base64Count++; return c; } private function encodeBase64( str:String ) { setBase64Str( str ); var result = ""; var inBuffer = new Array(3); var lineCount = 0; var done = false; while( !done && ( inBuffer[0] = readBase64() ) != _EndOfInput ) { inBuffer[1] = readBase64(); inBuffer[2] = readBase64(); result += ( _Chars[ inBuffer[0] >> 2 ] ); if( inBuffer[1] != _EndOfInput ) { result += ( _Chars[ ( ( inBuffer[ 0 ] << 4 ) & 0x30 ) | ( inBuffer[ 1 ] >> 4 ) ] ); if( inBuffer[ 2 ] != _EndOfInput ) { result += ( _Chars[ ( ( inBuffer[ 1 ] << 2 ) & 0x3c ) | ( inBuffer[ 2 ] >> 6 ) ] ); result += ( _Chars[ inBuffer[ 2 ] & 0x3F ] ); } else { result += ( _Chars[ ( ( inBuffer[ 1 ] << 2 ) & 0x3c ) ] ); result += ( "=" ); done = true; } } else { result += ( _Chars[ ( ( inBuffer[ 0 ] << 4 ) & 0x30 ) ] ); result += "="; result += "="; done = true; } lineCount += 4; if(lineCount >= 76) { result += ('\n'); lineCount = 0; } } return result; } private function readReverseBase64(){ if( !_base64Str ) { return _EndOfInput; } while( true ) { if( _base64Count >= _base64Str.length ) { return _EndOfInput; } var nextCharacter:String = _base64Str.charAt( _base64Count ); _base64Count++; if( _CharsReverseLookup[ nextCharacter ] ) { return _CharsReverseLookup[nextCharacter]; } if( nextCharacter == 'A' ) { return 0; } } return _EndOfInput; } private function ntos( n:Number ) : String { var str:String = n.toString( 16 ); // parseInt( n.toString(), 16 ).toString(); // if( str.length == 1 ) str = "0" + str; str = "%" + str; return unescape( str ); } private function decodeBase64( str:String ) : String { setBase64Str(str); var result:String = ""; var inBuffer:Array = new Array( 4 ); var done:Boolean = false; while( !done && ( inBuffer[ 0 ] = readReverseBase64() ) != _EndOfInput && ( inBuffer[ 1 ] = readReverseBase64() ) != _EndOfInput ) { inBuffer[ 2 ] = readReverseBase64(); inBuffer[ 3 ] = readReverseBase64(); result += ntos( ( ( ( inBuffer[ 0 ] << 2 ) & 0xff ) | inBuffer[ 1 ] >> 4 ) ); if( inBuffer[ 2 ] != _EndOfInput ) { result += ntos( ( ( ( inBuffer[ 1 ] << 4 ) & 0xff ) | inBuffer[ 2 ] >> 2 ) ); if(inBuffer[3] != _EndOfInput) { result += ntos((((inBuffer[2] << 6) & 0xff) | inBuffer[3])); } else { done = true; } } else { done = true; } } return result; } private function toHex( n:Number ) : String { var result:String = ""; var start = true; for( var i:Number=32; i>0; ) { i-=4; var digit = (n>>i) & 0xf; if(!start || digit != 0) { start = false; result += _Digits[digit]; } } return ( result=="" ? "0" : result ); } private function pad( str:String, len:Number, pad:String ) : String { var result:String = str; for (var i=str.length; i