MS_Encoding - NetDevInfraWGinOSSConsortium/NetDevInfraWiki GitHub Wiki

゚ンコヌディング

抂芁

  • ゚ンコヌディングずは【encoding】゚ンコヌド - 意味-解説-説明-定矩  IT甚語蟞兞
    https://e-words.jp/w/E382A8E383B3E382B3E383BCE38387E382A3E383B3E382B0.html
    • 情報を䞀定の芏則に埓っおデヌタに眮き換えお蚘録するこず。
    • ある圢匏のデヌタを䞀定の芏則に基づいお別の圢匏のデヌタに倉換するこず。
    • 文字゚ンコヌディングだけでなく、デヌタ圧瞮や暗号化などもこれに含たれる。

䜙談・・・ずなるず、

Stream に Decorate パタヌンを適甚する
殆どの凊理が゚ンコヌディングず蚀う事になる。

補足原文の「䜙談」は的を射おいる: .NET の Stream は
Decorator パタヌンで蚭蚈されおおり、
「倉換」を局ずしお重ねる構造になっおいる。

// 圧瞮 → 暗号化 → 文字゚ンコヌディング を重ねる
using var file   = File.Create("data.bin");
using var crypto = new CryptoStream(file, encryptor, CryptoStreamMode.Write);
using var gzip   = new GZipStream(crypto, CompressionMode.Compress);
using var writer = new StreamWriter(gzip, Encoding.UTF8);
writer.Write("本文");
【局の重なり】
   string文字
     ↓ StreamWriter文字゚ンコヌディング
   byte[]
     ↓ GZipStreamデヌタ圧瞮
   byte[]
     ↓ CryptoStream暗号化
   byte[]
     ↓ FileStream氞続化

どの局も「バむト列 → バむト列」の倉換であり、
文字゚ンコヌディングだけが特別なわけではない、
ずいう原文の指摘はそのたた正しい。
文字゚ンコヌディングは「最䞊局文字ずバむトの境界」に䜍眮する点だけが
他ず異なるここだけ string が絡む。

文字゚ンコヌディング

ココでは各皮、文字゚ンコヌディングの情報を纏めおいたす。
「倖字」に぀いおは、「Windowsの倖字」を参照䞋さい。

文字゚ンコヌディングずは、文字列デヌタを、
異なる文字コヌドコヌドペヌゞを䜿甚したバむト衚珟に倉換するこずである。

補足甚語の敎理: 「文字コヌド」ずいう語は耇数の局を混ぜお
䜿われるため、混乱の元になる。厳密には 3 局に分かれる。

å±€ 意味 䟋
笊号化文字集合Coded Character Set 「どの文字に、どの番号を振るか」 JIS X 0208、Unicode、ASCII
文字笊号化方匏Character Encoding Scheme 「その番号を、どうバむト列にするか」 Shift_JIS、EUC-JP、UTF-8、UTF-16
コヌドペヌゞ Microsoft / IBM が笊号化に振った番号 932CP932、65001UTF-8
【Unicode の堎合】
   文字「あ」
     ↓ 笊号化文字集合Unicodeが番号を決める
   U+3042コヌドポむント
     ↓ 文字笊号化方匏が バむト列にする
   UTF-8   → E3 81 823 バむト
   UTF-16  → 42 30リトル゚ンディアン、2 バむト
   UTF-32  → 42 30 00 004 バむト

「Unicode」ず「UTF-8」は同じ局のものではない。
Unicode は文字集合、UTF-8 はその笊号化方匏である。
Windows が蚀う「Unicode」は、倚くの堎合 UTF-16 LE を指す
Encoding.Unicode が UTF-16 LE であるのはこのため。

文字化け

文字化けは、䞀般的に、

  • ゚ンコヌダに適切な文字コヌドコヌドペヌゞを指定しおいない
  • プラットフォヌムやナヌザ間で䜿甚しおいる倖字が異なる
  • コヌドペヌゞによっおは、倉換が䞍可逆なケヌスがある

際に発生したす。

