インターネットの制限された環境で

追記(2011/09/29)

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


制限された環境で、テキストベースでバイナリデータをやりとりする。
そういう需要があるかもしれない。
Base64エンコードが最も適任と思われるが、Well knownなため、
解析されるかもしれない。
ということで、適当に作ってみた。
Linux環境なら、いろいろとやりようもあるので、Windows用。

バイナリファイルをテキスト変換

基本思想は、Base64と同じ。

Option Explicit

Dim TransTbl
TransTbl = "yAw2B!uCsDq8EoFmGkHi#IgJ17eKcLa^MbN94dOf%PhQjR3lS6nTpU0r$VtWvXxY5zZ"
Const ForReading = 1
Const ForWriting = 2
Const ForAppending = 8
Const TristateUseDefault = -2	' システムデフォルトでファイルを開く
Const TristateTrue = -1			' ファイルをUnicodeファイルとして開く
Const TristateFalse = 0			' ファイルをASCIIファイルとして開く


Dim LogStream
' **********************************************************
' ログ出力
' **********************************************************
Function LogWrite(msg)
	If Not IsNull(LogStream) Then
		LogStream.Write msg
	End If
End Function

' **********************************************************
' 1Byteを二つに分割する
' **********************************************************
Function SplitByte(inData, up, down, split)
    up = Int(inData / (2 ^ split))
    down = inData Mod (2 ^ split)
End Function




' **********************************************************
' main
' **********************************************************
Function main(target, outFile, table, log)
    Dim fso, InStream, OutStream
    ' Stream オブジェクト の作成
	Set fso = CreateObject("Scripting.FileSystemObject")

    ' 変換テーブル用文字列を読込む(指定がない場合は、デフォルト)
    If Len(table) > 0 Then
	    Set InStream = fso.OpenTextFile(table, ForReading, false, TristateUseDefault)
        TransTbl = InStream.Read(2 ^ 6)
		InStream.Close
		Set InStream = Nothing
    End If

    Set InStream = CreateObject("ADODB.Stream")
	InStream.Open
	InStream.Type = 1
	InStream.LoadFromFile target
    Set OutStream = fso.CreateTextFile(outFile, true)
	If Len(log) > 0 Then
	    Set LogStream = fso.OpenTextFile(log, ForAppending, true, TristateUseDefault)
	Else
		LogStream = Null
	End If

    ' 対象ファイルが終わるまで以下の処理を行う
    Dim inBuf, spBuf(2,2), valid, outBuf, LoopF
    LoopF = 1
    Do While LoopF >= 0
        ' 1Byte取得し、上位4Bit,下位4Bitに分解する
        If InStream.EOS Then
            LoopF = -1
            Exit Do
        Else
            inBuf = AscB(InStream.Read(1))
            SplitByte inBuf, spBuf(0,0), spBuf(0,1), 4
        End If
        LogWrite CStr(inBuf) & "=" & CStr(spBuf(0,0)) & ":" & CStr(spBuf(0,1)) & " "
        ' 1Byte取得し、上位2Bit,下位6Bitに分解する(取得失敗は、0にする)
        ' 二文字取得では、3。1文字では2を保持する
        If InStream.EOS Then
            LoopF = -1
            spBuf(1,0) = 0
            spBuf(1,1) = 0
            valid = 2
        Else
            inBuf = AscB(InStream.Read(1))
            SplitByte inBuf, spBuf(1,0), spBuf(1,1), 6
            valid = 3
            LoopF = LoopF + 1
        End If
        LogWrite CStr(inBuf) & "=" & CStr(spBuf(0,0)) & ":" & CStr(spBuf(0,1)) & " " & CStr(valid) & " "
        ' 以下の三文字を出力する
        ' ・保持数*(2^4)+上位4Bit
        ' ・上位2Bit*(2^4)+下位4Bit
        ' ・下位6Bit
        outBuf = Mid(TransTbl, valid * (2 ^ 4) + spBuf(0,0) + 1, 1)
        OutStream.Write outBuf
        LogWrite outBuf
        outBuf = Mid(TransTbl, spBuf(1,0) * (2 ^ 4) + spBuf(0,1) + 1, 1)
        OutStream.Write outBuf
        LogWrite outBuf
        outBuf = Mid(TransTbl, spBuf(1,1) + 1, 1)
        OutStream.Write outBuf
        LogWrite outBuf
        If LoopF > 20 Then
            LoopF = 1
            OutStream.Write Chr(13) & Chr(10)
        End If
        LogWrite Chr(13) & Chr(10)
    Loop

    InStream.Close
    OutStream.Close
    If Not IsNull(LogStream) Then
		LogStream.Close
	End If
    Set InStream = Nothing
    Set OutStream = Nothing
    Set LogStream = Nothing
End Function


Dim target, outFile, table, log
If WScript.Arguments.length > 1 Then
    target = WScript.Arguments(0)
    outFile = WScript.Arguments(1)
    If WScript.Arguments.length > 2 Then
        table = Wscript.Arguments(2)
        If WScript.Arguments.length > 3 Then
            log = Wscript.Arguments(3)
        Else
            log = ""
        End If
    Else
        table = ""
    End If
