固定長データは文字で見ると分かりにくい ― PowerShellでhex dumpして境界を見る

プログラミング・Web開発

この記事について
この記事は、生成AIを活用した自動生成フローで作成しています。.NETのEncoding APIを確認し、ダミー固定長レコードをbyte列として観察し、業務ファイルの項目ずれや文字コード不一致の調査へつなげる形に整理しています。

検証ステータス:📘 .NET公式仕様確認済み・実機未確認

固定長ファイルでは空白もデータです。画面上の文字列だけでなくbyte位置を見ると「どこからどこまでが項目か」が明確になります。

この考え方は、古い基幹システム、全銀系のような固定幅データ、外部委託先との連携ファイルなどで「見た目は合っているのに取り込みエラーになる」原因を調べるときに役立ちます。

今回の成功条件

1レコードをASCII byte列へ変換し、文字・空白・項目境界を位置付きで確認できれば成功です。

まず試す

$record = '001PANDA     025'
$bytes = [Text.Encoding]::ASCII.GetBytes($record)
0..($bytes.Length-1) | ForEach-Object {
  '{0:D2}: {1:X2} {2}' -f $_,$bytes[$_],[char]$bytes[$_]
}

ここを見る

空白は20として存在します。見た目で消えているわけではなく、項目幅を埋めるbyteです。

たとえば、このダミーレコードを次の仕様だと考えます。

byte位置項目
0-2コード3 byte
3-12名称10 byte
13-15数量3 byte

PANDAの後ろにある空白も、名称欄10byteを埋めるためのデータです。

項目単位で切ってみる

固定長データは、byte位置で切ると構造が見えます。

$code = [Text.Encoding]::ASCII.GetString($bytes, 0, 3)
$name = [Text.Encoding]::ASCII.GetString($bytes, 3, 10)
$qty  = [Text.Encoding]::ASCII.GetString($bytes, 13, 3)

[pscustomobject]@{
  Code = $code
  Name = $name.TrimEnd()
  Qty  = $qty
}

文字列全体を眺めるより、「3byte、10byte、3byte」という仕様書の定義と直接照合できます。

1か所変えてみる

PANDAパンダへ変えてEncodingをUTF-8にします。

$record = '001パンダ     025'
$bytes = [Text.Encoding]::UTF8.GetBytes($record)

"文字数 = $($record.Length)"
"byte数 = $($bytes.Length)"

文字数とbyte数が一致しなくなります。

ここで分かるのは、固定長仕様の「10文字」と「10byte」は同じではないということです。

なぜそうなる

ファイルは最終的にはbyte列です。文字コードは文字をどのbyte列へ変換するかを決めます。

ASCIIの英数字は基本的に1文字1byteなので、文字数とbyte数が一致しやすくなります。一方、UTF-8で日本語を使うと1文字が複数byteになるため、文字数だけで固定幅を管理すると境界がずれることがあります。

graph LR
A[文字列] --> B[Encoding]
B --> C[byte列]
C --> D[固定位置で項目分割]

あえて壊してみる

固定長仕様が「名称10byte」なのに、UTF-8の日本語を文字数だけで10文字入れたとします。

その場合、名称欄が10byteを超え、後ろの数量欄の開始位置まで食い込む可能性があります。

つまり、

コード | 名称       | 数量
001    | 10byte固定 | 025

という仕様なのに、実際には名称が13byte、15byte……と伸びれば、その後ろの項目位置が全部ずれます。

このタイプのエラーは、画面で文字列を見るだけでは原因が分かりにくいです。

さらに一段深く見る: 文字数ではなくbyte数を検査する

業務用チェックとしては、項目ごとのbyte数を事前検査できます。

$name = 'パンダ'
$encoding = [Text.Encoding]::UTF8
$byteCount = $encoding.GetByteCount($name)

[pscustomobject]@{
  Value      = $name
  CharCount  = $name.Length
  ByteCount  = $byteCount
  LimitBytes = 10
  Fits       = ($byteCount -le 10)
}

Fitsを見れば、「この値を10byte欄へ入れられるか」を機械的に確認できます。

事務職・業務でどこに使えるか

1. 基幹システムへのアップロードエラー調査

CSVではなく固定長ファイルをアップロードする業務で、

  • 特定行だけエラーになる

  • 日本語を入れた行だけ失敗する

  • 数量や金額が隣項目へずれる

といった現象がある場合、対象行を匿名化してbyte位置を見ると原因を絞れます。

2. Excelで作ったデータの受け渡し前チェック

事務担当がExcelで入力し、最終的に固定長テキストへ変換する業務では、セルのLENだけではbyte制限を判断できない場合があります。

PowerShell側でbyte数を検査し、

  • 規定byte以内か

  • 全角文字が混ざっていないか

  • 末尾空白が必要か

を確認する簡易チェックツールへ発展させられます。

3. ベンダーとの仕様確認

「名称10桁」とだけ書かれた仕様書では不十分なことがあります。

確認すべきなのは、

  • 10文字か10byteか

  • Encodingは何か

  • paddingは空白か0

  • 左寄せか右寄せか

  • 改行コードをレコード長へ含むか

です。

この5点を質問できるだけでも、受入テスト前のトラブルを減らせます。

4. 目視できない空白の確認

「Excelで見たら同じなのに片方だけエラー」というとき、半角空白、全角空白、NULL、改行など見えにくい差が原因になることがあります。

hex表示は、それらを見える値に変えるための道具です。

仕事で使うなら

全銀系や古い連携ファイルの調査では、仕様書のoffset、encoding、padding、改行有無を確認し、実データではなく匿名化サンプルで解析します。

まず1レコードだけで構造を確認し、その後に全件チェックへ広げるのが安全です。いきなり本番ファイルを書き換えず、読み取り専用の検査から始めます。

Microsoft Encoding.GetBytes: https://learn.microsoft.com/dotnet/api/system.text.encoding.getbytes

Microsoft Encoding.GetByteCount: https://learn.microsoft.com/dotnet/api/system.text.encoding.getbytecount

文書情報

記事タイトル
固定長データは文字で見ると分かりにくい ― PowerShellでhex dumpして境界を見る
作成日
更新日
Source URL
https://papanda925.com/?p=15466

ライセンス: 本記事のうち、当サイトが権利を有する本文・自作図表は、特記なき限り CC BY 4.0 で利用できます。生成AIを活用して作成・編集した内容を含みます。コードについて、別途ライセンス表示またはリンク先GitHubリポジトリのライセンスがある場合は、その条件を優先します。引用・第三者資料・画像・商標等は本ライセンスの対象外です。 利用ポリシー

タイトルとURLをコピーしました