文字コヌドコヌドペヌゞ指定を倧きく誀っおいる堎合は、すぐ気が付くのですが、

  • UTF-16Unicode
  • UTF-8
  • Shift JIS
  • EUC-JP

䞀郚だけ文字化けする堎合のトラブルシュヌトは苊戊するこずが倚いです。
䞀郚だけ文字化けするパタヌンは以䞋の様に分類できるず考えたす。

  • 文字コヌドコヌドペヌゞ指定を倧きく間違えおいない埮劙に間違っおいる

    • 䟋えば、Shift_JIS の亜皮のコヌドペヌゞ指定を誀っおいる。
      • ISO-2022-JP
      • Microsoft コヌドペヌゞ932CP932
      • MacJapanese
  • 倖字領域の定矩芋た目が異なっおいる。

    • この堎合、デヌタの゚ンコヌド自䜓は正しく行われおいる。
    • 人間にずっおの芋た目が、異なっおいるため文字化けず感じられる。
    • 倖字に぀いおはこちらを参照「Windowsの倖字」

補足この分類は今も有効: 「倧きく間違えた文字化け」ず
「䞀郚だけの文字化け」を分けるずいう原文の芖点は、
障害切り分けの手順ずしおそのたた䜿える。

症状 原因の芋圓
党郚が化ける「譁ᅵ怜喧瞺ᅵ」等 ゚ンコヌディングの指定違い。たず疑う
党郚が ? になる 倉換先に存圚しない文字䟋UTF-8 → ASCII
䞀郚の蚘号だけ化ける〜、−、①、㈱ CP932 の亜皮違い、たたは波ダッシュ問題事䟋
䞀郚の挢字だけ化ける髙、 倖字・機皮䟝存文字、たたは JIS2004
□ や ・ で衚瀺される フォントにその字がないデヌタは正しい
1 文字が 2 文字に芋える サロゲヌト ペアの扱い文字のチェック方匏

最埌の 2 ぀は「文字化け」ではない点が重芁である。
デヌタは正しく、衚瀺偎の問題なので、
デヌタを盎そうずするず事態が悪化する。

ポむント

埓っお、以䞋に泚意を払う必芁がありたす。

  • プラットフォヌム

    • 実装されおいる文字コヌドコヌドペヌゞやフォント
    • 適甚される暙準の゚ンコヌディングが䜕か
    • フォントや倖字がむンストヌルされおいるか
  • ゚ンコヌディングが動䜜する箇所

    • ファむル I/O

    • SGML 文曞の I/O

      • HTML 出力
      • XML 入出力
    • ファむル転送プロトコルに実装されおいるケヌス

      • SFUMicrosoft Windows Services for UNIX
      • FTPASCII モヌド
    • デヌタベヌスの I/O
      Unicode 文字列以倖のフィヌルドから入出力する堎合、
      通垞、照合順序で指定したに察応した文字コヌドコヌドペヌゞ
      を䜿甚しお、゚ンコヌド・デコヌドされる。

補足「゚ンコヌディングが動䜜する箇所」の珟圚版: 原文の
**「境界を数え䞊げる」**ずいう発想が本質で、
珟圚のシステムでも同じ手順で掗い出せる。

【文字ずバむトの境界゚ンコヌディングが働く堎所】

 ① ファむル I/O          
 StreamReader/Writer の encoding 匕数
 ② HTTP                  
 Content-Type の charset、URL ゚ンコヌド
 ③ HTML / XML / JSON     
 宣蚀ず実䜓の䞍䞀臎
 ④ デヌタベヌス          
 列の型varchar / nvarcharず照合順序
 â‘€ コン゜ヌル            
 Console.OutputEncoding、端末のコヌドペヌゞ
 ⑥ プロセス間            
 暙準入出力のリダむレクト、匕数
 ⑩ 圧瞮ファむル          
 ZIP のファむル名の゚ンコヌディング!
 ⑧ メヌル                
 MIME のヘッダずボディ
 ⑹ CSV / 固定長ファむル  
 BOM の有無、改行コヌド

**珟圚の指針は「境界を枛らす」**である。

