<?php
/*
+----------------------------------------------------------------------+
| SofeeFramework for PHP 4 |
+----------------------------------------------------------------------+
| Copyright (c) 2004-2005 Sofee Development Team.(http://www.sofee.cn) |
+----------------------------------------------------------------------+
| This source file is subject to version 1.00 of the Sofee license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.sofee.cn/license/1_00.txt. |
| If you did not receive a copy of the Sofee license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| [email protected] so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Justin Wu <[email protected]> |
+----------------------------------------------------------------------+
*/
/* $Id: SofeeScriptDecoder.php,v 1.1 2005/06/14 06:30:14 wenlong Exp $ */
/**
* Sofee Script Decoder class - Decodes JScript/VBscript data encoded with the
* MS ScriptEncoder in true crossbrowser manner.
*
* This script was influenced by the C version (scrdec1x.c) by Mr.Brownstone,
* and is distributed under the terms of the BSD License.
*
* scrdec1x.c is copyright(c) Mr.Brownstone <[email protected]>
* http://www.virtualconspiracy.com/scrdec.html
*
* @package SofeeFramework
* @access public
* @version $Revision: 1.1 $
* @author Justin Wu <[email protected]>
* @homepage http://www.sofee.cn
* @copyright Copyright (c) 2004-2005 Sofee Development Team.(http://www.sofee.cn)
* @since 2005-06-14
sample:
require_once('SofeeScriptDecoder.php');
$scr = new SofeeScriptDecoder();
$str = file_get_contents('text.txt');
echo $scr->decode($str);
*/
define('STATE_COPY_INPUT', 100);
define('STATE_READLEN', 101);
define('STATE_DECODE', 102);
define('STATE_UNESCAPE', 103);
class SofeeScriptDecoder {
var $rawData = array (
0x64,0x37,0x69, 0x50,0x7E,0x2C, 0x22,0x5A,0x65, 0x4A,0x45,0x72,
0x61,0x3A,0x5B, 0x5E,0x79,0x66, 0x5D,0x59,0x75, 0x5B,0x27,0x4C,
0x42,0x76,0x45, 0x60,0x63,0x76, 0x23,0x62,0x2A, 0x65,0x4D,0x43,
0x5F,0x51,0x33, 0x7E,0x53,0x42, 0x4F,0x52,0x20, 0x52,0x20,0x63,
0x7A,0x26,0x4A, 0x21,0x54,0x5A, 0x46,0x71,0x38, 0x20,0x2B,0x79,
0x26,0x66,0x32, 0x63,0x2A,0x57, 0x2A,0x58,0x6C, 0x76,0x7F,0x2B,
0x47,0x7B,0x46, 0x25,0x30,0x52, 0x2C,0x31,0x4F, 0x29,0x6C,0x3D,
0x69,0x49,0x70, 0x3F,0x3F,0x3F, 0x27,0x78,0x7B, 0x3F,0x3F,0x3F,
0x67,0x5F,0x51, 0x3F,0x3F,0x3F, 0x62,0x29,0x7A, 0x41,0x24,0x7E,
0x5A,0x2F,0x3B, 0x66,0x39,0x47, 0x32,0x33,0x41, 0x73,0x6F,0x77,
0x4D,0x21,0x56, 0x43,0x75,0x5F, 0x71,0x28,0x26, 0x39,0x42,0x78,
0x7C,0x46,0x6E, 0x53,0x4A,0x64, 0x48,0x5C,0x74, 0x31,0x48,0x67,
0x72,0x36,0x7D, 0x6E,0x4B,0x68, 0x70,0x7D,0x35, 0x49,0x5D,0x22,
0x3F,0x6A,0x55, 0x4B,0x50,0x3A, 0x6A,0x69,0x60, 0x2E,0x23,0x6A,
0x7F,0x09,0x71, 0x28,0x70,0x6F, 0x35,0x65,0x49, 0x7D,0x74,0x5C,
0x24,0x2C,0x5D, 0x2D,0x77,0x27, 0x54,0x44,0x59, 0x37,0x3F,0x25,
0x7B,0x6D,0x7C, 0x3D,0x7C,0x23, 0x6C,0x43,0x6D, 0x34,0x38,0x28,
0x6D,0x5E,0x31, 0x4E,0x5B,0x39, 0x2B,0x6E,0x7F, 0x30,0x57,0x36,
0x6F,0x4C,0x54, 0x74,0x34,0x34, 0x6B,0x72,0x62, 0x4C,0x25,0x4E,
0x33,0x56,0x30, 0x56,0x73,0x5E, 0x3A,0x68,0x73, 0x78,0x55,0x09,
0x57,0x47,0x4B, 0x77,0x32,0x61, 0x3B,0x35,0x24, 0x44,0x2E,0x4D,
0x2F,0x64,0x6B, 0x59,0x4F,0x44, 0x45,0x3B,0x21, 0x5C,0x2D,0x37,
0x68,0x41,0x53, 0x36,0x61,0x58, 0x58,0x7A,0x48, 0x79,0x22,0x2E,
0x09,0x60,0x50, 0x75,0x6B,0x2D, 0x38,0x4E,0x29, 0x55,0x3D,0x3F
);
var $pick_encoding = array (
1, 2, 0, 1, 2, 0, 2, 0, 0, 2, 0, 2, 1, 0, 2, 0,
1, 0, 2, 0, 1, 1, 2, 0, 0, 2, 1, 0, 2, 0, 0, 2,
1, 1, 0, 2, 0, 2, 0, 1, 0, 1, 1, 2, 0, 1, 0, 2,
1, 0, 2, 0, 1, 1, 2, 0, 0, 1, 1, 2, 0, 1, 0, 2
);
var $transformed = array();
/**
* 说明
*
* @access private
* @var string
*/
var $digits;
/**
* Constructor
*
* @access public
* @return void
*/
function SofeeScriptDecoder() {
$this->maketrans();
$this->makedigits();
}
/**
* unescape a char
*
* @access public
* @param string [$char]
* @return string
*/
function unescape($char) {
$escapes = "#&!*$";
$escaped = "/r/n<>@";
$i = 0;
if (ord($char) > 126) {
return $char;
}
while ($escapes[$i]) {
if ($escapes[$i] == $char)
return $escaped[$i];
$i++;
}
return '?';
}
/**
* pre-building the char-matrix
*
* @access public
* @return void
*/
function maketrans() {
for ($i=0; $i<3; $i++) {
$this->transformed[$i] = array();
}
for ($i=31; $i<=126; $i++) {
for ($j=0; $j<3; $j++) {
$this->transformed[$j][$this->rawData[($i-31)*3 + $j]] = ($i==31) ? 9 : $i;
}
}
}
/**
* pre-building the char-matrix
*
* @access public
* @return void
*/
function makedigits() {
for ($i=0; $i<26; $i++) {
$this->digits[ord('A')+$i] = $i;
$this->digits[ord('a')+$i] = $i+26;
}
for ($i=0; $i<10; $i++) {
$this->digits[ord('0')+$i] = $i+52;
}
$this->digits[0x2b] = 62;
$this->digits[0x2f] = 63;
}
/**
* decode string length
*
* @access public
* @param string [$str]
* @return integer
*/
function decodeBase64($str) {
$val = 0;
$val += ($this->digits[ord($str[0])] << 2);
$val += ($this->digits[ord($str[1])] >> 4);
$val += ($this->digits[ord($str[1])] & 0xf) << 12;
$val += (($this->digits[ord($str[2])] >> 2) << 8);
$val += (($this->digits[ord($str[2])] & 0x3) << 22);
$val += ($this->digits[ord($str[3])] << 16);
return $val;
}
/**
* Decodes JScript/VBscript data encoded with the MS ScriptEncoder in true crossbrowser manner.
*
* @access public
* @param string [$str]
* @return string
*/
function decode($str) {
$marker = "#@~^";
$strIdx = 0;
$scrIdx = 0;
$decIdx = 0;
$char = null;
$strLen = $scrLen = 0;
$state = STATE_COPY_INPUT;
$ret = "";
while ($state) {
switch ($state) {
case STATE_COPY_INPUT :
$scrIdx = strpos($str, $marker, $strIdx);
if ($scrIdx !== false) {
$ret .= substr($str, $strIdx, $scrIdx);
$scrIdx += strlen($marker);
$state = STATE_READLEN;
} else {
$strIdx = $strIdx==0 ? 0 : $strIdx;
$ret .= substr($str, $strIdx, strlen($str));
$state = 0;
}
break;
case STATE_READLEN :
$strLen = substr($str, $scrIdx, 6);
$scrLen = $this->decodeBase64($strLen);
$scrIdx += (6 + strlen("=="));
$state = STATE_DECODE;
break;
case STATE_DECODE :
if (!$scrLen) {
$strIdx = $scrIdx + strlen("DQgAAA==^#~@");
$decIdx = 0;
$state = STATE_COPY_INPUT;
break;
}
$char = substr($str, $scrIdx, 1);
if ($char == "@") {
$state = STATE_UNESCAPE;
} else {
if (ord($char[0]) < 0x80) {
$ret .= chr($this->transformed[$this->pick_encoding[$decIdx%64]][ord($char)]);
$decIdx++;
} else {
$ret .= $char;
$scrLen++;
if (
(ord($char) > 0xa0) && (ord($char) < 0xff) // 936 - Simplified Chinese GBK - 0xa1-0xfe
|| (ord($char) > 0x80) && (ord($char) < 0xff) // 950 - Traditional Chinese Big5 - 0x81-0xfe
) {
$scrIdx++;
$scrLen--;
$ret .= substr($str, $scrIdx, 1);
}
}
$scrIdx++;
$scrLen--;
break;
}
case STATE_UNESCAPE:
$ret .= $this->unescape(substr($str, ++$scrIdx, 1));
$scrIdx++;
$scrLen -= 2;
$decIdx++;
$state = STATE_DECODE;
break;
}
}
return ($ret);
}
}
?>