-3

私はいくつかの良いデータまたはそれほど良くないデータを a TStringStream(または任意のデータにすることができますTStream) にあり、最良の方法で視覚化したいと考えています。テキストが含まれている場合は、それをテキストとして表示したいと思います。 Hexコードを表示したいと思います。それがテキストまたはバイナリであると確実に言うための防弾方法がないことは理解していますが、それが目標ではなく、デバッグのために視覚化するだけです。

したがって、文字列の場合

  • は、コードが 32 から 127 の間の文字のみを持ちChars、.として受け入れることができますAnsiString簡単に実装できます
  • そうでない場合は、 formatUtf8StringがあることがわかっUtf8Stringているので、それを に変換しようとする ので、有効な utf8 文字列かどうかを判断できます。だから私は、はい、それはutf8stringである可能性があることを教えてくれるある種の関数が必要です。私が間違っていても、読めないテキストになっても問題ありません。16 進コードも流暢に読めません。
  • それでもそうでない場合は、ワイドストリングとして解釈したいと思います。これが最も難しい部分です。私が知っているように、フォーマットがないため、ここで多くのことを推測する必要があります。これには最も創造性が必要です。 . 完全にミッション・インポッシブルである場合は、この点を飛ばしてください。しかし、私は漢字を期待していないと言います。
  • else: 16 進コードを表示します。

データがどこから来たのか、プロトコルをどのように定義する必要があるのか​​ という事実に誰もがコメントしていたので、質問を完全に書き直しました(また、有用なヒントを得ることができました、ありがとう)。これは、新しい質問でよりよく説明されていることを願っています。

4

3 に答える 3

1

したがって、文字列の場合

• 32 から 127 までのコードを持つ Char のみがあり、AnsiString として受け入れることができます。簡単に実装できます

はい。ただし、128 ~ 255 の文字値 (別名 ANSI/MBCS 文字) も格納してAnsiString視覚的に表示できますが、それらの値が属する元の文字セットを知る必要があります。D2009+ の場合、値を に格納し、関数をRawByteString使用して適切なコードページを文字列に関連付けることができます。SetCodePage()そうすれば、コード内で文字列を渡すときに文字が正しく解釈されます。Unicode 形式以外の非 ASCII 文字を気にしない場合は、これを無視できます。

•そうでない場合は、Utf8String にフォーマットがあることを知っているので、それを Utf8String に変換しようとします。有効な utf8 文字列かどうかを判断できます。だから私は、はい、それはutf8stringである可能性があることを教えてくれるある種の関数が必要です。

データが有効な UTF-8 文字列かどうかを確認するには、Win32 APIWindows.MultiByteToWideChar()関数または Embarcadero のSystem.LocaleCharsToUnicode()関数 (XE 以降のみ) を使用できます。CP_UTF8(65001) コードページ、MB_ERR_INVALID_CHARSフラグ、およびnil出力バッファーを指定します。データが有効な UTF-8 文字列の場合、関数は、実際にデコードされた場合にデータが生成できる UTF-16 文字の数を返します。それ以外の場合、関数はERROR_NO_UNICODE_TRANSLATIONエラー コードで失敗します。

別のオプション (D2009 以降のみ) はGetCharCount()、クラスのメソッドを使用しSysUtils.TEncoding.UTF8て同じ数の UTF-16 文字を計算することです。

•それでもそうでない場合は、ワイドストリングとして解釈したいと思います。これは、私が知っているように、フォーマットがないため、最も難しい部分です。

はい、もちろんそうです - UTF-16 は、UTF-8 と同じくらい定義された形式です (実際、UTF-16 には 2 つのフレーバー、リトル エンディアンとビッグ エンディアンがあります)。

データが有効な UTF-16 (リトル エンディアンのみ) 文字列かどうかを確認するには、Win32 APIWindows.WideCharToMultiByte()関数または Embarcadero のSystem.UnicodeToLocaleChars()関数 (XE 以降のみ) を使用できます。CP_UTF8(65001) コードページ、WC_ERR_INVALID_CHARSフラグ、およびnil出力バッファーを指定します。データが有効な UTF-16LE 文字列である場合、関数は、実際にエンコードされた場合にデータが生成できる UTF-8 バイト数を返します。それ以外の場合、関数はERROR_NO_UNICODE_TRANSLATIONエラー コードで失敗します。

別のオプション (D2009 以降のみ) は、 (リトルエンディアン) またはクラスのGetByteCount()メソッドを使用して、同じ数の UTF-8 バイトを計算することです。SysUtils.TEncoding.UnicodeSysUtils.TEncoding.BigEndianUnicode

ここで多くのことを推測する必要があります

いいえ、あなたはしません。UTF-8 と UTF-16 の場合、当て推量は必要ありません。これらは明確に定義された標準化された形式であり、データを失うことなく相互に変換できるように設計されています。

于 2012-10-30T17:23:30.977 に答える
0

防弾検証を実装することはできません。文字列として渡すことができる外部制限があるまでは、WideString の任意の文字も AnsiString の有効な文字のペアになります。したがって、文字列の前にマーカーを渡す必要があります。

  • ユニコード文字列の場合、多くの場合、ストリームの開始時に特別な「文字」が送信されます。まだ可能ですが。
  • 最初の 2 バイトが Windows コードページであり、TEncoding を使用してさらにバイトを文字列に変換するという規則を作ることができます。ただし、これにより、Windows 以外のシステムとの将来のやり取りがかなり難しくなります。
  • URL で行われるように、メイン ロードの前にインターネット標準エンコーディングを AnsiString マーカーとして渡すことができます。そのマーカーは 7 ビットの ASCII 値のみを使用するため、ストリームから取得しても安全です。それでも、これらの文字セット名には多くの同義語があるため、それらの同義語名で辞書を照会する必要があります。
于 2012-10-30T06:22:20.107 に答える
0

プロトコルを定義し、それに固執することを強くお勧めします。たとえば、すべてのテキストが UTF8 であることを定義します。そのため、Delphi 7 では UTF8Encode/UTF8Decode を使用でき、XE2 では UTF8ToWideString (帯域幅を節約します!) を使用できます。また、各メッセージには、それが何であるかを定義するヘッダー (バイナリなど) があることも定義します。データの後で、次のメッセージまたはテキストのために UTF8 に戻すことができることがわかります。

于 2012-10-29T22:24:08.110 に答える