・内郚は垞に UTF-16.NET の stringで扱う
・倖郚ずの入出力は【原則 UTF-8】に統䞀する
・倉換が必芁な箇所を【システムの端に集玄する】
   → 䞭間局で倉換するず、どこで壊れたか分からなくなる

⑩ ZIP のファむル名は珟圚も事故が倚い。
叀い ZIP はファむル名を CP932 で持぀ため、
UTF-8 前提のツヌルで開くず化ける逆も同じ。

// .NET で CP932 のファむル名を持぀ ZIP を読む
ZipFile.ExtractToDirectory("a.zip", "out",
    Encoding.GetEncoding(932));

事䟋

プラットフォヌムに実装されおいる文字コヌドコヌドペヌゞやフォントに起因する文字化け。

  • Microsoft コヌドペヌゞ932 - Wikipedia
    https://ja.wikipedia.org/wiki/Microsoft%E3%82%B3%E3%83%BC%E3%83%89%E3%83%9A%E3%83%BC%E3%82%B8932

    • むンタヌネット䞊での Windows-31J の利甚に぀いお  NEC 特殊文字・IBM 拡匵文字

      • IBM 拡匵文字等の Windows-31J 独自远加の文字は、
        他の JIS X 0208 非登録の CJK 統合挢字に比べお、
        異機皮OS / アプリケヌション間でのデヌタ亀換を、
        文字化けを起こしたりせずにデヌタのやり取りが正垞に行える確率が高い。
      • しかし、JIS X 0208 非登録の文字をサポヌトしない環境があるこずを考えるず、
        JIS X 0208 登録文字だけを甚いおデヌタ亀換を行った方が、問題が起こりにくい。
    • JIS X 0208 - Wikipedia
      https://ja.wikipedia.org/wiki/JIS_X_0208

  • Windowsの機皮䟝存文字 - CyberLibrarian
    http://www.asahi-net.or.jp/~ax2s-kmtn/ref/mdc.html

    • NEC 機皮䟝存文字
    • NEC の IBM 拡匵文字
    • IBM 拡匵文字

補足機皮䟝存文字の実際: CP932 が JIS X 0208 に远加した領域が
事故の枩床である。

領域 内容 䟋
NEC 特殊文字13 区 䞞数字、ロヌマ数字、単䜍蚘号 ① ② Ⅰ Ⅱ ㈱ ℡ №
NEC 遞定 IBM 拡匵文字8992 区 IBM 拡匵文字の重耇定矩 兊 å…€ 冝 

IBM 拡匵文字115119 区 人名・地名の挢字、蚘号 髙 ïš‘ 圅 纊

NEC 遞定 IBM 拡匵文字ず IBM 拡匵文字は、
同じ文字に 2 ぀のコヌドが割り圓おられおいる
重耇笊号化。
これが埀埩倉換で倀が倉わる原因になる。

「兊」を Unicode → CP932 に倉換するず 0xFA5CIBM 拡匵になるが、
 元デヌタが 0xED40NEC 遞定だった堎合、倀が倉わっお戻る
   → バむト列で比范する凊理チェックサム、重耇刀定が壊れる

原文の結論——「JIS X 0208 登録文字だけを甚いる」——は
デヌタ亀換の指針ずしおは今も正しい
。
ただし珟実には、氏名に「髙」「」が入るため避けられない。
珟圚の解は、システム党䜓を UTF-8 / Unicode で通すこずである
アプリケヌションのUnicode化。

事䟋

プラットフォヌムで適甚される暙準の゚ンコヌディングに起因する文字化け。

  • IT事䟋に孊ぶWebシステム開発のワンポむント8
    http://www.atmarkit.co.jp/fjava/rensai2/webopt08/webopt08.html#ap04

    • .NET では暙準で、Shift_JIS  MS932 ずなるが、
    • Java では Shift_JIS ≠ MS932 ずなるため、

補足この差は今も残っおいる: 原文の指摘は珟圚も有効で、
.NET ず Java の異皮混圚システムで実際に起こる。

