6

.NET Framework で UNICODE エンコーディングを使用しているときに気になる点について助けてください ...

非 UNICODE アプリケーションを使用するいくつかの顧客データ システムとやり取りする必要があり、それらの顧客には世界規模の企業 (中国、韓国、ロシアなど) があります。そのため、Windows コード ページでエンコードされた ASCII 8 ビット ファイルを提供する必要があります。

したがって、ギリシャの顧客が製品名に「Σ」(シグマ文字「\u03A3」) を含むテキスト ファイルを送ってきた場合、211 ANSI コード ポイントに対応する同等の文字が、自分のコード ページで表されたものとして返されます。私のコンピュータはフランス語版の Windows です。つまり、コード ページは Windows-1252 です。したがって、このテキスト ファイルでは「Ó」を挿入します... わかりました。

この顧客がギリシャ人であることはわかっているので、インポート パラメータで Windows-1253 コード ページを強制することで、彼のファイルを読み取ることができます。

/// <summary>
/// Convert a string ASCII value using code page encoding to Unicode encoding
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static string ToUnicode(string value, int codePage)
{
    Encoding windows = Encoding.Default;
    Encoding unicode = Encoding.Unicode;
    Encoding sp = Encoding.GetEncoding(codePage);
    if (sp != null && !String.IsNullOrEmpty(value))
    {
        // First get bytes in windows encoding
        byte[] wbytes = windows.GetBytes(value);

        // Check if CodePage to use is different from current Windows one
        if (windows.CodePage != sp.CodePage)
        {
            // Convert to Unicode using SP code page
            byte[] ubytes = Encoding.Convert(sp, unicode, wbytes);
            return unicode.GetString(ubytes);
        }
        else
        {
            // Directly convert to Unicode using windows code page
            byte[] ubytes = Encoding.Convert(windows, unicode, wbytes);
            return unicode.GetString(ubytes);
        }
    }
    else
    {
        return value;
    }
}

最後に、アプリケーションで「Σ」を取得し、これを SQL Server データベースに保存できました。ここで、アプリケーションで複雑な計算を実行する必要があり、自動エクスポートを使用してこのファイルを顧客に返す必要があります...

だから私の問題は、UNICODE => ANSI変換を実行する必要があることです?! しかし、これは最初に思ったほど単純ではありません...

インポート時に使用したコード ページを保存したくないので、最初に考えたのは、UNICODE を windows-1252 に変換してから、ファイルを自動的に顧客に送信することでした。彼らはエクスポートされたテキスト ファイルを独自のコード ページで読み取るので、このアイデアは私にとって興味深いものでした。

しかし、問題は、この方法での変換が奇妙な動作をすることです... 2 つの異なる例を次に示します。

1例目 (я)

char ya = '\u042F';
string strYa = Char.ConvertFromUtf32(ya);
System.Text.Encoding unicode = System.Text.Encoding.Unicode;
System.Text.Encoding ansi1252 = System.Text.Encoding.GetEncoding(1252);
System.Text.Encoding ansi1251 = System.Text.Encoding.GetEncoding(1251);

string strYa1252 = ansi1252.GetString(System.Text.Encoding.Convert(unicode, ansi1252, unicode.GetBytes(strYa)));
string strYa1251 = ansi1251.GetString(System.Text.Encoding.Convert(unicode, ansi1251, unicode.GetBytes(strYa)));

したがって、strYa1252には ' ? '、strYa1251には有効な文字 ' я ' が含まれています。そのため、有効なコード ページが Convert() 関数に示されていなければ、ANSI に変換することはできないようです ... したがって、Unicode Encoding クラスには、ユーザーが ANSI と UNICODE コード ポイントの間の同等性を得るのに役立つものはありませんか? :\

2番目の例 (Σ)

char sigma = '\u3A3';
string strSigma = Char.ConvertFromUtf32(sigma);
System.Text.Encoding unicode = System.Text.Encoding.Unicode;
System.Text.Encoding ansi1252 = System.Text.Encoding.GetEncoding(1252);
System.Text.Encoding ansi1253 = System.Text.Encoding.GetEncoding(1253);

string strSigma1252 = ansi1252.GetString(System.Text.Encoding.Convert(unicode, ansi1252, unicode.GetBytes(strSigma)));
string strSigma1253 = ansi1253.GetString(System.Text.Encoding.Convert(unicode, ansi1253, unicode.GetBytes(strSigma)));

この時点で、 strSigma1253文字列には正しい ' Σ ' がありますが、 strSigma1252には ' S 'もあります。最初に示したように、ANSI コードが見つかった場合は「 Ó 」、または「?」が必要です。文字が見つからなかったが、'S' が見つからなかった場合。なんで?はい、もちろん、言語学者は「S」がギリシャ語のシグマ文字と同等であると言うことができます。これは、両方のアルファベットで同じように聞こえるためですが、同じ ANSI コードを持っていないからです!

それでは、.NET フレームワークの Convert() 関数は、この種の同等性をどのように管理できるのでしょうか?

また、顧客に送信する必要があるテキスト ファイルに UNICODE の ANSI 文字を書き戻すというアイデアはありますか?

4

1 に答える 1

7

私が持っている必要があります ...'?' 文字が見つからなかったが、'S' が見つからなかった場合。なんで?

これは「最適な」エンコーディングとして知られており、ほとんどの場合、これは悪いことです。Windows が文字をターゲット コード ページにエンコードできない場合 (Σコード ページ 1252 に存在しないため)、文字をそれに少し似たものにマップするために最善を尽くします。これは、分音記号を失うこと ( ë→<code>e)、または同族 ( Σ→<code>S)、関連する文字 ( ≤</code>→<code>=)、関連性はないが少し似ている文字( )∞</code>→<code>8などへのマッピングを意味する可能性があります。当時はマッドキャップの置き換えは良いアイデアのように思えましたが、実際には文化的または数学的に不快であることが判明しました。

そのシグマ マッピングを含む cp1252 の表をここで見ることができます。

疑わしい有用性の静かなマングリングであることは別として、それはまた、いくつかの非常に悪いセキュリティへの影響を持っています. またはに設定EncoderFallbackすることで、発生を停止できるはずです。ReplacementFallbackExceptionFallback

顧客に送信する必要があるテキスト ファイルに、UNICODE の ANSI 文字を書き戻すアイデアを誰かが持っていますか?

顧客ごとにエンコードのテーブルを保持する必要があります。そのエンコーディングを使用して入力ファイルを読み取り、デコードします。同じエンコーディングを使用して出力ファイルを書き込みます。

(正気を保つために、新規顧客には UTF-8 を設定し、これが優先エンコーディングであることを文書化してください。)

于 2013-06-10T22:03:18.903 に答える