End If
main target, outFile, table, log
WScript.Echo "Fin!"

続いて、できたテキストをバイナリに戻す

ASANO, Sei (Runrun)さんの、バイナリデータを生成するクラスに依存しています。
掲載の許可を頂いていないので、リンクまで。
ADODB.Streamに書き込めるバイナリデータを生成するクラス


リンク先にある「Class ByteStream」と一緒に、以下のコードを加えれば、OK。

Dim TransTbl
TransTbl = "yAw2B!uCsDq8EoFmGkHi#IgJ17eKcLa^MbN94dOf%PhQjR3lS6nTpU0r$VtWvXxY5zZ"
Const ForReading = 1
Const ForWriting = 2
Const ForAppending = 8
Const TristateUseDefault = -2	' システムデフォルトでファイルを開く
Const TristateTrue = -1			' ファイルをUnicodeファイルとして開く
Const TristateFalse = 0			' ファイルをASCIIファイルとして開く


Dim LogStream
' **********************************************************
' ログ出力
' **********************************************************
Function LogWrite(msg)
	If Not IsNull(LogStream) Then
		LogStream.Write msg
	End If
End Function

' **********************************************************
' 1Byteを二つに分割する
' **********************************************************
Function SplitByte(inData, up, down, split)
    up = Int(inData / (2 ^ split))
    down = inData Mod (2 ^ split)
End Function




' **********************************************************
' main
' **********************************************************
Function main(target, outFile, table, log)
    Dim fso, InStream, OutStream, bstream
    ' Stream オブジェクト の作成
	Set fso = CreateObject("Scripting.FileSystemObject")

    ' 変換テーブル用文字列を読込む(指定がない場合は、デフォルト)
    If Len(table) > 0 Then
	    Set InStream = fso.OpenTextFile(table, ForReading, false, TristateUseDefault)
        TransTbl = InStream.Read(2 ^ 6)
		InStream.Close
		Set InStream = Nothing
    End If

    Set InStream = fso.OpenTextFile(target, ForReading, false, TristateUseDefault)
    Set OutStream = CreateObject("ADODB.Stream")
	OutStream.Type = adTypeBinary
	OutStream.Open
	Set bstream = New ByteStream
	If Len(log) > 0 Then
	    Set LogStream = fso.OpenTextFile(log, ForAppending, true, TristateUseDefault)
	Else
		LogStream = Null
	End If

    ' 対象ファイルが終わるまで以下の処理を行う
    Dim inBuf, spBuf(3,3), i, outBuf
    Do While (Not InStream.AtEndOfStream)
        ' 3文字読込み、それぞれを数字にする
        ' 上位4Bit,下位4Bitに分解する
        i = 1
        Do While (i <= 3) And (Not InStream.AtEndOfStream)
            inBuf = InStream.Read(1)
            If Asc(inBuf) <> 10 And Asc(inBuf) <> 13 And Asc(inBuf) <> 32 Then
				LogWrite inBuf
                spBuf(i,0) = Instr(TransTbl, inBuf) - 1
                SplitByte spBuf(i,0), spBuf(i,1), spBuf(i,2), 4
                i = i + 1
            End If
        Loop
        If i < 4 Then
            Exit Do
        End If
		For i = 1 To 3
			LogWrite " " & CStr(spBuf(i,0)) & "=" & CStr(spBuf(i,1)) & ":" & CStr(spBuf(i,2))
		Next
        ' 合成して出力する
		outBuf = (spBuf(1,2) * (2 ^ 4) + spBuf(2,2))
		OutStream.Write bstream.getByte(outBuf)
		LogWrite " " & CStr(outBuf)
        ' 2Byte目もあるなら出力する
        If spBuf(1,1) > 2 Then
			outBuf = (spBuf(2,1) * (2 ^ 6) + spBuf(3,0))
			OutStream.Write bstream.getByte(outBuf)
			LogWrite " " & CStr(outBuf)
        End If
		LogWrite Chr(13) & Chr(10)
    Loop

    InStream.Close
	OutStream.SaveToFile outFile, 2
	OutStream.Flush
    OutStream.Close
    If Not IsNull(LogStream) Then
		LogStream.Close
	End If
    Set InStream = Nothing
    Set OutStream = Nothing
	Set bstream = Nothing
    Set LogStream = Nothing
End Function


Dim target, outFile, table, log
If WScript.Arguments.length > 1 Then
    target = WScript.Arguments(0)
    outFile = WScript.Arguments(1)
    If WScript.Arguments.length > 2 Then
        table = Wscript.Arguments(2)
        If WScript.Arguments.length > 3 Then
            log = Wscript.Arguments(3)
        Else
            log = ""
        End If
    Else
        table = ""
    End If
End If
main target, outFile, table, log
WScript.Echo "Fin!"

、、、実験してて、バグを見つけた。
そのうち修正予定、、、。

追記(2/2)

  • 使用してたクラスの元ねたが分かったので、ソースから削除してリンクを掲載
  • バグの原因が分かったので、ソースを改修(スペースを無視するようにした、他)