指定 .NET Java
"Shift_JIS" CP932 ず同じ MS932 JIS X 0208 準拠。機皮䟝存文字が化ける
"MS932" この名前は䜿わない CP932 盞圓
"Windows-31J" CP932 CP932 盞圓
【事故のパタヌン】
   .NET 偎 Encoding.GetEncoding("Shift_JIS") で「①」を曞き出す
             → 0x8740CP932 ずしお正しい
   Java 偎 new String(bytes, "Shift_JIS") で読む
             → 「?」になるJIS X 0208 に ① がないため

【察策】 Java 偎で "Windows-31J" を明瀺する

゚ンコヌディング名は「別名」が倚く、実䜓が凊理系で異なる——
これが教蚓である。
曖昧さのない名前Windows-31J、UTF-8を䜿い、
䞡システムの実装を確認する。

事䟋

フォントや倖字のむンストヌル状況に起因する文字化け。

事䟋

コヌドペヌゞによっおは、倉換が䞍可逆なケヌスがある。

  • JA16SJIS → Unicode 方向ぞの倉換においお、
    Unicode の文字デヌタに U+FF5E が枡されるず 0x8160 に倉換される。

  • 逆向きの JA16SJIS → Unicode 方向ぞの倉換においお、
    JA16SJIS の入力デヌタに 0x8160 が枡されるず、U+FF5E ではなく U+301C に倉換される。

この倉換はあくたでも Unicode から JA16SJIS 方向ぞの片方向の倉換においおのみ適甚される。

移行メモ原文の方向衚蚘が入れ替わっおいる: 原文は
**1 番目も 2 番目も「JA16SJIS → Unicode 方向」ず曞いおいるが、
内容から芋お
1 番目は「Unicode → JA16SJIS 方向」**が正しい
「Unicode の文字デヌタに U+FF5E が枡されるず」ずあるため。
最終行の「Unicode から JA16SJIS 方向ぞの片方向の倉換」ずいう蚘述ずも敎合する。

この珟象は「波ダッシュ問題」ずしお知られる、
日本語システムで最も有名な文字化け
である。

【問題の構造】
   Shift_JIS の 0x81601 バむト目 0x81、2 バむト目 0x60
     ↓ この 1 文字に、Unicode の候補が 2 ぀ある

   U+301C  〜  WAVE DASH波ダッシュ      ← JIS の芏栌䞊はこちら
   U+FF5E    FULLWIDTH TILDE党角チルダ ← Microsoft はこちらに察応付けた
察応付け 採甚しおいる凊理系
0x8160 ↔ U+FF5E Windows / .NETCP932、倚くの Windows アプリ
0x8160 ↔ U+301C Java の Shift_JIS、Unix 系、Oracle の JA16SJIS、iOS/macOS

同じ「〜」に芋えるのに、バむト倀が違うため、

・文字列比范が䞀臎しない芋た目は同じなのに
・DB の怜玢でヒットしない
・埀埩倉換で別の文字になる
・Windows で入力したデヌタを Oracle に入れるず化ける

同皮の問題を起こす文字Unicode 察応が 2 通りある:

文字 JIS 系 Microsoft 系
〜波ダッシュ U+301C U+FF5E
‖双柱 U+2016 U+2225
−負笊号 U+2212 U+FF0D
ï¿  ï¿¡ ï¿¢ U+00A2 U+00A3 U+00AC U+FFE0 U+FFE1 U+FFE2

珟圚の察策:

① 【システム党䜓を UTF-8 に統䞀する】
      → 倉換自䜓をなくす。最も確実

② 倉換が避けられないなら、【正芏化テヌブルを持぀】
      → 入力時に U+FF5E → U+301C 等ぞ寄せるどちらかに統䞀

③ 【Unicode 正芏化NFKCを掛ける】
      → ただし NFKC は党角英数を半角にする等、圱響が広い。芁泚意
// ② の䟋入力時に波ダッシュ系を統䞀する
static string NormalizeWaveDash(string s) => s
    .Replace('', '〜')   //  → 〜
    .Replace('', '−')   //   → −
    .Replace('∥', '‖');  // ∥  → ‖

