1

キーボードを使用して、Webブラウザで表示されるフォームのフィールドに多言語テキストを入力しています。O / Sにとらわれず、ブラウザにとらわれないレベルでは、次のイベントが発生すると思います(私が間違っている場合は、私が間違っていると思うので、訂正してください)。

  1. キーを押すたびに、キーが押されたことを示す割り込みがあります
  2. O / S(またはキーボードドライバー?)はキーコードを決定し、それをある種のキーボードイベント(文字、修飾子など)に変換します。
  3. O / Sのウィンドウマネージャーは、現在フォーカスされているウィンドウ(ブラウザー)を探し、キーボードイベントをそのウィンドウに渡します。
  4. ブラウザのGUIツールキットは、現在フォーカスされている要素(この場合は入力しているフィールド)を探し、キーボードイベントをその要素に渡します。
  5. フィールドが更新され、新しい文字が含まれるようになります
  6. フォームが送信されると、ブラウザは入力されたテキストをフォームターゲットに送信する前にエンコードします(どのエンコードですか?)

先に進む前に、これは実際に何が起こっているのですか?私は何か重要なことを見逃したり、見落としたりしましたか?

次に、質問したいのですが、上記の各ステップでキャラクターはどのように表現されていますか?ステップ1では、キーコードはデバイス固有のマジックナンバーである可能性があります。ステップ2で、キーボードドライバーはそれをO / Sが理解できるものに変換できます(たとえば、USB HID仕様: http: //en.wikipedia.org/wiki/USB_human_interface_device_class)。次のステップではどうですか?手順3と4のエンコーディングは、それぞれOS依存とアプリケーション依存(ブラウザ)だと思います。それらは異なる可能性がありますか?もしそうなら、その問題はどのように解決されますか?

私が尋ねている理由は、私が最近使い始めたサイトに固有の問題に遭遇したからです。

ここに画像の説明を入力してください

上記のステップ6までは機能しているように見えます。ここで、入力されたテキストを含むフォームが送信され、その後、テキストが認識できないほどマングルされます。サイトがUnicode入力を正しく処理していないことは明らかですが、この事件により、私は物事がどのように機能するかについての私自身の理解に疑問を抱きました。そして今、私はここにいます。

4

2 に答える 2

1

あなたの説明は多かれ少なかれ正しいです。

ただし、サイトの何が問題になっているのかを理解することは必須ではありません。

文字の代わりに疑問符は、エンコーディングの不実表示とは対照的に、エンコーディング間の変換が行われたことを示します(これはおそらくぎこちない結果になります)。

文字を表すために使用される文字は、さまざまな方法でエンコードできます。たとえば、ASCIIの「a」は0x61ですが、EBCDICでは0x81です。これはおそらくご存知でしょうが、人々が忘れがちなのは、ASCIIは英語の文字のみを含む7ビットのコードであるということです。PCコンピュータはストレージユニットとしてバイトを使用するため、ASCIIコードの未使用の上位128の場所は、他のアルファベットの文字を表すために使用されていましたが、どれですか。キリル?ギリシャ語?など。DOSはコードページ番号を使用して、使用する記号を指定しました。ほとんど(すべて?)のDOSコードページでは、下の128記号が変更されていないため、使用されているコードページに関係なく、英語は英語のように見えました。しかし、ギリシャ語のコードページを使用してロシア語のテキストファイルを読み取ろうとすると、ギリシャ語と記号がぎこちなくなります。

その後、Windowsは独自のエンコーディングを追加し(各文字が1バイトコードで表されるDOSコードページとは対照的に)、Unicodeがコードポイントの概念を導入しました。

コードポイントの下で、各文字には一般的な番号で識別されるコードポイントが割り当てられます。つまり、コードポイントは16ビットの数字ではなく番号で識別されます。Unicodeは、コードポイントをバイトにエンコードするためのエンコーディングも定義しました。UCS-2は、コードポイント番号を16ビット番号としてエンコードする固定長エンコーディングです。16ビットを超えるコードポイントはどうなりますか。単純に、UCS-2ではエンコードできません。特定のコードポイントをサポートするエンコーディングから、文字をサポートしないエンコーディングに変換する場合、指定された文字(通常は疑問符)に置き換えられます。

したがって、UTF-16でヘブライ文字のaleph'א'を使用して送信を取得し、それをそのような文字を持たないlatin-1エンコーディングに変換すると(または正式にはlatin-1にはユニコードコードポイントU+を表すコードポイントがありません) 05D0)代わりに「?」という疑問符の文字を取得します

Webサイトで起こっていることは、まさにそれです。入力は問題なく取得されていますが、入力のすべての文字をサポートしていないエンコーディングに変換されています。

残念ながら、ページのエンコーディングを手動で指定することで修正できるエンコーディングの不実表示とは異なり、クライアントでこれを修正するためにできることは何もありません。

関連する問題は、文字が表示されていないフォントを使用していることです。この場合、文字の代わりに空白の正方形が表示されます。この問題は、サイトのCSSをオーバーライドするか、適切なフォントをインストールすることで、クライアントで修正できます。

