まず、オリジナルのまま関数で移植しました。ふつーのC++のコードです。
#include <sstream>
#include <iostream>
#include <string>
using namespace std;
string jjencode(string gv, string& text) {
stringstream r, s;
const char* b[] = { "___", "__$", "_$_", "_$$", "$__", "$_$", "$$_", "$$$", "$___", "$__$", "$_$_", "$_$$", "$$__", "$$_$", "$$$_", "$$$$" };
for (int i = 0; i < text.size(); i++) {
char n = text.at( i );
if (n == 0x22 || n == 0x5c) {
s << "\\\\\\" << dec << n;
} else if ((0x20 <= n && n <= 0x2f) || (0x3A <= n == 0x40) || (0x5b <= n && n <= 0x60) || (0x7b <= n && n <= 0x7f)) {
s << dec << n;
} else if ((0x30 <= n && n <= 0x39) || (0x61 <= n && n <= 0x66)) {
if (!s.str().empty()) r << "\"" << s.str() << "\"+";
r << gv << "." << b[ n < 0x40 ? n - 0x30 : n - 0x57 ] << "+";
s.str("");
s.clear(stringstream::goodbit);
} else if (n == 0x6c) { // 'l'
if (!s.str().empty()) r << "\"" << s.str() << "\"+";
r << "(![]+\"\")[" << gv << "._$_]+";
s.str("");
s.clear(stringstream::goodbit);
} else if (n == 0x6f) { // 'o'
if (!s.str().empty()) r << "\"" << s.str() << "\"+";
r << gv << "._$+";
s.str("");
s.clear(stringstream::goodbit);
} else if (n == 0x74) { // 'u'
if( !s.str().empty() ) r << "\"" << s.str() << "\"+";
r << gv << ".__+";
s.str("");
s.clear(stringstream::goodbit);
} else if (n == 0x75) { // 'u'
if( !s.str().empty() ) r << "\"" << s.str() << "\"+";
r << gv << "._+";
s.str("");
s.clear(stringstream::goodbit);
} else if (n < 128) {
if (!s.str().empty()) r << "\"" << s.str();
else r << "\"";
r << "\\\\\"+";
stringstream ss;
string ns;
ss << oct << int(n) && ss >> ns;
string s08i = "01234567";
for (string::iterator it = ns.begin(); it != ns.end(); it++) {
if (s08i.find(*it) != string::npos)
r << gv << "." << b[ *it-'0' ] << "+";
else
r << *it;
}
s.str("");
s.clear(stringstream::goodbit);
}else{
if (!s.str().empty()) r << "\"" << s;
else r << "\"";
r << "\\\\\"+" << gv << "._+";
stringstream ss;
string ns;
ss << hex << int(n) && ss >> ns;
string s16i = "0123456789";
string s16a = "abcdef";
for (string::iterator it = ns.begin(); it != ns.end(); it++) {
if (s16i.find(tolower(*it)) != string::npos)
r << gv << "." << b[ *it-'0' ] << "+";
else
if (s16a.find(tolower(*it)) != string::npos)
r << gv << "." << b[ tolower(*it)-'a'+10 ] << "+";
else
r << *it;
}
s.str("");
s.clear(stringstream::goodbit);
}
}
if (!s.str().empty()) r << "\"" << s.str() << "\"+";
s.str("");
s.clear(stringstream::goodbit);
s <<
gv << "=~[];" <<
gv << "={___:++" << gv +",$$$$:(![]+\"\")["+gv+"],__$:++"+gv+",$_$_:(![]+\"\")["+gv+"],_$_:++" <<
gv+",$_$$:({}+\"\")["+gv+"],$$_$:("+gv+"["+gv+"]+\"\")["+gv+"],_$$:++"+gv+",$$$_:(!\"\"+\"\")[" <<
gv+"],$__:++"+gv+",$_$:++"+gv+",$$__:({}+\"\")["+gv+"],$$_:++"+gv+",$$$:++"+gv+",$___:++"+gv+",$__$:++"+gv+"};" <<
gv+".$_=" <<
"("+gv+".$_="+gv+"+\"\")["+gv+".$_$]+" <<
"("+gv+"._$="+gv+".$_["+gv+".__$])+" <<
"("+gv+".$$=("+gv+".$+\"\")["+gv+".__$])+" <<
"((!"+gv+")+\"\")["+gv+"._$$]+" <<
"("+gv+".__="+gv+".$_["+gv+".$$_])+" <<
"("+gv+".$=(!\"\"+\"\")["+gv+".__$])+" <<
"("+gv+"._=(!\"\"+\"\")["+gv+"._$_])+" <<
gv+".$_["+gv+".$_$]+" <<
gv+".__+" <<
gv+"._$+" <<
gv+".$;" <<
gv+".$$=" <<
gv+".$+" <<
"(!\"\"+\"\")["+gv+"._$$]+" <<
gv+".__+" <<
gv+"._+" <<
gv+".$+" <<
gv+".$$;" <<
gv+".$=("+gv+".___)["+gv+".$_]["+gv+".$_];" <<
gv+".$("+gv+".$("+gv+".$$+\"\\\"\"+" << r.str() << "\"\\\"\")())();";
return s.str();
}
int main(void) {
string line, content;
while(!cin.eof()) {
getline(cin, line);
content += line;
}
cout << jjencode("$", content) << endl;
}
これで前回失敗したjqueryで試してみました。結果は...30秒以内では戻ってこず断念。
あれーと思って、「そうか。一回結果を格納しちゃってるのがまずいのか!そうなら逐次出力すればいい!」とまた勝手な推測の元、stringstreamに溜め込まずcoutに吐き出す様修正しました。
#include <sstream>
#include <iostream>
#include <string>
using namespace std;
int main(void) {
const char* b[] = { "___", "__$", "_$_", "_$$", "$__", "$_$", "$$_", "$$$", "$___", "$__$", "$_$_", "$_$$", "$$__", "$$_$", "$$$_", "$$$$" };
string gv = "$";
cout <<
gv << "=~[];" <<
gv << "={___:++" << gv +",$$$$:(![]+\"\")["+gv+"],__$:++"+gv+",$_$_:(![]+\"\")["+gv+"],_$_:++" <<
gv+",$_$$:({}+\"\")["+gv+"],$$_$:("+gv+"["+gv+"]+\"\")["+gv+"],_$$:++"+gv+",$$$_:(!\"\"+\"\")[" <<
gv+"],$__:++"+gv+",$_$:++"+gv+",$$__:({}+\"\")["+gv+"],$$_:++"+gv+",$$$:++"+gv+",$___:++"+gv+",$__$:++"+gv+"};" <<
gv+".$_=" <<
"("+gv+".$_="+gv+"+\"\")["+gv+".$_$]+" <<
"("+gv+"._$="+gv+".$_["+gv+".__$])+" <<
"("+gv+".$$=("+gv+".$+\"\")["+gv+".__$])+" <<
"((!"+gv+")+\"\")["+gv+"._$$]+" <<
"("+gv+".__="+gv+".$_["+gv+".$$_])+" <<
"("+gv+".$=(!\"\"+\"\")["+gv+".__$])+" <<
"("+gv+"._=(!\"\"+\"\")["+gv+"._$_])+" <<
gv+".$_["+gv+".$_$]+" <<
gv+".__+" <<
gv+"._$+" <<
gv+".$;" <<
gv+".$$=" <<
gv+".$+" <<
"(!\"\"+\"\")["+gv+"._$$]+" <<
gv+".__+" <<
gv+"._+" <<
gv+".$+" <<
gv+".$$;" <<
gv+".$=("+gv+".___)["+gv+".$_]["+gv+".$_];" <<
gv+".$("+gv+".$("+gv+".$$+\"\\\"\"+";
cout.flush();
stringstream s;
while(!cin.eof()) {
char n;
cin.get(n);
if (n == 0x22 || n == 0x5c) {
s << "\\\\\\" << dec << n;
} else if ((0x20 <= n && n <= 0x2f) || (0x3A <= n == 0x40) || (0x5b <= n && n <= 0x60) || (0x7b <= n && n <= 0x7f)) {
s << dec << n;
} else if ((0x30 <= n && n <= 0x39) || (0x61 <= n && n <= 0x66)) {
if (!s.str().empty()) cout << "\"" << s.str() << "\"+";
cout << gv << "." << b[ n < 0x40 ? n - 0x30 : n - 0x57 ] << "+";
s.str("");
s.clear(stringstream::goodbit);
} else if (n == 0x6c) { // 'l'
if (!s.str().empty()) cout << "\"" << s.str() << "\"+";
cout << "(![]+\"\")[" << gv << "._$_]+";
s.str("");
s.clear(stringstream::goodbit);
} else if (n == 0x6f) { // 'o'
if (!s.str().empty()) cout << "\"" << s.str() << "\"+";
cout << gv << "._$+";
s.str("");
s.clear(stringstream::goodbit);
} else if (n == 0x74) { // 'u'
if( !s.str().empty() ) cout << "\"" << s.str() << "\"+";
cout << gv << ".__+";
s.str("");
s.clear(stringstream::goodbit);
} else if (n == 0x75) { // 'u'
if( !s.str().empty() ) cout << "\"" << s.str() << "\"+";
cout << gv << "._+";
s.str("");
s.clear(stringstream::goodbit);
} else if (n < 128) {
if (!s.str().empty()) cout << "\"" << s.str();
else cout << "\"";
cout << "\\\\\"+";
stringstream ss;
string ns;
ss << oct << int(n) && ss >> ns;
string s08i = "01234567";
for (string::iterator it = ns.begin(); it != ns.end(); it++) {
if (s08i.find(*it) != string::npos)
cout << gv << "." << b[ *it-'0' ] << "+";
else
cout << *it;
}
s.str("");
s.clear(stringstream::goodbit);
}else{
if (!s.str().empty()) cout << "\"" << s;
else cout << "\"";
cout << "\\\\\"+" << gv << "._+";
stringstream ss;
string ns;
ss << hex << int(n) && ss >> ns;
string s16i = "0123456789";
string s16a = "abcdef";
for (string::iterator it = ns.begin(); it != ns.end(); it++) {
if (s16i.find(tolower(*it)) != string::npos)
cout << gv << "." << b[ *it-'0' ] << "+";
else
if (s16a.find(tolower(*it)) != string::npos)
cout << gv << "." << b[ tolower(*it)-'a'+10 ] << "+";
else
cout << *it;
}
s.str("");
s.clear(stringstream::goodbit);
}
cout.flush();
}
if (!s.str().empty()) cout << "\"" << s.str() << "\"+";
cout << "\"\\\"\")())();" << endl;
}
これで前回失敗したjqueryで試してみました。結果は...またもや30秒以内では戻ってこず断念。
おかしいな...と思ってmod_ext_filterを通さず実行したらjqueryのファイル全体でも1.5秒程で終了しているので、どうやらmod_ext_filter側が蓄積してしまっているのが原因だと分かりました。 ... orz
まーそうやわなー。あたりまえやなー。勝手な推測しすぎです。
ただ、一度作ったjavascriptファイルをこのツールで変換して静的ファイルとして置く事は出来るはずですので、利用価値がない...とまでは言えないかもしれません。なお、jQueryの場合は$を潰すので変数gvを$以外のものにしないと動きません。