コヌドペヌゞ

  • サポヌトするコヌド ペヌゞ
    https://learn.microsoft.com/ja-jp/windows/win32/intl/code-page-identifiers

  • Microsoft コヌドペヌゞ932 - Wikipedia
    https://ja.wikipedia.org/wiki/Microsoft%E3%82%B3%E3%83%BC%E3%83%89%E3%83%9A%E3%83%BC%E3%82%B8932

    • CP932 の呌称別名の敎理

      • Windows-31J
        Windows 3.1 (J) のリリヌスに合わせお、マむクロ゜フトが
        IBM ず日本電気 (NEC) のコヌドを統合しお䜜った笊号化文字集合。
        1993 幎以降、マむクロ゜フトが自瀟のドキュメント等で「CP932」ずいう甚語を䜿っお
        衚しおいる察象は、垞にこの「Windows-31J」である。この名前は IANA に登録されおいる。

      • MS932
        Java で、「IBM のコヌドペヌゞ 932」ず「Windows-31J」を区別するための甚語。

      • CP932
        MS-DOS ず Windows における日本語コヌドペヌゞを衚す甚語。
        「Windows-31J」が制定されるたでは、OEM ベンダによっお文字集合が違う。

      • MS 挢字コヌド
        「CP932」ずほが同じ意味の甚語である。
        マむクロ゜フトがShift_JIS ずいう笊号化方匏を策定したずいう点や、
        マむクロ゜フトがJIS X 0208 ずいう文字集合に察しお文字を独自に远加した点を
        匷調したい堎合に甚いられる。たた、単に「シフト JIS」のこずを指しおいる堎合もある。

      • OEM コヌドペヌゞ 932
        Windows 3.1 日本語版の発売以前における、OEM ベンダ各自の拡匵を蚱した仕様の文字セット。
        以䞋は、マむクロ゜フトから離れ、珟圚では公的機関からも認められた文字笊号化方匏を指す甚語。

      • シフト JIS
        JIS X 0208 笊号化文字集合を䞀定の芏則に埓っおシフトした文字笊号化方匏。
        具䜓的な内容は JIS X 0208:1997 に「シフト笊号化衚珟」ずしお蚘茉がある。
        しかし、文脈によっおはベンダ拡匵されたコヌドセットを指しおいる堎合もある。

      • Shift_JIS
        「シフト JIS」の IANA 登録名。

      • SJIS
        Shift_JIS の短瞮圢。Java では Shift_JIS ず同矩語。

移行メモSJIS は Java では Shift_JIS ず同矩ではない: 原文の
最終行は正確でない。Java の SJIS は Shift_JIS の別名ずしお
扱われるが、事䟋で述べた通り、
Shift_JIS 自䜓が CP932 ずは異なるため、
「同矩語」ずいう衚珟は誀解を招く。
Java で CP932 盞圓を䜿いたければ Windows-31J たたは MS932 を指定する。

補足.NET でコヌドペヌゞを䜿う際の必須手順: .NET Core 以降、
Encoding.GetEncoding(932) は既定では倱敗する
。

// ✗ .NET Core / .NET 5+ では ArgumentException
var enc = Encoding.GetEncoding(932);

// ○ プロバむダヌを登録しおから䜿う
// NuGet: System.Text.Encoding.CodePages
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
var enc = Encoding.GetEncoding(932);

.NET Framework には党コヌドペヌゞが組み蟌たれおいたが、
.NET Core 以降は UTF 系ず ASCII / Latin-1 のみが暙準で、
それ以倖は䞊蚘のパッケヌゞが芁るクロス プラットフォヌム化のため。

䞻なコヌドペヌゞ:

番号 名前 内容
932 Shift_JIS / Windows-31J 日本語CP932
20932 EUC-JP 日本語Unix 系
50220/50222 ISO-2022-JP JIS コヌドメヌルで䜿われた
1252 Windows-1252 西欧
65001 UTF-8 既定にすべきもの
1200 UTF-16 LE Windows の内郚衚珟Encoding.Unicode

Encoding.Default の意味も倉わった点に泚意する。

.NET Framework .NET Core 以降
Encoding.Default OS の ANSI コヌドペヌゞ日本語なら CP932 垞に UTF-8

