TT Lab
はじめる
学ぶ 学習パス コース

銀行現場の言葉

取り込んだ後に誤った行を見つけても、もう遅い

TT Labで続きを見る

一言でいうと

相手機関から受け取った清算・送金指示ファイルは、取り込む前にフォーマット契約で検査し、1行でもずれていればファイル全体を差し戻します。入り口で拒否することは、取り込んだあとで突合することより常に安上がりです。

なぜ必要なのか

銀行の電算の1日は、ファイルで始まり、ファイルで終わります。相手機関が明け方にFTPで置いた1日分の指示ファイルを受け取って取り込み、夕方にこちらの結果を同じ方式で返します。この通り道で事故が起きるパターンは、いつも似ています。ファイルは届き、取り込みバッチは「成功」で終わり、ところが、相手が送ったトレーラーの件数とこちらが入れた件数が違うのです。

そのあとが本当の問題です。すでに入った行は、別のバッチがくわえて持っていきました。残高が変わり、通知が出ました。戻すには訂正伝票を書き、どの行が入ってどの行が抜けたかを数え直さなければなりません。ファイル1つを受け入れなければ5分で済んだことが、1日分の突合とお詫びの電話になります。

そのため、受信経路には必ずゲートキーパーが立ちます。ゲートキーパーの仕事は単純です。このファイルが、合意したフォーマット契約を守っているかだけを見ます。守っていなければ、1行も取り込まず、理由を付けて差し戻します。半分だけ入れるという選択肢はありません。

どう動くのか

フォーマット契約は、たいてい4つの層です。

第一に、ファイルの外見です。名前のルール、エンコーディング、行末。国内の金融機関の対外ファイルには、今もまだ固定長(fixed width)のEUC-KR系が多く残っています。Pythonではcp949コーデックを使いますが、標準エンコーディングの表は、このコーデックの別名を949、ms949、uhcと書き、言語をKoreanに分類しています。ハングル1文字がCP949では2バイト、UTF-8では3バイトだという違いが、次の層にそのままつながります。

第二に、レコードの構造です。固定長なら、1行がちょうど何バイトかを見ます。ここで最もよく起きる間違いが、文字数で埋めることです。受取人名の欄が20なら、それは20文字ではなく20バイトです。ハングル3文字の名前「キム・ソジュン」を3文字と見て、17個分を空白で埋めると、その行は規格の幅からずれ、そのあとのフィールドがまるごとずれます。Unicodeの扱い方ガイドが説明するように、Pythonの文字列の長さはコードポイントの数であり、ファイルに書かれるのはエンコードされたバイトです。切る場所は、strではなくbytesの上になければなりません。

CSVなら、RFC 4180が基準です。この文書はCategoryがInformationalで、自らインターネット標準を何も規定しないと明記していますが、事実上の合意として広く使われています。核心は3つです。改行・二重引用符・カンマを含むフィールドは、二重引用符で囲みます。囲まれたフィールド内の二重引用符は、二重引用符2つで書きます。レコードはCRLFで終わります。そのため、line.split(",")で切った瞬間、受取人名にカンマが含まれる行はフィールドが1つ増え、口座の位置に名前の断片が入ってきます。csvモジュールに任せれば、引用の中のカンマと改行を区切りとして数えません。

第三に、ヘッダーとトレーラーです。ファイル末尾のTレコードに書かれた件数と合計を、実際に数えた値と合わせます。これが、送信中の切れを捕まえる最も安い仕組みです。件数が合っているのに合計が違うなら、切れたのではなく値が変わったのであり、この2つは別の事故なので、エラーコードも別に置きます。

第四に、フィールド単位の規格と重複です。取引番号の形、口座の形式、金額の範囲を見ます。そして、同じファイルが2回来ることは、例外ではなく日常です。相手がこちらのレスポンスを受け取れなければ、同じファイルをもう一度置きます。ファイルのsha256が同じなら単なる再送で、連番は同じなのに内容が違うなら、それは事故です。hashlibでファイルのハッシュを残しておけば、この2つを切り分けられます。

수신함 ──▶ 이름·인코딩 ──▶ 레코드 폭·인용 ──▶ 트레일러 ──▶ 필드 ──▶ 중복
                 │              │               │           │        │
                 └──────────── 하나라도 걸리면 파일 전체를 거절 ──────┘

このコードブロックの韓国語コメントは、受信ボックス、名前・エンコーディング、レコード幅・引用、トレーラー、フィールド、重複の順に検査し、1つでも引っかかればファイル全体を拒否する、という意味です。

現場での姿

最初に出会う姿は、静かに壊れるエンコーディングです。規格はCP949なのに、相手機関がシステムを替えるときにUTF-8で送り始めます。運がよければ、デコードが例外で終わってすぐ引っかかります。運が悪いと、一部のバイトが別の文字として解釈され、名前だけが文字化けしたまま入ってしまいます。そのため、エンコーディングだけを見るのではなく、バイト幅まで一緒に見ます。ハングル1文字が2バイトから3バイトに変わると行の長さが変わるので、幅の検査がエンコーディングの事故をもう一度捕まえてくれます。

2つ目は、部分取り込みの誘惑です。「998件は問題ないのに、2件のせいで全部差し戻すのか」という声が、必ず出ます。差し戻さなければなりません。998件だけを入れると、相手のトレーラーの1000件とこちらの元帳の998件がずれたまま残り、翌日に相手が送った訂正ファイルにその2件が再び入ってきて、今度は重複になります。全部か無かで置いておけば、事故は1日で終わります。

3つ目は、理由のない拒否です。「フォーマットエラー」とだけ書いて差し戻すと、相手の担当者は何を直せばよいかわかりません。どの行のどのフィールドが何だったので引っかかったかを、機械が読める拒否ファイルとして一緒に返せば、相手はそのファイルを自分のバッチにそのまま渡せます。

実務で本当に大切なこと

次のラボですること

次のラボが使う80バイトのレコード配置とエラーコードの名前、終了コードは、このラボの前提です。機関ごとに規格が異なり、現場で原本になるのは、相手機関との間で交わした合意文書です。変わらないのは、検査する層の順序と、全部か無かという原則です。

相手機関4か所が送ってきた1日分の受信ボックスを自分で作り、その前に立つゲートキーパーを段階的に積み上げます。トレーラーの突合から始めて、固定長のバイト幅、規格と異なるエンコーディング、RFC 4180の引用、フィールドの検証と拒否ファイル、再送の判定まで加えます。採点ツールは、毎回異なる機関コードと件数で自分の受信ファイルを作り、作成したゲートキーパーを実行して判定を突き合わせます。最後に、自分の受信ボックスを処理して、受信レポートを残します。