于 2013-02-06T04:40:56.373 に答える
1

キーを押してからアプリケーションに至るまでのキャラクターの構造:

1-PCキーボード:

PCキーボードだけがキーボードの種類ではありませんが、私はそれらに限定します。
PCキーボードは、驚くべきことに文字を理解していません。キーボードボタンを理解しています。これにより、USキーボードで使用されているのと同じハードウェアをQEWERTYまたはDvorakで使用したり、US 101/104キー形式を使用する他の言語の英語で使用したりできます(一部の言語には追加のキーがあります)。

キーボードは標準のスキャンコードを使用してキーを識別し、さらに興味深いことに、特定のコードセットを使用するようにキーボードを構成できます。

セット1-古いXTキーボードで使用されています
セット2-現在使用されており、
セット3は現在誰も使用していないPS/2キーボードで使用されています。

セット1と2は、メイクコードとブレークコードを使用します(つまり、押し下げコードとリリースコード)。セット3は、一部のキー(Shiftなど)に対してのみmakeおよびbreakコードを使用し、文字に対してのみmakeコードを使用します。これにより、キーボード自体が、キーが長押しされたときにキーの繰り返しを処理できるようになります。これは、PS / 2 8086または80286プロセッサからキーリピート処理をオフロードするのに適していますが、ゲームには適していません。

これについて詳しくは、こちらをご覧ください。また、独自の104キーウィンドウキーボードを作成して認定したい場合に備えて、スキャンコードに関するMicrosoftの仕様も見つけました。

いずれの場合も、セット2を使用するPCキーボードを想定できます。つまり、キーが押されたときにコードがコンピューターに送信され、キーが離されたときに1つのコードがコンピューターに送信されます。
ちなみに、USB HID仕様では、キーボードから送信されるスキャンコードは指定されておらず、それらのスキャンコードの送信に使用される構造のみが指定されています。
ハードウェアについて話しているので、これはすべてのオペレーティングシステムに当てはまりますが、すべてのオペレーティングシステムがこれらのコードを処理する方法は異なる場合があります。私は自分自身をWindowsで起こることに制限しますが、他のオペレーティングシステムもほぼ同じ道をたどるべきだと思います。

2-オペレーティングシステム

Windowsがキーボードをどのように正確に処理するのか、どの部分がドライバーによって処理されるのか、どの部分がカーネルによって処理されるのか、そしてどの部分がユーザーモードで処理されるのか正確にはわかりません。ただし、キーボードが定期的にポーリングされてキー状態に変更され、スキャンコードが変換されて仮想キーコードを含むWM_KEYDOWN/WM_KEYUPメッセージに変換されると言えば十分です。正確には、WindowsはWM_SYSKEYUP / WM_SYSKEYDOWNメッセージも生成します。これらのメッセージについて詳しくは、こちらをご覧ください。

3-アプリケーション

それであるWindowsの場合、アプリケーションは生の仮想キーコードを取得し、それらをそのまま使用するか、文字コードに変換するかを決定します。
今日では、正直なC Windowsプログラムを作成する人は誰もいませんが、かつてプログラマーは独自のメッセージポンプ処理コードを展開し、ほとんどのメッセージポンプには次のようなコードが含まれていました。

while (GetMessage( &msg, NULL, 0, 0 ) != 0)
{ 
        TranslateMessage(&msg); 
        DispatchMessage(&msg); 
} 

TranslateMessageは魔法が起こる場所です。TranslateMessageのコードは、WM_KEYDOWN(およびWM_SYSKEYDOWN)メッセージを追跡し、WM_CHARメッセージ(およびWM_DEADCHAR、WM_SYSCHAR、WM_SYSDEADCHAR)を生成し
ます。WM_CHARメッセージには、UTF-16(実際にはUCS-2ですが、ヘアを分割できません)コードが含まれます。その時点でアクティブなキーボードレイアウトを考慮して、WM_KEYDOWNメッセージから変換された文字。
Unicodeの前に書かれたアプリケーションはどうですか?これらのアプリケーションは、ANSIバージョンのRegisterClassEx(つまり、RegisterClassExA)を使用してウィンドウを登録しました。この場合、TranslateMessageは、キーボードレイアウトとアクティブなカルチャに基づいて、8ビットの文字コードでWM_CHARメッセージを生成しました。

4-5-キャラクターの派遣と表示。

UIライブラリを使用する最新のコードでは、TranslateMessageを使用せず、WM_KEYDOWNイベントのカスタム変換を行うことは完全に可能です(可能性は低いですが)。標準のウィンドウコントロール(ウィジェット)は、ディスパッチされたWM_CHARメッセージを理解して処理しますが、ウィンドウで実行されているUIライブラリ/ VMは、独自のディスパッチメカニズムを実装できます。

これがあなたの質問に答えることを願っています。

于 2013-02-06T11:10:48.787 に答える