旧コヌドから移怍する際、Encoding.Default が
暗黙に CP932 を意味しおいた箇所は党お壊れる
。
移怍時は明瀺的に Encoding.GetEncoding(932) ぞ眮き換える。

その他の゚ンコヌディング

SGML文曞

HTML゚ンコヌディング

文字参照数倀文字参照・文字実䜓参照の゚ンコヌディング゚スケヌプを行う。

  • 文字参照 - Wikipedia
    https://ja.wikipedia.org/wiki/%E6%96%87%E5%AD%97%E5%8F%82%E7%85%A7\ 盎接蚘述できない文字や蚘号を HTML・XML 䞊に衚蚘、参照するため甚いられる方法。
    • マヌクアップで䜿われる、半角の䞍等号「<」や「>」

    • 指定の文字コヌドで衚珟できない文字を衚蚘、参照する。

    • 衚蚘方法により「数倀文字参照」ず「文字実䜓参照」の二皮が存圚する。

      • 数倀文字参照
        10 or 16 進数で該圓文字を ISO 10646 の文字番号で指定する方法。
        指定の文字コヌドで衚珟できない文字を衚蚘、参照する。

      • 文字実䜓参照
        特定のキヌワヌド文字列で該圓文字䞻にマヌクアップで䜿われる文字を指定する方法。
        XSSクロスサむト・スクリプティング察策ずしおも䜿甚される。

補足゚スケヌプの正しい考え方: 原文は
「XSS 察策ずしおも䜿甚される」ず曞いおいるが、
ここは珟圚の理解に沿っお敎理しおおく必芁がある。

**XSS 察策の本質は「出力先の文脈に応じた゚スケヌプ」**であり、
HTML ゚スケヌプさえすれば安党、ではない。

出力先文脈 必芁な゚スケヌプ
HTML の本文 < > & " ' → 文字参照
HTML の属性倀 䞊蚘必ず匕甚笊で囲う
<script> の䞭 JavaScript の゚スケヌプHTML ゚スケヌプでは䞍十分
URL の䞀郚 URL ゚ンコヌド埌述
CSS の䞭 CSS の゚スケヌプ
<a href> の倀 スキヌムを怜蚌javascript: を匟く
<!-- HTML ゚スケヌプしおも防げない䟋 -->
<a href="&#106;avascript:alert(1)">クリック</a>

.NET での実装:

// 文脈ごずに䜿い分ける
HttpUtility.HtmlEncode(s);        // HTML 本文・属性
HttpUtility.JavaScriptStringEncode(s);  // <script> 内
HttpUtility.UrlEncode(s);         // URL

ASP.NET Core の Razor では @倀 が自動的に HTML ゚スケヌプされる
ため、手で゚スケヌプしないのが原則である
二重゚スケヌプになる。
危険なのは @Html.Raw() を䜿った箇所だけ、ずいう状態に保぀。

HTMLの文字゚ンコヌディング

HTTP ヘッダか、meta タグに゚ンコヌディングを指定するこずで
WWW ブラりザがデコヌドする際に指定する文字コヌドコヌドペヌゞを指定する。

  • HTTP ヘッダ

    Content-Type: text/html; charset=Shift_JIS
    
  • meta タグ

    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  • ITJavaの文字化け察策FAQ1
    http://www.atmarkit.co.jp/fjava/rensai3/mojibake01/mojibake01.html

    • 質問1Web ブラりザが文字コヌドを刀定する基準は䜕ですか
      HTTP ヘッダか、meta タグに゚ンコヌディングを指定
    • 質問2page ディレクティブで文字コヌドを正しく指定する方法は
      CGI 毎、HTML を出力する際に指定する方法が存圚する。

補足珟圚の曞き方ず優先順䜍: HTML5 では 短い圢匏が䜿える。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">  <!-- ← HTML5 の曞き方。先頭 1024 バむト以内に眮く -->

刀定の優先順䜍匷い順:

 ① HTTP ヘッダの Content-Type: charset=
   ← 最も匷い
 ② BOMバむト オヌダヌ マヌク
 ③ <meta charset="
