ConnectPlusユニコード開発

第5回 UTF-8 と SAP ユニコードシステム

今回は、SAP ユニコードシステムのデータ入出力で使われるエンコード方式 UTF-8 についてお話しします。

■ UTF-8

第 2 回のコラムで、ユニコードには、 128 の群、256 の面 、256 の区、256 の点の組み合わせから成る 20 億個の文字集合である UCS-4 とその部分集合である UCS-2 の 2 通りの文字集合があると説明しました。

 

UTF-8 は、UCS-4 の文字集合を完全に対応できるエンコード方式です。UTF-8 は、UCS-4 に定義された文字を 1 バイトから 6 バイトまでのバイト列に符号化します。また、UTF-8 の特長として、ASCII コードとの互換性が挙げられます。
ASCII コードに収録されている文字は、UTF-8 で符号化しても ASCII コードとバイト列が同じになります。つまり、アルファベットや数字をユニコードで処理しても、UTF-8 で符号化すれば、ASCII コードで処理した場合と同じバイト列になるのです。

 

一方、ASCII コードで定義されていない文字は、2 から 6 バイトのバイト列に符号化されます。例えば、日本語文字であれば、半角カナ、全角かな、JIS 第一、第二水準漢字、JIS 第三、第四水準漢字の一部、<や>などの記号が 3 バイト、JIS 第三、第四水準漢字の残りが 4 バイトでエンコードされます。そして、これらの文字は、シフト JISで符号化したバイト列とは同じになりません。

 

■ UTF-8 の種類

第 3 回のコラムで、エンディアンによる UTF-16 の違いについて説明しましたが、UTF-8 には、エンディアンによる違いはありません。エンディアンの判別が不要なので、本来ならば BOM は必要ないのですが、UTF-8 を扱うソフトウエアによっては、バイト列の先頭に UTF-8 を表す BOM を付加することがあります。そこで、BOM が付いたものを UTF-8、BOM が付いていないものを UTF-8N と区別して呼ぶことがあります。

 

メモ帳を例にして説明します。メモ帳で文字コード UTF-8 を指定して、 「あ」という文字をファイルに保存すると、 ファイル全体のバイト列は、0xEFBBBFE38182 になります。 この場合、バイト列の先頭の 3 バイト EFBBBF が UTF-8 を表す BOM で、 E38182 が「あ」を符号化したバイト列になります。
一方、フリーのエディターソフト TeraPad で文字コード UTF-8N を指定して「あ」をファイルに保存すると、BOM が先頭に付加されないので、ファイル全体のバイト列は、0xE38182 になります。

 

■ 日本語と英語の違い

SAP ユニコードシステムでは、 GUI を含む外部システムとのデータ入出力のエンコード方式に UTF-8 を採用しています。では、なぜ SAP ユニコードシステムは、内部処理とデータ入出力でエンコード方式を使い分けるのでしょうか。
SAP 社の公開文書 Supported Languages in Unicode SAP Systems には、データ入出力に UTF-8 を採用した理由として、ASCII 文字との互換性やエンディアンの判別が不要である点、XML がエンコード方式に UTF-8 を採用している点などが挙げられています。アメリカを含む英語圏の多くの SAP ユーザへの配慮、エンディアンの違うベンダーのハードウエアへの対応、SOA などのシステム連携などを考慮すると、データ入出力に UTF-8 を使用するのは妥当なことなのかもしれません。

 

例えば、英語しか使わない SAP ユーザが MDMP システムからユニコードシステムにアップグレードした場合、システム内部のデータは大幅に変わりますが、システムインタフェース部分は、UTF-8 と ASCII コードで符号化の結果が同じなので、受渡されるデータに違いがありません。従って、ユニコードシステムに切り替えても、インタフェースの部分は、システムを修正する必要がありません。

 

しかし、SAP システムで日本語を使用しているユーザの場合は、事情が異なります。MDMP システムでは、内部処理と入出力のエンコード方式にシフト JIS が使われていたので、インタフェース部分は、バイト固定長でデータを取り扱うことができました。しかし、ユニコードシステムは、内部では UTF-16 で文字を 2 バイトで処理し、インタフェース部分では、UTF-8 で文字を 1 バイトから 4 バイトの可変長データに変換して処理します。従って、UTF-8 から シフト JIS に再変換しても、データをバイト固定長で処理することはできません。

 

■ 日本語のダウンロード

では、実際に SAP システムからデータをダウンロードして、MDMP システムとユニコードシステムの違いを確認してみます。

 

column01_5_1

 

この画面は、データブラウザー機能を使って、受注伝票の得意先発注番号 (VBAK-BSTNK) という文字型長さ 20 の項目を表示したものです。上段に数字 3 字、下段に漢字 3 字の値があります。GUI のメニューから、システム > 一覧 > 保存 > ローカルファイル を選択して、パソコンに得意先発注番号をダウンロードしてみます。

 

MDMP システムからシフト JIS で得意先発注番号をダウンロードして、メモ帳を使って等幅フォントで照会してみると、次のように上段、下段で得意先発注番号が揃って表示されます。

 

column01_5_2

 

