気づいてしまった、、、。

追記(2011/09/29)

ただのBase64変換で良く、使うオブジェクトに制限がなければ、お手軽版があります。
WSHでバイナリー・テキスト相互変換(Base64変換) - じゅんじゅんのきまぐれ


いえ、最近ごそごそやってる、Base64デコードスクリプト
前回の検討はこちら
バイナリ出力を、テキスト形式で行うとNGな理由が、VBScriptの文字の取り扱いにあるのでは?
と、閃いてしまったのです。


で、試しにやってみました。
JScript版。

// テキスト→バイナリ
// f2t.vbsが変換したテキストファイルをバイナリに戻す
// Cr / Lf / (space) は無視しますので、変換文字には使えません
var TransTbl, PadChar, SecondTbl;
var sp = new Array(6, 4, 2, 0);
TransTbl = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
SecondTbl = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
PadChar = "=";
var adTypeBinary = 1;
var adTypeText = 2;
var Non = 256;
var TblLen = 64;
var ForReading = 1;
var ForWriting = 2;
var ForAppending = 8;
var TristateUseDefault = -2;	// システムデフォルトでファイルを開く
var TristateTrue = -1;			// ファイルをUnicodeファイルとして開く
var TristateFalse = 0;			// ファイルをASCIIファイルとして開く


var LogStream = null;
/**********************************************************
 ログ出力
 **********************************************************/
function LogWrite(msg)
{
	if(LogStream != null) {
		LogStream.Write(msg);
	}
}

/**********************************************************
 1Byteを二つに分割する
 **********************************************************/
function SplitByte(inData, split)
{
    var s = Math.pow(2, split);
    inData[1] = Math.floor(inData[0] / s);
	inData[2] = inData[0] % s;
}

var mDecodeIndex = 0, mDecode = new Array(4);
/**********************************************************
 decode
 **********************************************************/
var ret = new Array(3);
var spBuf = new Array(new Array(3), new Array(3), new Array(3), new Array(3));
function decode(target)
{
	// 内部バッファに蓄える
	if(target.charCodeAt(0) != 10 && target.charCodeAt(0) != 13 && target.charCodeAt(0) != 32) {
		mDecode[mDecodeIndex] = target;
		mDecodeIndex++;
	}
	if(mDecodeIndex < 4) {
	    return null;
	}
	mDecodeIndex = 0

	var inBuf, i, outBuf;
	// 4文字読込み、それぞれを数字にする
	// 上位Bit,下位Bitに分解する
	for(i = 0; i < 4; i++) {
		inBuf = mDecode[i];
		LogWrite(inBuf);
		spBuf[i][0] = TransTbl.indexOf(inBuf);
		if(spBuf[i][0] == -1) {
			spBuf[i][0] = SecondTbl.indexOf(inBuf);
		}
		if(spBuf[i][0] == -1) {
			spBuf[i][1] = 0;
			spBuf[i][2] = 0;
		} else {
			SplitByte(spBuf[i], sp[i]);
		}
	}
	for(i = 0; i < 4; i++) {
		LogWrite(" " + spBuf[i][0] + "=" + spBuf[i][1] + ":" + spBuf[i][2]);
	}

	// 合成して出力する
	for(i = 0; i < 3; i++) {
		if(spBuf[i+1][0] < TblLen) {
			ret[i] = spBuf[i][2] * Math.pow(2, (8 - sp[i])) + spBuf[i+1][1]
		} else {
			ret[i] = Non;
		}
		LogWrite(" " + ret[i]);
	}
	LogWrite("\r\n");

	return ret;
}



/**********************************************************
 main
 **********************************************************/
function main(target, outFile, table, pad, log)
{
	var fso, InStream, OutStream;
	// Stream オブジェクト の作成
	fso = new ActiveXObject("Scripting.FileSystemObject");

	// 変換テーブル用文字列を読込む(指定がない場合は、デフォルト)
	if(table.length > 0) {
		InStream = fso.OpenTextFile(table, ForReading, false, TristateUseDefault);
		TransTbl = InStream.Read(TblLen);
		InStream.Close();
	}
	// パディングが指定されている場合は、それを使う
	if(pad.length > 0) {
		PadChar = pad;
	}
	TransTbl = TransTbl + PadChar;
	SecondTbl = SecondTbl + PadChar;

	InStream = fso.OpenTextFile(target, ForReading, false, TristateUseDefault);
	OutStream = new ActiveXObject("ADODB.Stream");
	OutStream.Type = adTypeText;
	OutStream.charset = "iso-8859-1";
	OutStream.Open();
	if(log.length > 0) {
		LogStream = fso.OpenTextFile(log, ForAppending, true, TristateUseDefault);
	} else {
		LogStream = null;
	}

	// 対象ファイルが終わるまで以下の処理を行う
	var inBuf, buf, i, trans
	while(!InStream.AtEndOfStream) {
		// 4文字読込み、それぞれを数字にする
		inBuf = InStream.Read(1);
		// 合成して出力する
		buf = decode(inBuf);
		if(buf != null) {
			for(i = 0; i < 3; i++) {
				if(buf[i] < Non) {
					OutStream.WriteText(String.fromCharCode(buf[i]));
				}
			}
		}
	}

	InStream.Close();
	OutStream.SaveToFile(outFile, 2);
	OutStream.Flush();
	OutStream.Close();
	if(LogStream != null) {
		LogStream.Close();
	}
	InStream = null;
	OutStream = null;
	LogStream = null;
}


var arg = new Array(5), i;
for(i = 0; i < 5; i++) {
	if(WScript.Arguments.length > i) {
		arg[i] = WScript.Arguments.item(i);
	} else {
		arg[i] = "";
	}
}
main(arg[0], arg[1], arg[2], arg[3], arg[4]);
WScript.Echo("Fin!");

JScriptだと、こういう方法もあるのですねぇ。
ま、VBScriptの場合は、転載許可を頂いたクラスのお世話になるしかなさそうです。


ちなみに、「ADODB.Stream」は使うしかないようです、、、。
FileSystemObjectにS-JISのリーダバイトあたりを出力させようとすると、怒られます。
「Scripting.FileSystemObject」は「ADODB.Stream」で代用が利きますが、「ADODB.Stream」は任意の出力ができなさそうなため、ロガーとしてイマイチなのです、、、。
コマンドライン専用を想定するならば、ログは標準出力、という手もあるから、依存が少し減らせるけど。
いや、どちらかと言えば「ADODB.Stream」を減らしたいので、私には意味がないかも。


書いてて気づいた。
これって、Stream系クラスにすべきですね。
そうすれば、取り扱いも概念的に楽になるし。
Base64EncoderStreamとBase64DecoderStreamかな。



余談

「リーダバイト」という言葉は一般的でなかろう、と思い、検索してみた。
ちなみに、私の期待値は
「マルチバイト文字コードにおける、上位バイトのこと。参考)トレーラーバイト」
とかなんですけど、、、
Googleは、上位をそれ関連の話が占めました。
Yahoo!は、「バイトのリーダー君」の話でした。
上位10件中、Googleは6件、Yahoo!は1件が、コンピュータ関連の話。
Googleの方が技術者に優しい?
ま、たまたまかもしれないけどね。