">
 ④ ブラりザの掚枬 / 既定倀

① が ③ を䞊曞きするため、
HTML に UTF-8 ず曞いおも、サヌバが別の charset を返せば化ける。
ここが実務でよく詰たる点である。

珟圚の指針:

・【UTF-8 以倖を䜿わない】
    HTML Standard は UTF-8 を芁求しおいる
・HTTP ヘッダず meta の䞡方を UTF-8 に揃える
・meta charset は【head の先頭付近】に眮く
    1024 バむトを過ぎるずブラりザが再解析する
・BOM は付けないUTF-8 では䞍芁。付けおも害は少ないが䞍芁

ASP.NET Core では既定で UTF-8 が䜿われるため、
明瀺的に倉曎しおいなければ問題は起きない。

XMLの文字゚ンコヌディング

ヘッダ郚分の蚘述を DOM が理解しお自動的に゚ンコヌド・デコヌドしたす。

<?xml version="1.0" encoding="Shift_JIS"?>

移行メモ原文の XML 宣蚀に閉じ蚘号の誀りがある: 原文は
<?xml version="1.0" encoding="Shift_JIS"> ず曞いおいるが、
XML 宣蚀は ?> で閉じる必芁がある
䞊のコヌドでは修正枈み。

補足: XML では宣蚀ず実䜓が食い違うず、パヌサが゚ラヌにする
HTML のように黙っお掚枬しない。これは良い性質である。

・encoding を省略した堎合、【UTF-8 ず芋なされる】
・BOM があれば、BOM が優先される
・宣蚀ず実䜓が違えば、パヌス ゚ラヌ

.NET で XML を曞き出す際、
XmlWriterSettings.Encoding ず実際の曞き蟌み先を揃える。

var settings = new XmlWriterSettings { Encoding = new UTF8Encoding(false) };
using var writer = XmlWriter.Create("out.xml", settings);

new UTF8Encoding(false) の false は BOM を付けない指定である。
Encoding.UTF8 は BOM 付きなので、
意図せず BOM が入っお盞手システムが読めなくなる事故が起きる。

URL゚ンコヌディング

  • 抂芁

    • URI においお䜿甚できない文字を䜿う際に行われる゚ンコヌド゚スケヌプを行う。
    • RFC3986 の Section 2.1 で定矩されおいる。
  • 利甚シヌン

    • Query String 経由でデヌタを受け枡す堎合にも䜿甚する。
  • 参考

補足.NET の゚ンコヌド API の䜿い分け: URL ゚ンコヌドには
埮劙に仕様の違う API が耇数あるため、混同するず事故になる。

API 空癜の扱い 甹途
Uri.EscapeDataString %20 RFC 3986 準拠。これを䜿う
Uri.EscapeUriString %20 廃止枈みObsolete。䜿わない
HttpUtility.UrlEncode + application/x-www-form-urlencodedフォヌム
WebUtility.UrlEncode + 同䞊System.Net 偎
Uri.EscapeDataString("あ い");        // "%E3%81%82%20%E3%81%84"
HttpUtility.UrlEncode("あ い");       // "%e3%81%82+%e3%81%84"

+ を空癜ず解釈するのはフォヌム送信の芏則であり、
**URL のパス郚分では + は「プラス蚘号そのもの」**である。
パスに HttpUtility.UrlEncode を䜿うず、
空癜が + になっお盞手に別の文字列ずしお届く。

【䜿い分け】
   URL のパス・ク゚リの【倀】   → Uri.EscapeDataString
   フォヌムの POST ボディ       → HttpUtility.UrlEncode

文字コヌドにも泚意する。
URL ゚ンコヌドはバむト列を %XX にするだけなので、
元のバむト列が UTF-8 か CP932 かで結果が倉わる。
珟圚は UTF-8 が既定RFC 3986 が掚奚だが、
叀いシステムは CP932 で送っおくるこずがある。

Base64゚ンコヌディング

  • 抂芁

    • Byte デヌタず文字列の盞互倉換を行う。
  • 利甚シヌン

    • Byte デヌタを Text ベヌスのプロトコルSMTP, HTTP 等に乗せる堎合に䜿甚する。
  • 参考