一方、ユニコードシステムから UTF-8 でダウンロードして、シフト JIS に変換した場合は、次のように最後の縦罫線がずれて表示されます。

 

column01_5_3

 

なぜ、ユニコードシステムでは、表示がずれたのでしょうか。ダウンロードしたデータのバイト列を比較してみます。

 

下の表は、MDMP システムからシフト JIS でダウンロードした得意先発注番号を 16 進数で表記したバイト列です。上段の先頭 0×31、0×32、0×33 は、数字の 1, 2, 3 で、下段の先頭 0x88EA、0x93F1、0x8E4F は、シフト JIS で符号化された漢字の一、二、三です。上段、下段とも、値の後ろに空文字 0×20 が追加されていますが、全体の長さは、いずれも 20 バイトであることが分かります。

 

バイト

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

31

32

33

20

20

20

20

20

20

20

20

20

20

20

20

20

20

20

20

20

88

EA

93

F1

8E

4F

20

20

20

20

20

20

20

20

20

20

20

20

20

20

 

 

下の表は、ユニコードシステムでダウンロードした UTF-8 のバイト列です。上段の先頭 3 バイトは、数字の “123″ で、シフト JIS と同様に ASCII コードと同じバイト列になっています。一方、下段の先頭 0xE4B880、0xE4BA8C、0xE4B889 は、UTF-8 で符号化された漢字の一、二、三のバイト列です。内部処理では、UTF-16 で同じ 2 バイト、文字型長さ 1 で処理された数字と漢字が、ダウンロード時に UTF-8 で符号化され、1 文字のバイト長に差が発生して、得意先発注番号全体のバイト長が変わったことが分かります。

バイト

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

31

32

33

20

20

20

20

20

20

20

20

20

20

20

20

20

20

20

20

20

E4

B8

80

E4

BA

8C

E4

B8

89

20

20

20

20

20

20

20

20

20

20

20

20

20

20

20

20

20

 

 

下の表は、上の UTF-8 のデータをシフト JIS に変換したバイト列です。合計 9 バイトで符号化されていた下段の漢字が 6 バイトになっていることが分かります。しかし、シフト JIS に変換しても、上段と下段の得意先発注番号には 3 バイトの差があります。

バイト

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

31

32

33

20

20

20

20

20

20

20

20

20

20

20

20

20

20

20

20

20

88

EA

93

F1

8E

4F

20

20

20

20

20

20

20

20

20

20

20

20

20

20

20

20

20

 

 

MDMP システムは、文字型 1 個分の長さが 1 バイトで、シフト JIS で文字を符号化します。従って、数字の “123″ は、文字列の長さが 3 になり、得意先発注番号項目の残りの長さ 17 には空文字 0×20 が更新されます。漢字の「一二三」の場合は、1 文字当たり 2 バイトで符号化されるので、文字列の長さが 6 になり、残りの長さ 14 に空文字が更新されます。そして、シフト JIS のままでシステム外部に出力されるので、ダウンロードされるデータは、20 バイトになります。

 

ユニコードシステムは、文字型 1 個分の長さが 2 バイトで、内部処理では UTF-16 で文字を符号化します。従って、数字の “123″ も漢字の「一二三」も 6 バイト、文字型長さ 3 で処理され、残りの長さ 17 に空文字が更新されます。そして、UTF-8 で符号化してシステム外部に出力すると、数字と空文字が 1 バイト、漢字が 3 バイトのバイト列に変換されるので、数字 3 つの文字列の 3 バイトと漢字 3 つの文字列の 9 バイトの間に 6 バイトの差が発生します。そして、UTF-8 のデータをシフト JIS に変換すると、数字と空文字が 1 バイト、漢字が 2 バイトで符号化されるので、上段の得意先発注番号は、数字 の 3 バイト、と空文字 の 17 バイトで合計 20 バイトのデータになり、下段は、漢字 6 バイトと空文字 17 バイトで合計 23 バイトのデータになります。シフト JIS に変換しても、結果的に 3 バイトの差異が発生してしまうのです。

 

つまり、ユニコードシステムの内部では、UTF-16 で同じバイト長で処理されたデータでも、システム外部に出力すると、UTF-8 のままでも、シフト JIS に再変換しても、バイト長が可変することになります。この現象は、パソコンへのデータダウンロードに限ったものではありません。IDoc や ファイルポートを使ったデータ出力の場合でも同じことが発生します。

 

■ 次回は、ユニコードの特長について検証します

今回は、ユニコードのエンコード方式 UTF-8 と SAP システムのデータ出力について説明しました。次回は、ユニコードの特長である、世界中の様々な文字を同時に使用できるという点を検証してみます。 引き続き、よろしくお願いいたします。

お問い合わせ

  • Webで簡単お問い合わせ

    製品、導入事例、関連セミナーなど
    お気軽にお問い合わせください。

  • SAPアダプタ ショールーム

    製品デモンストレーションを
    見てみませんか?

  • 資料ダウンロード

    製品別のパンフレットや導入事例の資料をダウンロードできます。

  • エンジニアコラム
  • 特別コラム
  • サイト内用語解説