バイナリダンプをバイナリに変換

To-BIN.ps1

バイナリダンプをバイナリに変換

To-BIN.ps1

# バイナリダンプをバイナリに変換
#
# 戻り値
#     なし
# -pathOutput
#     出力先のファイル・パス
#     既に存在する場合は内容を破棄してから書き込む
# -skipLine
#     スキップ行数
#     始めの行にコメントを記していた場合に飛ばす行数。0 以上
# -startIndex
#     行の始めにコメントを記していた場合に読み飛ばす文字数
# -count
#     一行に記載しているバイト数
Param( $pathOutput, $skipLine, $startIndex, $count )


Begin
{
    trap
    {
        break
    }

    $format = [System.Globalization.NumberFormatInfo]::new()

    Function ToInt( [System.Char] $c )
    {
        $n = $c.ToUInt32( $format )

        if( ($n - 0x30) -lt 10 )
        {
            return [int]($n - 0x30)
        }

        if( ($n - 0x41) -lt 26 )
        {
            return [int]($n - 0x41 + 10)
        }

        if( ($n - 0x61) -lt 26 )
        {
            return [int]($n - 0x61 + 10)
        }

        return [int]-1
    }


    $buffer = New-Object 'byte[]' $count


    $fs = [System.IO.FileStream]::new( $pathOutput, [System.IO.FileMode]::Create, [System.IO.FileAccess]::Write, [System.IO.FileShare]::Read )
    $bw = [System.IO.BinaryWriter]::new( $fs )


    $cnxt = @{}

    $cnxt.fnAction = $Null

    $cnxt.Action2 = `
    {
        Param( $xxxx )

        $lineChars = ([String] $xxxx).ToCharArray()

        $nIndex = $startIndex

        for( $i = 0; $i -lt $count; $i ++ )
        {
            $nH = ToInt $lineChars[$nIndex + 0]
            if( $nH -lt 0 )
            {
                $cnxt.fnAction = {}.GetNewClosure()
                break
            }
            $nL = ToInt $lineChars[$nIndex + 1]
            if( $nL -lt 0 )
            {
                $cnxt.fnAction = {}.GetNewClosure()
                break
            }

            $nIndex += 3

            $buffer[$i] = [byte] (($nH -shl 4) -bor ($nL -shl 0))
        }

        $bw.Write( $buffer, 0, $i )
    }.GetNewClosure()

    $cnxt.Action1 = `
    {
        if( -- $skipLine -eq 0 )
        {
            $cnxt.fnAction = $cnxt.Action2
        }
    }.GetNewClosure()

    if( $skipLine -gt 0 )
    {
        $cnxt.fnAction = $cnxt.Action1
    }
    else
    {
        $cnxt.fnAction = $cnxt.Action2
    }
}

End
{
    $bw.Dispose()
    $fs.Dispose()
}

Process
{
    & $cnxt.fnAction $_
}

使用サンプル

サンプルコード
# dump.txt をバイナリに変換
dump.txt の一行目を飛ばし、始めの 10 文字を飛ばす。一行 16 バイト記されている
Get-Context dump.txt | To-BIN dump.bin 1 10 16
dump.txt の内容
 ADDRESS  00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F  0123456789ABCDEF
00000000  FF EE DD CC BB AA 99 88 77 66 55 44 33 22 11 00  ........wfUD3".
00000010  0F 1E 2D 3C 4B 5A 69 78