補足Base64 の実際: Base64 は暗号化ではない——
誀解が倚いので明蚘しおおく。誰でも埩元できる。

string s = Convert.ToBase64String(Encoding.UTF8.GetBytes("秘密"));
// "56eY5a+G"  ← 単に読みにくいだけで、秘匿性はない

サむズが玄 4/3 に増える点も重芁である
3 バむト → 4 文字。倧きなデヌタには向かない。

URL で䜿う堎合は「Base64 URL セヌフ」が芁る。

【暙準の Base64】       + / =  ← URL で意味を持぀文字が入る
【Base64 URL セヌフ】   - _    ← + → -、/ → _、= は陀去

JWT やトヌクン系はすべお URL セヌフである。

// .NET 9 以降は暙準 API がある
var s = System.Buffers.Text.Base64Url.EncodeToString(bytes);

// それ以前は自前で眮換する
var s = Convert.ToBase64String(bytes)
    .Replace('+', '-').Replace('/', '_').TrimEnd('=');

性胜が芁る堎面では Convert.TryToBase64Chars を䜿うず
䞭間の文字列割り圓おを避けられる。

各皮フォヌマット

Excelが開くこずが可胜なCSVファむル

CSV ファむルを扱い際は、以䞋のこずに気を付ける。

Excel にお文字化けや゚ラヌが発生せず読み蟌める CSV ファむルは、

以䞋の 2 皮類の゚ンコヌドのファむルである。

  • BOM 付き UTF-8
  • 各蚀語(囜)の ANSI コヌド

各蚀語(囜)の ANSI コヌド(䞀䟋)

# 蚀語 文字セット名 codepage
1 日本語 Shift-JIS 932
2 英語(米囜) Windows-1252 1252
3 英語(英囜) Windows-1252 1252
4 フランス語(フランス) Windows-1252 1252
5 スペむン語(スペむン) Windows-1252 1252
6 繁䜓字䞭囜語 big5 950
7 簡䜓字䞭囜語 gb2312 936
8 韓囜語 ks_c_5601-1987 949

Excel 䞊で CSV 圢匏で保存するず、ANSI コヌドで保存される。

補足CSV ず Excel の珟況: 原文の「BOM 付き UTF-8」ずいう指摘が
最も重芁な実務知識で、珟圚も倉わらない。

・BOM なし UTF-8 の CSV を Excel でダブルクリックするず
   → 【CP932 ず誀認しお文字化けする】
・BOM 付き UTF-8 なら
   → 正しく UTF-8 ず認識される
// Web アプリから CSV をダりンロヌドさせる際
var bom = new UTF8Encoding(true).GetPreamble();  // EF BB BF
await stream.WriteAsync(bom);
await using var writer = new StreamWriter(stream, new UTF8Encoding(false));

XML では BOM を付けないのが無難、CSV では BOM を付ける——
ずいう逆の指針になる点に泚意する。

珟況の補足:

項目 珟圚
Excel の「保存」 既定は今も ANSICP932。「CSV UTF-8」圢匏が別に遞べる
Microsoft 365 **「CSV UTF-8 (コンマ区切り)」**が遞択肢にあるBOM 付き
区切り文字 地域蚭定に䟝存欧州では ; になる囜がある
改行を含むセル " で囲む。RFC 4180

そもそも CSV を避けられるなら避けるのが最善である。

代替 利点
.xlsx を盎接生成ClosedXML 等 文字コヌドの問題が消える。曞匏も付けられる
JSON 構造を持おる。UTF-8 が前提
TSV 区切り文字の衝突が起きにくい

CSV は**「区切り文字」「匕甚笊」「改行」「文字コヌド」の 4 ぀が
すべお曖昧**ずいう、亀換圢匏ずしお匱い仕様である。
垳祚出力 で觊れた通り、
利甚者が Excel で加工する前提なら .xlsx を盎接吐く方が確実である。

参考

Microsoft Learn


Tags: 移行, .NET開発, 囜際化察応, 文字コヌド

⚠ **GitHub.com Fallback** ⚠